1 |
#ident "$Header: /home/cvsuser/cvsroot/JSOC/proj/lev0/apps/decode_hk.c,v 1.14 2011/05/03 23:40:42 arta Exp $" |
2 |
/***************************************************************************** |
3 |
* Filename: decode_hk.c * |
4 |
* Author: Carl * |
5 |
* Create Date: August, 5, 2005 * |
6 |
* Description: This file contains modules to decode housekeeping data. * |
7 |
* (C) Stanford University, 2005 * |
8 |
*****************************************************************************/ |
9 |
#include <stdio.h> |
10 |
#include <stdlib.h> |
11 |
#include <string.h> |
12 |
#include <math.h> |
13 |
#include <time.h> |
14 |
#include <sys/types.h> |
15 |
#include <sys/stat.h> |
16 |
#include <sys/vfs.h> |
17 |
#include <fcntl.h> |
18 |
#include <unistd.h> |
19 |
#include <libgen.h> |
20 |
#include "decode_hk.h" // defines DRMS_TYPE_* via packets.h |
21 |
#include "printk.h" |
22 |
#include "write_hk_to_drms.h" |
23 |
#include "egsehmicomp.h" // defines DRMS_TYPE_* |
24 |
|
25 |
// ERRMSG was already defined in a couple of headers to this file (egsehmicomp.h, sum_rpc.h) |
26 |
// Change name to DHK_ERRMSG |
27 |
#define DHK_ERRMSG(__msg__) printkerr("ERROR at %s, line %d: " #__msg__"\n",__FILE__,__LINE__); |
28 |
|
29 |
|
30 |
/***************************** extern global variables ***********************/ |
31 |
extern APID_Pointer_HK_Configs *global_apid_configs; |
32 |
extern GTCIDS_Version_Number* global_gtcids_vn; |
33 |
extern SHCIDS_Version_Number* global_shcids_vn; |
34 |
/**************************static function prototypes ************************/ |
35 |
static void get_version_number(unsigned short *wd_ptr, char *ptr_vn); |
36 |
HK_Keywords_Format * load_hk_configs(HK_Config_Files *found_config);/*encode_hk uses-keep non-static*/ |
37 |
static int load_hk_values(unsigned short *word_ptr, HK_Keywords_Format *hk_keywords); |
38 |
static int load_engr_values(HK_Keywords_Format *hk_keywords, HK_Keyword_t **kw_head); |
39 |
static void deallocate_hk_keywords_format(HK_Keywords_Format *head); |
40 |
float translateint2float(int ival); |
41 |
double translateint2double(int64_t ival); |
42 |
double get_packet_time(unsigned short *word_ptr); |
43 |
/*********** extern function prototypes **************/ |
44 |
extern void sprint_time (char *at, TIME t, char *zone, int precision); |
45 |
extern int check_for_sdo_apid(int apid); |
46 |
extern char * find_fvn_from_shcids(SHCIDS_Version_Number *top,char pkt_date[MAX_SIZE_PKT_DATE], int apid); |
47 |
extern char * make_strupr (char *in_string); |
48 |
|
49 |
|
50 |
/**********************housekeeping telemetry decode routines*****************/ |
51 |
/***************************************************************************** |
52 |
* Decode HK Keywords |
53 |
* Module Name: decode_hk_keywords |
54 |
* Description: This is the top level function to decode housekeeping keywords. |
55 |
* Status decode_hk_keywords(): Tested and Reviewed |
56 |
*****************************************************************************/ |
57 |
int decode_hk_keywords(unsigned short *word_ptr, int apid, HK_Keyword_t **kw_head) |
58 |
{ |
59 |
/* declarations */ |
60 |
APID_Pointer_HK_Configs *apid_configs; |
61 |
HK_Config_Files *config_files; |
62 |
HK_Config_Files *matching_config; |
63 |
HK_Keywords_Format *ptr_hk_keywords; |
64 |
char pkt_date[MAX_SIZE_PKT_DATE]; //ascii time |
65 |
char *ptr_fvn; |
66 |
char version_number[MAX_CHAR_VERSION_NUMBER]; |
67 |
int status; |
68 |
char apid_str[10]; |
69 |
int curr_pvn_wn, curr_pvn_dn; |
70 |
char pkt_name[10]; |
71 |
|
72 |
/* init values */ |
73 |
matching_config= (HK_Config_Files *)NULL; |
74 |
|
75 |
/* Get Version Number from byte 8 and byte 9 bit stream for hk packet |
76 |
or Get packet time from bytes for sdo hk packet */ |
77 |
if (check_for_sdo_apid(apid)) |
78 |
{ |
79 |
/* get packet time to lookup sdo hk config version to use */ |
80 |
(void)sprint_time (pkt_date, get_packet_time(word_ptr), "TAI", 0); |
81 |
strcat(version_number,"\0"); |
82 |
/* for sdo 129 set pvn to merged case to pickup SDO-ASD-PVN-TO-JSVN file */ |
83 |
/* also to go into merged case logic below */ |
84 |
curr_pvn_wn= HK_LEV0_START_MERGED_PVNW; |
85 |
curr_pvn_dn= HK_LEV0_START_MERGED_PVND; |
86 |
} |
87 |
else |
88 |
{ |
89 |
get_version_number(word_ptr, version_number); |
90 |
strcat(pkt_date,"\0"); |
91 |
|
92 |
/* get number value of packet version number for comparison later */ |
93 |
sscanf(version_number,"%3d.%3d",&curr_pvn_wn, &curr_pvn_dn); |
94 |
} |
95 |
|
96 |
/* check if global pointer to configuration link list exists*/ |
97 |
if (!global_apid_configs ) |
98 |
{ |
99 |
load_all_apids_hk_configs(apid, version_number, pkt_date ); |
100 |
} |
101 |
|
102 |
/* check if packet version number is greater than or equal to merged flag values */ |
103 |
/* if so then use string names for setting apid_string value */ |
104 |
if(curr_pvn_wn >= HK_LEV0_START_MERGED_PVNW && curr_pvn_dn >= HK_LEV0_START_MERGED_PVND) |
105 |
{ |
106 |
|
107 |
/* get number value of packet version number for comparison later */ |
108 |
#ifdef DEBUG_DECODE_HK |
109 |
printkerr("DEBUG:Message at %s, line %d: Doing Merge Data Series Name. PVN:<%d.%d> \n", |
110 |
__FILE__, __LINE__,curr_pvn_wn,curr_pvn_dn); |
111 |
#endif |
112 |
|
113 |
/* doing merge data series case */ |
114 |
if (apid == HK_HSB_HMI_ISP_1 || apid == HK_HSB_HMI_ISP_2 || apid == HK_LR_HMI_ISP) |
115 |
{ |
116 |
/* get number value of packet version number for comparison later */ |
117 |
/* lookup in define variable packet name to use */ |
118 |
strcpy(pkt_name, HK_HMI_PKT_NAME_ISP); |
119 |
/* Turn string value to upper case */ |
120 |
strcpy(apid_str,make_strupr(pkt_name)); |
121 |
} |
122 |
else if (apid == HK_HSB_AIA_ISP_1 || apid == HK_HSB_AIA_ISP_2 || apid == HK_LR_AIA_ISP) |
123 |
{ |
124 |
strcpy(pkt_name, HK_AIA_PKT_NAME_ISP); |
125 |
strcpy(apid_str,make_strupr(pkt_name)); |
126 |
} |
127 |
else if (apid == HK_HSB_HMI_SEQ_1 || apid == HK_HSB_HMI_SEQ_2 || apid == HK_LR_HMI_SEQ ) |
128 |
{ |
129 |
strcpy(pkt_name, HK_HMI_PKT_NAME_SEQ); |
130 |
strcpy(apid_str,make_strupr(pkt_name)); |
131 |
} |
132 |
else if (apid == HK_HSB_AIA_SEQ_1 || apid == HK_HSB_AIA_SEQ_2 || apid == HK_LR_AIA_SEQ) |
133 |
{ |
134 |
strcpy(pkt_name, HK_AIA_PKT_NAME_SEQ); |
135 |
strcpy(apid_str,make_strupr(pkt_name)); |
136 |
} |
137 |
else if (apid == HK_HSB_HMI_OBT_1 || apid == HK_HSB_HMI_OBT_2 || apid == HK_LR_HMI_OBT ) |
138 |
{ |
139 |
strcpy(pkt_name, HK_HMI_PKT_NAME_OBT); |
140 |
strcpy(apid_str,make_strupr(pkt_name)); |
141 |
} |
142 |
else if (apid == HK_HSB_AIA_OBT_1 || apid == HK_HSB_AIA_OBT_2 || apid == HK_LR_AIA_OBT) |
143 |
{ |
144 |
strcpy(pkt_name, HK_AIA_PKT_NAME_OBT); |
145 |
strcpy(apid_str,make_strupr(pkt_name)); |
146 |
} |
147 |
else if (apid == HK_LR_SDO_ASD) |
148 |
{ |
149 |
strcpy(pkt_name, HK_SDO_PKT_NAME_ASD); |
150 |
strcpy(apid_str,make_strupr(pkt_name)); |
151 |
} |
152 |
else |
153 |
{ |
154 |
/* if not SEQ or ISP with packet name then make name using */ |
155 |
/* apid number where apid is made into string(i.e.,0x01D) */ |
156 |
sprintf(apid_str,"0x%03.3x",apid); |
157 |
} |
158 |
} |
159 |
else |
160 |
{ |
161 |
sprintf(apid_str,"0x%03.3x",apid); |
162 |
|
163 |
#ifdef DEBUG_DECODE_HK |
164 |
printkerr("DEBUG:Message at %s, line %d: Doing NON-Merge Data Series Name. PVN:<%d.%d> \n", |
165 |
__FILE__, __LINE__,curr_pvn_wn,curr_pvn_dn); |
166 |
#endif |
167 |
|
168 |
} |
169 |
|
170 |
/* get pointer to HK_Config_File structure based on apid # */ |
171 |
apid_configs = global_apid_configs; |
172 |
while(apid_configs) |
173 |
{ |
174 |
//if (!strcmp(apid_configs->apid_name, apid_str)) |
175 |
if ((strcmp(apid_str, "ISP") && apid == apid_configs->apid) && (strcmp( apid_str, "SEQ") && apid == apid_configs->apid) && (strcmp( apid_str, "ASD") && apid == apid_configs->apid) && (strcmp(apid_str, "OBT") && apid == apid_configs->apid)) |
176 |
{ |
177 |
/* Found -if non-merge apid and packet version number */ |
178 |
#ifdef DEBUG_DECODE_HK |
179 |
printkerr("DEBUG:Message at %s, line %d: Found NON-Merge dec valued apid <%d> configuration data. \n", |
180 |
__FILE__, __LINE__, apid); |
181 |
#endif |
182 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
183 |
} |
184 |
else if( (!strcmp( apid_str, "ISP")) && (apid_configs->apid == HK_HSB_HMI_ISP_1 ) && (apid == HK_HSB_HMI_ISP_1 || apid == HK_HSB_HMI_ISP_2 || apid == HK_LR_HMI_ISP)) |
185 |
{ |
186 |
/* Found -if merged apid and packet version number */ |
187 |
/* Logic: if to be looked up apid_str is ISP and if the apid number in apid_config node is primary apid(445) and */ |
188 |
/* if looked up apid is one of the known HMI ISP apid values then this is merge apid case */ |
189 |
#ifdef DEBUG_DECODE_HK |
190 |
printkerr("DEBUG:Message at %s, line %d: Found Merged HMI ISP dec valued apid <%d> configuration data. \n", |
191 |
__FILE__, __LINE__, apid); |
192 |
#endif |
193 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
194 |
} |
195 |
else if( (!strcmp( apid_str, "SEQ")) && ( apid_configs->apid == HK_HSB_HMI_SEQ_1 ) && (apid == HK_HSB_HMI_SEQ_2 || apid == HK_HSB_HMI_SEQ_1 || apid == HK_LR_HMI_SEQ)) |
196 |
{ |
197 |
/* Found -if merge apid and packet version number */ |
198 |
/* Logic: if to be looked up apid_str is SEQ and if the apid number in apid_config node is primary apid(451) and */ |
199 |
/* if looked up apid is one of the known HMI SEQ apid values then this is merge apid case */ |
200 |
#ifdef DEBUG_DECODE_HK |
201 |
printkerr("DEBUG:Message at %s, line %d: Found Merged HMI SEQ dec valued apid <%d> configuration data. \n", |
202 |
__FILE__, __LINE__, apid); |
203 |
#endif |
204 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
205 |
} |
206 |
else if( (!strcmp( apid_str, "OBT")) && (apid_configs->apid == HK_HSB_HMI_OBT_1 ) && (apid == HK_HSB_HMI_OBT_1 || apid == HK_HSB_HMI_OBT_2 || apid == HK_LR_HMI_OBT )) |
207 |
{ |
208 |
/* Found -if merge apid and packet version number */ |
209 |
#ifdef DEBUG_DECODE_HK |
210 |
printkerr("DEBUG:Message at %s, line %d: Found Merged HMI OBT dec valued apid <%d> configuration data. \n", |
211 |
__FILE__, __LINE__, apid); |
212 |
#endif |
213 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
214 |
} |
215 |
else if( (!strcmp( apid_str, "ISP")) && (apid_configs->apid == HK_HSB_AIA_ISP_1 ) && (apid == HK_HSB_AIA_ISP_1 || apid == HK_HSB_AIA_ISP_2 || apid == HK_LR_AIA_ISP)) |
216 |
{ |
217 |
/* Found -if merge apid and packet version number */ |
218 |
#ifdef DEBUG_DECODE_HK |
219 |
printkerr("DEBUG:Message at %s, line %d: Found Merged AIA ISP dec valued apid <%d> configuration data. \n", |
220 |
__FILE__, __LINE__, apid); |
221 |
#endif |
222 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
223 |
} |
224 |
else if( (!strcmp( apid_str, "SEQ")) && (apid_configs->apid == HK_HSB_AIA_SEQ_1 ) && (apid == HK_HSB_AIA_SEQ_1 || apid == HK_HSB_AIA_SEQ_2 || apid == HK_LR_AIA_SEQ )) |
225 |
{ |
226 |
/* Found -if merge apid and packet version number */ |
227 |
#ifdef DEBUG_DECODE_HK |
228 |
printkerr("DEBUG:Message at %s, line %d: Found Merged AIA SEQ dec valued apid <%d> configuration data. \n", |
229 |
__FILE__, __LINE__, apid); |
230 |
#endif |
231 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
232 |
} |
233 |
else if( (!strcmp( apid_str, "OBT")) && (apid_configs->apid == HK_HSB_AIA_OBT_1 ) && (apid == HK_HSB_AIA_OBT_1 || apid == HK_HSB_AIA_OBT_2 || apid == HK_LR_AIA_OBT )) |
234 |
{ |
235 |
/* Found -if merge apid and packet version number */ |
236 |
#ifdef DEBUG_DECODE_HK |
237 |
printkerr("DEBUG:Message at %s, line %d: Found Merged AIA OBT dec valued apid <%d> configuration data. \n", |
238 |
__FILE__, __LINE__, apid); |
239 |
#endif |
240 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
241 |
} |
242 |
else if( (!strcmp( apid_str, "ASD")) && (apid_configs->apid == HK_LR_SDO_ASD ) ) |
243 |
{ |
244 |
/* Found -if merge apid and packet version number */ |
245 |
#ifdef DEBUG_DECODE_HK |
246 |
printkerr("DEBUG:Message at %s, line %d: Found Merged SDO ASD dec valued apid <%d> configuration data. \n", |
247 |
__FILE__, __LINE__, apid); |
248 |
#endif |
249 |
break; /*Found pointer apid pointer correct HK_Config_File structures */ |
250 |
} |
251 |
else |
252 |
{ |
253 |
/* Did not find- keep checking */ |
254 |
#ifdef DEBUG_DECODE_HK |
255 |
printkerr("DEBUG:Message at %s, line %d: Keep checking for dec valued apid <%d> configuration data. \n", |
256 |
__FILE__, __LINE__, apid); |
257 |
#endif |
258 |
apid_configs = apid_configs->next; |
259 |
} |
260 |
} |
261 |
|
262 |
/* check if found config node for this apid */ |
263 |
if ( apid_configs == NULL) |
264 |
{ |
265 |
if(check_for_sdo_apid(apid)) |
266 |
{ |
267 |
printkerr("ERROR at %s, line %d: This apid <%x> does not have valid " |
268 |
"config data to decode packet. Check if sdo hk config files " |
269 |
"exists for file version number <%s>. " |
270 |
"If don't exist, run make_hkpdf.pl script to create files. " |
271 |
"If file version is set to <BAD PKT DATE> then check if " |
272 |
"packet date from packet time is a valid date. \n", |
273 |
__FILE__, __LINE__, apid, find_fvn_from_shcids(global_shcids_vn, pkt_date,apid)); |
274 |
} |
275 |
else |
276 |
{ |
277 |
printkerr("ERROR at %s, line %d: This apid <%x> does not have valid " |
278 |
"config data to decode packet. Check if hk config files exists " |
279 |
"for packet version number %s. " |
280 |
"If don't exist, run make_hkpdf.pl script to create files.\n", |
281 |
__FILE__, __LINE__, apid, version_number); |
282 |
} |
283 |
return HK_DECODER_ERROR_NO_CONFIG_DATA; |
284 |
} |
285 |
|
286 |
/*set pointer to configs to tmp pointer to get config data for this apid*/ |
287 |
config_files = apid_configs->ptr_hk_configs; |
288 |
|
289 |
/* check if config data exists in-memory */ |
290 |
//if(config_files->apid_number == 129) |
291 |
//PROBLEM HERE-GET 10922 for apid_number??? |
292 |
//fix 2-3-2009-CCif(check_for_sdo_apid(config_files->apid_number)) |
293 |
if(check_for_sdo_apid(apid)) |
294 |
{ |
295 |
/* check the file version number based on packet time */ |
296 |
ptr_fvn= find_fvn_from_shcids(global_shcids_vn, pkt_date,config_files->apid_number); |
297 |
matching_config = check_file_version_number(config_files, ptr_fvn); |
298 |
if ( matching_config == NULL ) |
299 |
{ |
300 |
/* Could not find matching config. Try to reload the config files. */ |
301 |
printkerr("WARNING at %s, line %d: For apid <%x> and file version number <%s> " |
302 |
"-Cannot find config data to decode packet!!Rereading data files.\n", |
303 |
__FILE__, __LINE__, apid, ptr_fvn, ptr_fvn); |
304 |
if( !strcmp(ptr_fvn,"BAD PKT DATE")) |
305 |
{ |
306 |
printkerr("WARNING at %s, line %d: Skipping Rereading config file since have bad packet date<%s>\n", __FILE__, __LINE__,ptr_fvn); |
307 |
} |
308 |
else |
309 |
{ |
310 |
config_files = reread_all_files(apid_configs, version_number, pkt_date); |
311 |
ptr_fvn= find_fvn_from_shcids(global_shcids_vn, pkt_date, config_files->apid_number); |
312 |
matching_config = check_file_version_number(config_files, ptr_fvn); |
313 |
} |
314 |
if ( matching_config != NULL ) |
315 |
{ |
316 |
printkerr("WARNING at %s, line %d: Found sdo hk config data for apid <%x> and file version number <%s>\n", |
317 |
__FILE__, __LINE__,apid, version_number); |
318 |
} |
319 |
} |
320 |
#ifdef DEBUG_DECODE_HK |
321 |
printkerr("DEBUG:Message at %s, line %d: Found sdo hk config for apid <%x> and file version number <%s>\n", |
322 |
__FILE__, __LINE__,apid, ptr_fvn); |
323 |
#endif |
324 |
} |
325 |
else |
326 |
{ |
327 |
/*************************************************************** |
328 |
* Check if version number exists for hk-configurations * |
329 |
* There are two version numbers: * |
330 |
* File Version number for STANFORD_TLM_HMI_AIA file * |
331 |
* Packet or Parameter Version number for parameter from packet* |
332 |
***************************************************************/ |
333 |
matching_config = check_packet_version_number(config_files,version_number); |
334 |
if ( matching_config == NULL ) |
335 |
{ |
336 |
/* Could not find matching config. Try to reload the config files. */ |
337 |
printkerr("WARNING at %s, line %d: For apid <%x> and packet version number <%s> " |
338 |
"-Cannot find config data to decode packet!!Rereading data files.\n", |
339 |
__FILE__, __LINE__, apid, version_number,version_number); |
340 |
|
341 |
config_files = reread_all_files(apid_configs, version_number, pkt_date); |
342 |
matching_config = check_packet_version_number(config_files,version_number); |
343 |
if ( matching_config != NULL ) |
344 |
{ |
345 |
printkerr("WARNING at %s, line %d: Found config data for apid <%x> and packet version number <%s>\n", |
346 |
__FILE__, __LINE__,apid, version_number); |
347 |
} |
348 |
else |
349 |
{ |
350 |
;//Did not find after rereading files |
351 |
#ifdef DEBUG_DECODE_HK |
352 |
printkerr("WARNING at %s, line %d: After reread did not find config data for apid <%x> and packet version number <%s>\n", |
353 |
__FILE__, __LINE__,apid, version_number); |
354 |
#endif |
355 |
} |
356 |
} |
357 |
else |
358 |
{ |
359 |
;// Found config |
360 |
#ifdef DEBUG_DECODE_HK |
361 |
printkerr("DEBUG:Message at %s, line %d: Found config data for apid <%x> and packet version number <%s>\n", |
362 |
__FILE__, __LINE__,apid, version_number); |
363 |
#endif |
364 |
} |
365 |
} |
366 |
|
367 |
|
368 |
if ( matching_config == NULL ) |
369 |
{ |
370 |
/* Still no matching config information. Return an error code. */ |
371 |
if(check_for_sdo_apid(apid)) |
372 |
{ |
373 |
DHK_ERRMSG("Could not find packet date value because of bad packet date or could not find even after re-reading sdo hk config files."); |
374 |
} |
375 |
else |
376 |
{ |
377 |
DHK_ERRMSG("Could not find packet version number even after re-reading hk config files."); |
378 |
} |
379 |
return HK_DECODER_ERROR_CANNOT_FIND_VER_NUM; |
380 |
} |
381 |
/* Load hk configs in HK_Keywords_Format structure */ |
382 |
if (ptr_hk_keywords = load_hk_configs( matching_config )) |
383 |
{ |
384 |
/* Load hk values in HK_Keyword_struct */ |
385 |
if (status = load_hk_values( word_ptr, ptr_hk_keywords)) |
386 |
return status; |
387 |
/* set engr values and raw values in HK_Keyword_t structure which is used for Lev0 Processing*/ |
388 |
if (!( status = load_engr_values(ptr_hk_keywords, kw_head))) |
389 |
{ |
390 |
/* deallocate HK_Keyword_Format structure */ |
391 |
deallocate_hk_keywords_format(ptr_hk_keywords); |
392 |
status = HK_DECODER_SUCCESSFUL; /*successful!!*/ |
393 |
deallocate_apid_ptr_hk_config_nodes();/*check setting before doing*/ |
394 |
return status; |
395 |
} |
396 |
} |
397 |
else |
398 |
{ |
399 |
DHK_ERRMSG("Could not find config data for this packet version number"); |
400 |
status = HK_DECODER_ERROR_CANNOT_LOAD_HK_VALUES; |
401 |
} |
402 |
return status; |
403 |
}/*Module:decode_hk_keywords*/ |
404 |
|
405 |
|
406 |
/***************************************************************************** |
407 |
* GET VERSION NUMBER |
408 |
* Module Name: get_version_number |
409 |
* Description: This is a utility to get version number from pointer to hk |
410 |
* packet. |
411 |
* Status get_version_number(): Reviewed and Tested |
412 |
*****************************************************************************/ |
413 |
static void get_version_number(unsigned short *wd_ptr, char *ptr_vn) |
414 |
{ |
415 |
/* declarations */ |
416 |
unsigned short w; |
417 |
w = wd_ptr[7]; |
418 |
/* parse high and low bytes of version number and convert from hex to decimal value */ |
419 |
sprintf(ptr_vn, "%d.%d", w & 0x00FF, w >> 8 & 0x00FF ); |
420 |
} |
421 |
|
422 |
/***************************************************************************** |
423 |
* Load Engineering Values |
424 |
* Module Name: load_engr_values |
425 |
* Status load_engr_values(): Tested and Reviewed |
426 |
*****************************************************************************/ |
427 |
static int load_engr_values(HK_Keywords_Format *hk_keywords, HK_Keyword_t **kw_head) |
428 |
{ |
429 |
/* declarations */ |
430 |
HK_Keyword_t *kwt=NULL; |
431 |
DSC_Conversion *dsc; |
432 |
int i; |
433 |
|
434 |
/* Loop thru HK_Keywords_Format link list structure and find |
435 |
first value to load */ |
436 |
while(hk_keywords) |
437 |
{ |
438 |
if (!kwt) |
439 |
*kw_head = kwt = (HK_Keyword_t*) malloc (sizeof (HK_Keyword_t)); |
440 |
else |
441 |
{ |
442 |
kwt->next = (HK_Keyword_t*) malloc (sizeof (HK_Keyword_t)); |
443 |
kwt = kwt->next; |
444 |
} |
445 |
memset(kwt,0,sizeof(HK_Keyword_t)); |
446 |
kwt->next = NULL; |
447 |
/* load keyword name */ |
448 |
strcpy(kwt->fitsname, hk_keywords->keyword_name); |
449 |
strcpy(kwt->name, hk_keywords->telemetry_mnemonic_name); |
450 |
strcat(kwt->name,"\0"); /*fix ticket #278 */ |
451 |
|
452 |
/* load raw value */ |
453 |
kwt->raw_value = hk_keywords->keyword_value; |
454 |
|
455 |
/* load engr value and type */ |
456 |
if ( hk_keywords->conv_type == 'R') |
457 |
{ |
458 |
if (!strcmp( hk_keywords->type , "UB")) |
459 |
{ |
460 |
kwt->eng_type = KW_TYPE_UINT8; |
461 |
kwt->eng_value.uint8_val = (unsigned char)hk_keywords->keyword_value; |
462 |
} |
463 |
else if (!strcmp( hk_keywords->type , "SB")) |
464 |
{ |
465 |
kwt->eng_type = KW_TYPE_INT8; |
466 |
kwt->eng_value.int8_val = (signed char)hk_keywords->keyword_value; |
467 |
} |
468 |
else if (!strcmp( hk_keywords->type , "IU1")) |
469 |
{ |
470 |
kwt->eng_type = KW_TYPE_UINT16; |
471 |
kwt->eng_value.uint16_val = (unsigned short)hk_keywords->keyword_value; |
472 |
|
473 |
} |
474 |
else if (!strcmp( hk_keywords->type , "IS1")) |
475 |
{ |
476 |
kwt->eng_type = KW_TYPE_INT16; |
477 |
kwt->eng_value.int16_val = (short)hk_keywords->keyword_value; |
478 |
} |
479 |
else if (!strcmp( hk_keywords->type , "IL1")) |
480 |
{ |
481 |
kwt->eng_type = KW_TYPE_INT32; |
482 |
kwt->eng_value.int32_val = hk_keywords->keyword_value; |
483 |
} |
484 |
else if (!strcmp( hk_keywords->type , "UL1")) |
485 |
{ |
486 |
kwt->eng_type = KW_TYPE_UINT32; |
487 |
kwt->eng_value.uint32_val = hk_keywords->keyword_value; |
488 |
} |
489 |
else if (!strcmp( hk_keywords->type , "SFP")) |
490 |
{ |
491 |
kwt->eng_type = KW_TYPE_FLOAT; |
492 |
kwt->eng_value.float_val = translateint2float(hk_keywords->keyword_value); |
493 |
} |
494 |
else if (!strcmp( hk_keywords->type , "DFP")) |
495 |
{ |
496 |
kwt->eng_type = KW_TYPE_DOUBLE; |
497 |
kwt->eng_value.double_val = (double)translateint2double(hk_keywords->keyword_value); |
498 |
} |
499 |
else |
500 |
{ |
501 |
printkerr("ERROR at %s, line %d: Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->type); |
502 |
return ERROR_HK_UNHANDLED_TYPE; |
503 |
} |
504 |
}/* end-if R type */ |
505 |
else if ( hk_keywords->conv_type == 'D') |
506 |
{ |
507 |
if (!strcmp( hk_keywords->type,"UB") || !strcmp( hk_keywords->type ,"IU1") || !strcmp( hk_keywords->type,"UL1")) |
508 |
{ |
509 |
kwt->eng_type = KW_TYPE_STRING; |
510 |
for (dsc = hk_keywords->dsc; dsc ; dsc= dsc->next) |
511 |
{ |
512 |
if ( hk_keywords->keyword_value >= dsc->low_range && |
513 |
hk_keywords->keyword_value <= dsc->high_range ) |
514 |
{ |
515 |
kwt->eng_value.string_val =(char *) malloc(sizeof(dsc->dsc_value) + 1); |
516 |
strcpy( kwt->eng_value.string_val , dsc->dsc_value); |
517 |
break; |
518 |
} |
519 |
} |
520 |
if ( !kwt->eng_value.string_val) |
521 |
{ |
522 |
kwt->eng_value.string_val =(char *) malloc(sizeof("NO_VALUE") + 1); |
523 |
strcpy( kwt->eng_value.string_val , "NO_VALUE"); |
524 |
printkerr("WARNING at %s, line %d: There are no DSC data lines to set digital type keyword '%s'.\n" |
525 |
"Setting value to NO_VALUE. Check config files and run script to update config files.\n", |
526 |
__FILE__, __LINE__, hk_keywords->keyword_name); |
527 |
} |
528 |
} |
529 |
else |
530 |
{ |
531 |
printkerr("ERROR at %s, line %d: Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->type); |
532 |
return ERROR_HK_UNHANDLED_TYPE; |
533 |
} |
534 |
} /* end else if D type */ |
535 |
else if (hk_keywords->conv_type == 'A') |
536 |
{ |
537 |
/* Calculation is as follows: |
538 |
(1) get raw value |
539 |
(2) get number of coeffs |
540 |
(3) get each coeff value |
541 |
(4) engr value = coeff[0] * pow(raw, 0) + coeff[1] * pow(raw, 1) + .. coeff[4] * pow(raw, 4); |
542 |
*/ |
543 |
if (!strcmp( hk_keywords->type,"UB") || !strcmp( hk_keywords->type ,"IU1") || !strcmp( hk_keywords->type,"UL1")) |
544 |
{ |
545 |
if(hk_keywords->alg) |
546 |
{ |
547 |
kwt->eng_value.double_val=0.0; |
548 |
for (i=0; i < hk_keywords->alg->number_of_coeffs; i++) |
549 |
{ |
550 |
/* check if going to load values in array that exceed array size */ |
551 |
if( i == (MAX_NUMBER_COFFICIENTS)) |
552 |
{ |
553 |
printkerr("WARNING at %s, line %d: Cannot store all coefficients " |
554 |
"in array with total number of coefficients equal to <%d>. " |
555 |
"Can only store 6 coefficients in current array. Adjust array " |
556 |
"size,sscanf,and max number coefficients define in code " |
557 |
"if needed. Currently will scan in only 6 coefficients " |
558 |
"values. Skipping using other coefficient values to avoid " |
559 |
"overrunning array. This could effect analog value.\n", |
560 |
__FILE__, __LINE__, hk_keywords->alg->number_of_coeffs); |
561 |
} |
562 |
else |
563 |
{ |
564 |
|
565 |
kwt->eng_value.double_val += (double)hk_keywords->alg->coeff[i] * (double)powl((double)hk_keywords->keyword_value, (double)i); |
566 |
//kwt->eng_value.double_val += hk_keywords->alg->coeff[i] * powl((double)hk_keywords->keyword_value, (double)i); ADDED Update above to fix compile warning -but does it work with adp. |
567 |
} |
568 |
} |
569 |
} |
570 |
else |
571 |
{ /* handle case when no ACON line which contains coeff. values in config data */ |
572 |
kwt->eng_value.double_val = 0; |
573 |
printkerr("WARNING at %s, line %d: Missing ACON line for keyword '%s'." |
574 |
" Default engr.value set to zero.\n" |
575 |
"Check config files for missing ACON lines for keyword.\n", |
576 |
__FILE__, __LINE__, hk_keywords->keyword_name); |
577 |
} |
578 |
kwt->eng_type = KW_TYPE_DOUBLE;/*set to given type or double */ |
579 |
} |
580 |
else |
581 |
{ |
582 |
printkerr("ERROR at %s, line %d: Engr Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->type); |
583 |
return ERROR_HK_UNHANDLED_TYPE; |
584 |
} |
585 |
}/* else if A type */ |
586 |
else |
587 |
{ |
588 |
printkerr("ERROR at %c, line %d: Conversion Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->conv_type); |
589 |
return ERROR_HK_UNHANDLED_TYPE; |
590 |
} |
591 |
hk_keywords = hk_keywords->next; |
592 |
} /*while-loop*/ |
593 |
return HK_SUCCESSFUL; /* successful*/ |
594 |
} |
595 |
|
596 |
|
597 |
|
598 |
/***************************************************************************** |
599 |
* LOAD HK CONFIGS |
600 |
* Module Name: load_hk_configs |
601 |
* Description: This is the top level function to decode housekeeping keywords. |
602 |
* This function loads in config data for decoding raw value and |
603 |
* engr. values. |
604 |
* Status load_hk_configs(): updated code- not Tested and Reviewed |
605 |
*****************************************************************************/ |
606 |
HK_Keywords_Format *load_hk_configs(HK_Config_Files *config) |
607 |
{ |
608 |
HK_Keywords_Format *new_kw, *new_kw_head; |
609 |
Keyword_Parameter *config_kw; |
610 |
DSC_Conversion *config_dsc, *prev_new_dsc, *new_dsc; |
611 |
ALG_Conversion *config_alg, *new_alg; |
612 |
int i; |
613 |
/* Initialized variables */ |
614 |
config_kw=config->keywords; |
615 |
/* Allocate memory to HK_Keywords_Format structure */ |
616 |
if (config_kw == NULL) |
617 |
{ |
618 |
DHK_ERRMSG("Null pointer input."); |
619 |
return NULL; |
620 |
} |
621 |
/* load values to HK_Keywords_Format structure while not null */ |
622 |
new_kw_head = new_kw = NULL; |
623 |
while (config_kw) |
624 |
{ |
625 |
if (!new_kw) |
626 |
new_kw = new_kw_head = malloc(sizeof(HK_Keywords_Format)); |
627 |
else |
628 |
{ |
629 |
new_kw->next = malloc(sizeof(HK_Keywords_Format)); |
630 |
new_kw = new_kw->next; |
631 |
} |
632 |
new_kw->next = NULL; |
633 |
/* Load config values */ |
634 |
strcpy(new_kw->keyword_name, config_kw->keyword_name); |
635 |
/*for debugging only */ |
636 |
strcpy(new_kw->telemetry_mnemonic_name, |
637 |
config_kw->telemetry_mnemonic_name); |
638 |
/* for parsing later */ |
639 |
new_kw->start_byte = config_kw->start_byte; |
640 |
new_kw->start_bit = config_kw->start_bit_number; |
641 |
/* for parsing later */ |
642 |
strcpy( new_kw->type, config_kw->type); |
643 |
/* for parsing later */ |
644 |
new_kw->bit_length = config_kw->bit_length; |
645 |
new_kw->conv_type = config_kw->conv_type; |
646 |
/* get DSC values for parsing later and setting engr values */ |
647 |
if( config_kw->conv_type == 'D') |
648 |
{ |
649 |
new_kw->dsc = (DSC_Conversion*)NULL;/*ADDED 6-26-2006 */ |
650 |
config_dsc=config_kw->dsc_ptr; |
651 |
prev_new_dsc=NULL; |
652 |
while (config_dsc) |
653 |
{ |
654 |
/* Set low and high range and string value */ |
655 |
new_dsc=(DSC_Conversion*) malloc(sizeof(DSC_Conversion)); |
656 |
if (!prev_new_dsc) |
657 |
{ |
658 |
new_kw->dsc= new_dsc; |
659 |
} |
660 |
new_dsc->low_range = config_dsc->low_range; |
661 |
new_dsc->high_range = config_dsc->high_range; |
662 |
strcpy(new_dsc->dsc_value,config_dsc->dsc_value); |
663 |
new_dsc->next = (DSC_Conversion *)NULL; |
664 |
if(prev_new_dsc) |
665 |
{ |
666 |
prev_new_dsc->next = new_dsc; |
667 |
} |
668 |
/* Go to next node for values */ |
669 |
config_dsc= config_dsc->next; |
670 |
prev_new_dsc=new_dsc; |
671 |
new_dsc= new_kw->dsc->next; |
672 |
} |
673 |
} |
674 |
else |
675 |
{ |
676 |
new_kw->dsc = (DSC_Conversion*)NULL; |
677 |
} |
678 |
/* get ALG values for setting engr values */ |
679 |
if( config_kw->conv_type == 'A') |
680 |
{ |
681 |
config_alg=config_kw->alg_ptr; |
682 |
if (config_alg) |
683 |
{ |
684 |
/* create node & set low and high range and string value */ |
685 |
new_alg = (ALG_Conversion*) malloc(sizeof(ALG_Conversion)); |
686 |
new_kw->alg= new_alg; |
687 |
new_alg->number_of_coeffs = config_alg->number_of_coeffs; |
688 |
for(i=0; i < new_alg->number_of_coeffs; i++) |
689 |
{ |
690 |
new_alg->coeff[i] = config_alg->coeff[i]; |
691 |
} |
692 |
} |
693 |
else |
694 |
{ |
695 |
/* set to null -missing ACON line case */ |
696 |
new_kw->alg= (ALG_Conversion*)NULL; |
697 |
} |
698 |
|
699 |
} |
700 |
else |
701 |
{ |
702 |
new_kw->alg = (ALG_Conversion*)NULL; |
703 |
} |
704 |
|
705 |
/* Go to next keyword-parameter link list |
706 |
node in HK_Config_Files structure */ |
707 |
config_kw = config_kw->next; |
708 |
} |
709 |
return new_kw_head; |
710 |
} |
711 |
|
712 |
|
713 |
|
714 |
/***************************************************************************** |
715 |
* Load HK Values |
716 |
* Module Name: load_hk_values |
717 |
* Description: This function load housekeeping keywords from input data stream. |
718 |
* Status load_hk_values():Review and tested |
719 |
*****************************************************************************/ |
720 |
static int load_hk_values(unsigned short *word_ptr, HK_Keywords_Format *ptr_hk_keywords) |
721 |
{ |
722 |
/* declarations */ |
723 |
HK_Keywords_Format *top_hk_keywords; |
724 |
unsigned int *w; |
725 |
unsigned char *byte_ptr; |
726 |
unsigned int signbit; |
727 |
unsigned int keep_bits; /* 32 bits */ |
728 |
//unsigned int low_word, high_word; |
729 |
uint32_t low_word, high_word; |
730 |
uint64_t dfp_int; |
731 |
|
732 |
/* initialized variables */ |
733 |
top_hk_keywords = ptr_hk_keywords; |
734 |
|
735 |
/* Initialize variable */ |
736 |
byte_ptr= (unsigned char*)(word_ptr+3); |
737 |
|
738 |
/* Loop thru HK_Keywords_Format link list structure and find first value to load */ |
739 |
while ( ptr_hk_keywords != NULL ) |
740 |
{ |
741 |
if(!strcmp(ptr_hk_keywords->type, "UB") || !strcmp(ptr_hk_keywords->type, "SB") ) |
742 |
{ |
743 |
/* set keep bits to zero */ |
744 |
keep_bits=0; |
745 |
/* get raw value */ |
746 |
w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]); |
747 |
/* calculate keep bits mask to use*/ |
748 |
keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length) - 1) ; |
749 |
/* adjust based on bit length and bit position */ |
750 |
ptr_hk_keywords->keyword_value = (unsigned char)(( *w >> (8 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length))) & keep_bits); |
751 |
/* fix for ticket 112 -If IS1 value is negative value then add extented bits to handle IS1 signed value */ |
752 |
if(!strcmp(ptr_hk_keywords->type, "SB")) |
753 |
{ |
754 |
/* get high bit value */ |
755 |
signbit = (unsigned int) (pow( 2, (ptr_hk_keywords->bit_length - 1))) ; |
756 |
/* check for negative sign in high bit then if true, then do sign extention */ |
757 |
if (signbit & ptr_hk_keywords->keyword_value) |
758 |
{ |
759 |
ptr_hk_keywords->keyword_value= ptr_hk_keywords->keyword_value | (0xFFFFFFFF ^ keep_bits); |
760 |
} |
761 |
} |
762 |
} |
763 |
else if( (!strcmp(ptr_hk_keywords->type, "IS1") || !strcmp(ptr_hk_keywords->type, "IU1")) && ptr_hk_keywords->bit_length <= 16) |
764 |
{ |
765 |
/* set keep bits to zero */ |
766 |
keep_bits=0; |
767 |
/* get raw value */ |
768 |
w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]); |
769 |
/* calculate keep bits mask to use*/ |
770 |
keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length) - 1) ; |
771 |
/* set 0th to 7th bits */ |
772 |
ptr_hk_keywords->keyword_value = (unsigned short int) (( (*w ) >> 8) & 0x00FF ); |
773 |
/* set 8th to 15th bits */ |
774 |
ptr_hk_keywords->keyword_value |= (unsigned short int) (( (*w ) << 8 ) & 0xFF00 ); |
775 |
/* adjust based on bit length and bit position */ |
776 |
ptr_hk_keywords->keyword_value = (unsigned int) (( ptr_hk_keywords->keyword_value >> (16 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length))) & keep_bits); |
777 |
/* fix for ticket 112 -If IS1 value is negative value then add extented bits to handle IS1 signed value */ |
778 |
if(!strcmp(ptr_hk_keywords->type, "IS1")) |
779 |
{ |
780 |
/* get high bit value */ |
781 |
signbit = (unsigned int) (pow( 2, (ptr_hk_keywords->bit_length - 1))) ; |
782 |
/* check for negative sign in high bit then do sign extention */ |
783 |
if (signbit & ptr_hk_keywords->keyword_value) |
784 |
{ |
785 |
ptr_hk_keywords->keyword_value= ptr_hk_keywords->keyword_value | (0xFFFFFFFF ^ keep_bits); |
786 |
} |
787 |
} |
788 |
} |
789 |
else if (!strcmp(ptr_hk_keywords->type, "UL1") || !strcmp(ptr_hk_keywords->type, "IL1")) |
790 |
{ |
791 |
/* set keep bits to zero */ |
792 |
keep_bits=0; |
793 |
/* calculate keep bits mask to use*/ |
794 |
keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length ) - 1 ) ; |
795 |
/* get raw value */ |
796 |
w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]); |
797 |
/* set 0th to 7th bits */ |
798 |
ptr_hk_keywords->keyword_value = (unsigned int) ( (*w) >> 24 & 0x000000FF); |
799 |
/* set 8th to 15th bits */ |
800 |
ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) >> 8 & 0x0000FF00); |
801 |
/* set 24th to 31th bits */ |
802 |
ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) << 24 & 0xFF000000); |
803 |
/* set 16th to 23th bits */ |
804 |
ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) << 8 & 0x00FF0000); |
805 |
/* adjust for bit length */ |
806 |
ptr_hk_keywords->keyword_value = (ptr_hk_keywords->keyword_value >> (32 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length ))) & keep_bits ; |
807 |
/* fix for ticket 112 -If IL1 value is negative value then add extented bits to handle IL1 signed value */ |
808 |
if(!strcmp(ptr_hk_keywords->type, "IL1")) |
809 |
{ |
810 |
/* get high bit value */ |
811 |
signbit = (unsigned int) (pow( 2, (ptr_hk_keywords->bit_length - 1))) ; |
812 |
/* check for negative sign in high bit then do sign extention */ |
813 |
if (signbit & ptr_hk_keywords->keyword_value) |
814 |
{ |
815 |
ptr_hk_keywords->keyword_value= ptr_hk_keywords->keyword_value | (0xFFFFFFFF ^ keep_bits); |
816 |
} |
817 |
} |
818 |
} |
819 |
else if (!strcmp(ptr_hk_keywords->type, "SFP")) |
820 |
{ |
821 |
/* set keep bits to zero */ |
822 |
keep_bits=0; |
823 |
/* calculate keep bits mask to use*/ |
824 |
keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length ) - 1 ) ; |
825 |
/* get raw value */ |
826 |
w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]); |
827 |
/* set 0th to 7th bits */ |
828 |
ptr_hk_keywords->keyword_value = (unsigned int) ( (*w) >> 24 & 0x000000FF); |
829 |
/* set 8th to 15th bits */ |
830 |
ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) >> 8 & 0x0000FF00); |
831 |
/* set 24th to 31th bits */ |
832 |
ptr_hk_keywords->keyword_value |= ( unsigned int) ( (*w) << 24 & 0xFF000000); |
833 |
/* set 16th to 23th bits */ |
834 |
ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) << 8 & 0x00FF0000); |
835 |
/* adjust for bit length */ |
836 |
ptr_hk_keywords->keyword_value = (ptr_hk_keywords->keyword_value >> (32 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length ))) & keep_bits ; |
837 |
|
838 |
} |
839 |
else if (!strcmp(ptr_hk_keywords->type, "DFP")) |
840 |
{ |
841 |
/* set keep bits to zero */ |
842 |
keep_bits=0; |
843 |
/* calculate keep bits mask to use*/ |
844 |
keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length ) - 1 ) ; |
845 |
/* get raw value of first word from packet */ |
846 |
w = (unsigned int *) &(byte_ptr[ptr_hk_keywords->start_byte]); |
847 |
/* set 0th to 7th bits */ |
848 |
low_word = (unsigned int) ( (*w) >> 24 & 0x000000FF); |
849 |
/* set 8th to 15th bits */ |
850 |
low_word |= (unsigned int) ( (*w) >> 8 & 0x0000FF00); |
851 |
/* set 16th to 23th bits */ |
852 |
low_word |= (unsigned int) ( (*w) << 8 & 0x00FF0000); |
853 |
/* set 24th to 31th bits */ |
854 |
low_word |= ( unsigned int) ( (*w) << 24 & 0xFF000000); |
855 |
/* get raw value of second word from packet */ |
856 |
w = (unsigned int *) &(byte_ptr[ptr_hk_keywords->start_byte + 4]); |
857 |
/* set 32th to 39th bits */ |
858 |
high_word |= (unsigned int) ( (*w) >> 24 & 0x000000FF); |
859 |
/* set 40th to 47th bits */ |
860 |
high_word |= (unsigned int) ( (*w) >> 8 & 0x0000FF00); |
861 |
/* set 48th to 55th bits */ |
862 |
high_word |= (unsigned int) ( (*w) << 8 & 0x00FF0000); |
863 |
/* set 56th to 63nd bits */ |
864 |
high_word |= ( unsigned int) ( (*w) << 24 & 0xFF000000); |
865 |
/* combine low and high words to make 64 bit int */ |
866 |
//1st try-dfp_int = (uint64_t)low_word ; |
867 |
dfp_int = (uint64_t)high_word ; |
868 |
//1st try-dfp_int |= (uint64_t)(((uint64_t)high_word << 32) & (0xFFFFFFFF00000000)); |
869 |
dfp_int |= (uint64_t)(((uint64_t)low_word << 32) & (0xFFFFFFFF00000000)); |
870 |
ptr_hk_keywords->keyword_value = (uint64_t)dfp_int; |
871 |
} |
872 |
else |
873 |
{ |
874 |
printkerr("ERROR at %s, line %d: Did not find this bit length for keyword %s\n", |
875 |
__FILE__, __LINE__, ptr_hk_keywords->keyword_name ); |
876 |
//return ERROR_HK_INVALID_BITFIELD_LENGTH; |
877 |
} |
878 |
ptr_hk_keywords = ptr_hk_keywords->next; |
879 |
} |
880 |
ptr_hk_keywords= top_hk_keywords; |
881 |
return (HK_SUCCESSFUL); /*no errors */ |
882 |
} /*END-module :load_hk_values()*/ |
883 |
|
884 |
|
885 |
/***************************************************************************** |
886 |
* DeAllocate HK Keywords Format |
887 |
* Module Name: deallocate_hk_keywords_format() |
888 |
* Description: This functions deallocates keywords-nods in |
889 |
* HK_Keywords_Format link list structures. |
890 |
* Status deallocate_hk_keywords_format(): Tested and Reviewed 6-28-2006 |
891 |
*****************************************************************************/ |
892 |
static void deallocate_hk_keywords_format(HK_Keywords_Format *head) |
893 |
{ |
894 |
HK_Keywords_Format *tmp; |
895 |
DSC_Conversion *d_tmp, *d_head; |
896 |
|
897 |
while(head) |
898 |
{ |
899 |
/*clear dsc nodes*/ |
900 |
d_head=head->dsc; |
901 |
while (d_head) |
902 |
{ |
903 |
d_tmp=d_head->next; |
904 |
free(d_head); |
905 |
d_head= d_tmp; |
906 |
} |
907 |
|
908 |
/*clear alg nodes*/ |
909 |
if (head->alg) |
910 |
{ |
911 |
free(head->alg); |
912 |
} |
913 |
|
914 |
/*clear HK_Keyword_Format nodes */ |
915 |
tmp = head->next; |
916 |
free(head); |
917 |
head = tmp; |
918 |
} |
919 |
} |
920 |
|
921 |
/***************************************************************************** |
922 |
* DeAllocate HK Keyword_t link list structure |
923 |
* Module Name: deallocate_hk_keywords_t |
924 |
* Description: This functions deallocates keywords-nodes in |
925 |
* HK_Keywords_t Structure. |
926 |
* Status deallocate_hk_keyword_t(): Tested and Reviewed. |
927 |
*****************************************************************************/ |
928 |
void deallocate_hk_keyword(HK_Keyword_t *head) |
929 |
{ |
930 |
HK_Keyword_t *tmp; |
931 |
|
932 |
while(head) |
933 |
{ |
934 |
tmp = head->next; |
935 |
if (head->eng_type == KW_TYPE_STRING && head->eng_value.string_val) |
936 |
{ |
937 |
free(head->eng_value.string_val); |
938 |
} |
939 |
free(head); |
940 |
head = tmp; |
941 |
} |
942 |
} |
943 |
|
944 |
|
945 |
|
946 |
/***************************************************************************** |
947 |
* COPY HK Keywords |
948 |
* |
949 |
*****************************************************************************/ |
950 |
HK_Keyword_t *copy_hk_keywords(HK_Keyword_t *head) |
951 |
{ |
952 |
HK_Keyword_t *newhead, *p; |
953 |
|
954 |
if (head) |
955 |
{ |
956 |
newhead = malloc(sizeof(HK_Keyword_t)); |
957 |
if(!newhead) |
958 |
{ |
959 |
printkerr("ERROR at %s, line %d: malloc failed to allocate space\n",__FILE__, __LINE__); |
960 |
} |
961 |
p = newhead; |
962 |
memcpy(p, head, sizeof(HK_Keyword_t)); |
963 |
if (head->eng_type == KW_TYPE_STRING) |
964 |
p->eng_value.string_val = strdup(head->eng_value.string_val); |
965 |
head = head->next; |
966 |
while(head) |
967 |
{ |
968 |
p->next = malloc(sizeof(HK_Keyword_t)); |
969 |
if(!p->next) |
970 |
{ |
971 |
printkerr("ERROR at %s, line %d: malloc failed to allocate space\n",__FILE__, __LINE__); |
972 |
} |
973 |
|
974 |
p = p->next; |
975 |
memcpy(p, head, sizeof(HK_Keyword_t)); |
976 |
if (head->eng_type == KW_TYPE_STRING) |
977 |
p->eng_value.string_val = strdup(head->eng_value.string_val); |
978 |
head = head->next; |
979 |
} |
980 |
} |
981 |
else |
982 |
newhead = NULL; |
983 |
|
984 |
return newhead; |
985 |
} |
986 |
|
987 |
/***************************************************************************** |
988 |
* TRANSLATE INTEGER TO DOUBLE |
989 |
* |
990 |
*****************************************************************************/ |
991 |
double translateint2double(int64_t ival) |
992 |
{ |
993 |
#define HK_DPF_RADIX 2 |
994 |
#define HK_DPF_BIAS 1023 |
995 |
/* declare variables */ |
996 |
int i, x; |
997 |
int radix; |
998 |
int bias; |
999 |
int sign_bit; |
1000 |
int64_t imatissa; |
1001 |
int iexp; |
1002 |
int iexp_posinf; |
1003 |
int iexp_neginf; |
1004 |
double calexp=0.0; |
1005 |
double cal_matissa=0.0; |
1006 |
double sum=0.0; |
1007 |
double d=0.0; |
1008 |
|
1009 |
/* 1.set sign bit*/ |
1010 |
sign_bit=ival >> 63 & 0x00000000000001; |
1011 |
|
1012 |
/* 2.radix*/ |
1013 |
radix=HK_DPF_RADIX; |
1014 |
|
1015 |
/* 3.bias */ |
1016 |
bias=HK_DPF_BIAS; |
1017 |
|
1018 |
/* 4.get exponent bits where e are exponent bits: |
1019 |
s eee eeee eeee mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm |
1020 |
0th---1st------11th--12th--------------------------------------------------------52st |
1021 |
*/ |
1022 |
iexp=(ival >> 52) & 0x000007FF; |
1023 |
|
1024 |
/* 4.1.check for -inf and +inf-view documentation on this at http://en.wikipedia.org/wiki/Double_precision */ |
1025 |
iexp_posinf=(ival >> 52) & 0x000007FF; |
1026 |
iexp_neginf=(ival >> 52) & 0x00000FFF; |
1027 |
if (iexp_posinf == 2047) |
1028 |
{ |
1029 |
//printkerr("translateint2double:WARNING got +infinity exponent value:exp is %d\n",iexp_posinf); |
1030 |
//printkerr("translateint2double:CHECK:double value set correctly in DRMS\n"); |
1031 |
} |
1032 |
else if (iexp_neginf == 4095) |
1033 |
{ |
1034 |
//printkerr("translateint2double:WARNING got -infinity exponent value:exp is %d\n",iexp_neginf); |
1035 |
//printkerr("translateint2double:CHECK:double value set correctly in DRMS\n"); |
1036 |
} |
1037 |
|
1038 |
/* 5. calculate exponent value to use in formula */ |
1039 |
calexp=(double)(iexp - bias); |
1040 |
|
1041 |
/* 6. get 1.m value or matissa value to use in formula. |
1042 |
utilize bits in matissa to get summation value where |
1043 |
if bit 12(matissa first bit) is one, sum=.5 and |
1044 |
if bit 13(matissa second bit) is two, sum=.25 |
1045 |
or 2^-1 and 2 ^-2 respectively. |
1046 |
*/ |
1047 |
imatissa= (ival) & 0x000FFFFFFFFFFFFF; |
1048 |
|
1049 |
|
1050 |
/*loop thru matissa bits start at known low bit(bit 12 in word)*/ |
1051 |
for (i =0, x=52; i < 53; i++, x--) |
1052 |
{ |
1053 |
/* check if first bit to last bit in matissa are set */ |
1054 |
//does not do large numbers::printf(" pow mask is %ld \n",(int) powl((int)2,(int)x)); |
1055 |
if (imatissa & (int64_t)(powl((double)2, (double)x))) |
1056 |
{ |
1057 |
/* if matissa bit set then add to sum value |
1058 |
and calculate current value using bit position |
1059 |
i which goes from 1 to 52. |
1060 |
*/ |
1061 |
sum += (double)(powl((double)2,(double)-i)); |
1062 |
} |
1063 |
} |
1064 |
cal_matissa=(double)(1.0 + sum); |
1065 |
/* 7. calculate 32 bit float using formula */ |
1066 |
d= (double)((pow(-1,sign_bit)) * (cal_matissa) * pow(radix, calexp)); |
1067 |
return(d); |
1068 |
|
1069 |
} |
1070 |
/***************************************************************************** |
1071 |
* Translateint2float |
1072 |
* |
1073 |
*****************************************************************************/ |
1074 |
float translateint2float(int ival) |
1075 |
{ |
1076 |
#define HK_RADIX 2 |
1077 |
#define HK_BIAS 127 |
1078 |
/* declare variables */ |
1079 |
int radix; |
1080 |
int bias; |
1081 |
int sign_bit; |
1082 |
int imatissa; |
1083 |
int iexp; |
1084 |
int iexp_posinf; |
1085 |
int iexp_neginf; |
1086 |
float calexp; |
1087 |
float cal_matissa; |
1088 |
float f; |
1089 |
int i,x; |
1090 |
float sum=0.0; |
1091 |
|
1092 |
/* 1.set sign bit*/ |
1093 |
sign_bit=ival >> 31; |
1094 |
|
1095 |
/* 2.radix*/ |
1096 |
radix=HK_RADIX; |
1097 |
|
1098 |
/* 3.bias */ |
1099 |
bias=HK_BIAS; |
1100 |
|
1101 |
/* 4.get exponent bits where e are exponent bits: |
1102 |
s eeeeeeee mmm mmmm mmmm mmmm mmmm mmmm |
1103 |
0th---1st----8th----9th-------------------------31st |
1104 |
*/ |
1105 |
iexp=(ival >> 23) & 0x000000FF; |
1106 |
|
1107 |
/* 4.1.check for -inf and +inf-view documentation on this at http://en.wikipedia.org/wiki/Floating_point */ |
1108 |
iexp_posinf=(ival >> 23) & 0x0000007F; |
1109 |
iexp_neginf=(ival >> 23) & 0x000000FF; |
1110 |
if (iexp_posinf == 127) |
1111 |
{ |
1112 |
; |
1113 |
//printkerr("translateint2float:WARNING got +infinity exponent value:exp is %d ival:%d iexp:%d\n",iexp_posinf,ival,iexp); |
1114 |
//printkerr("translateint2float:CHECK:float value set correctly in DRMS\n"); |
1115 |
} |
1116 |
else if (iexp_neginf == 255) |
1117 |
{ |
1118 |
; |
1119 |
//printkerr("translateint2float:WARNING got -infinity exponent value:exp is %d ival is %d\n",iexp_neginf,ival); |
1120 |
//printkerr("translateint2float:CHECK:float value set correctly in DRMS\n"); |
1121 |
} |
1122 |
|
1123 |
/* 5. calculate exponent value to use in formula */ |
1124 |
calexp=(float)(iexp - bias); |
1125 |
|
1126 |
/* 6. get 1.m value or matissa value to use in formula. |
1127 |
utilize bits in matissa to get summation value where |
1128 |
if bit 9(matissa first bit) is one, sum=.5 and |
1129 |
if bit 10(matissa second bit) is two, sum=.25 |
1130 |
or 2^-1 and 2 ^-2 respectively. |
1131 |
*/ |
1132 |
imatissa= (ival) & 0x007FFFFF; |
1133 |
/*loop thru matissa bits start at known low bit(bit 9 in word)*/ |
1134 |
for (i =1, x=22; i < 24; i++, x--) |
1135 |
{ |
1136 |
/* check if first bit to last bit in matissa are set */ |
1137 |
if (imatissa & (unsigned int)(pow(2, x))) |
1138 |
{ |
1139 |
/* if matissa bit set then add to sum value |
1140 |
and calculate current value using bit position |
1141 |
i which goes from 1 to 23. |
1142 |
*/ |
1143 |
sum += (float)pow(2, -i); |
1144 |
} |
1145 |
} |
1146 |
cal_matissa=1 + sum; |
1147 |
|
1148 |
|
1149 |
/* 7. calculate 32 bit float using formula */ |
1150 |
f= (float)((pow(-1,sign_bit)) * (cal_matissa) * pow(radix, calexp)); |
1151 |
return(f); |
1152 |
|
1153 |
//Formula to calculate: |
1154 |
//value = (-1) ^ sign-bit *((radix) ^ (exponent - bias) * ((1) + 2^(-bit value=matissa)) |
1155 |
// radix=2, bias=0x7f(127 decimal), matissa = 1 + 2^(bit-value-matissa) |
1156 |
// example for 3: value =(-1)^0 *(2) ^(128-127) * (1 + 2^(-1) |
1157 |
} |