CARMA C++
regmap.h
1 #ifndef regmap_h
2 #define regmap_h
3 
4 #include "carma/szaarrayutils/netbuf.h"
5 #include "carma/szaarrayutils/input.h"
6 #include "carma/szaarrayutils/output.h"
7 
9 #include "carma/szautil/Coord.h"
10 
11 #include <map>
12 
13 /*
14  * List supported addressing modes.
15  */
16 typedef enum {
17  ADDR_A16D08_O, /* A 16-bit address of an 8-bit-odd register */
18  ADDR_A24D08_O, /* A 24-bit address of an 8-bit-odd register */
19  ADDR_A32D08_O, /* A 32-bit address of an 8-bit-odd register */
20  ADDR_A16D08_EO, /* A 16-bit address of an 8-bit-even/odd register */
21  ADDR_A24D08_EO, /* A 24-bit address of an 8-bit-even/odd register */
22  ADDR_A32D08_EO, /* A 32-bit address of an 8-bit-even/odd register */
23  ADDR_A16D16, /* A 16-bit address of a 16-bit register */
24  ADDR_A24D16, /* A 24-bit address of a 16-bit register */
25  ADDR_A32D16, /* A 32-bit address of a 16-bit register */
26  ADDR_A16D32, /* A 16-bit address of a 32-bit register */
27  ADDR_A24D32, /* A 24-bit address of a 32-bit register */
28  ADDR_A32D32, /* A 32-bit address of a 32-bit register */
29  ADDR_A16D16_L, /* A 16-bit address of a 32-bit (aka longword) */
30  /* register to be read via two D16 transfers */
31  ADDR_A24D16_L, /* A 24-bit address of a 32-bit (aka longword) */
32  /* register to be read via two D16 transfers */
33  ADDR_A32D16_L, /* A 32-bit address of a 32-bit (aka longword) */
34  /* register to be read via two D16 transfers */
35  ADDR_DEFAULT /* A local 32-bit array of 32-bit integers */
36 } RegAddrMode;
37 
38 /*
39  * The following bit-mask enumerators are used to specify many of the
40  * characteristics of each register. When describing a register in
41  * a RegBlkTmpl template, the value of the flags member is either 0,
42  * or the bitwise OR of one or more of the following enumerators.
43  * Note that REG_READABLE and REG_WRITABLE are ignored for REG_LOCAL
44  * registers. Also note that when writing to unreadable vme registers,
45  * a copy of the written value is recorded in a software shadow
46  * register. This value will be returned on subsequent reads.
47  * REG_EXC should be used for registers that are used internally
48  * but shouldn't be archived. Note that reading from vme registers can
49  * sometimes have side-effects such as acknowledging an interrupt, so
50  * be careful to exclude such registers from the archive.
51  */
52 enum RegFlags {
53  REG_NONE = 0x0, // None of the following.
54  REG_COMPLEX = 0x1, // Include if register contains real,imaginary
55  // pairs Exclude if register contains only real
56  // values
57  REG_R = 0x4, // Include if the register's vme address is
58  // readable. Exclude to read written values from
59  // the shadow array.
60  REG_W = 0x8, // Include if the register's vme address is
61  // writable. Exclude if the register can't be
62  // written to.
63  REG_RW = REG_R | REG_W,
64  REG_PREAVG = 0x10, // Include for integrated registers. Exclude if
65  REG_POSTAVG = 0x20, // Include for integrated registers. Exclude if
66  REG_SUM = 0x40, // Include for integrated registers. Exclude if
67  // the register contains a snapshot value.
68  REG_UNION = 0x80, // Including this tells the archiver to
69  // integrate this register by taking the
70  // bit-mask union of the values of the register
71  // that are to be combined.
72  REG_EXC = 0x100, // Include to exclude the register from the
73  // archive. Exclude to include the register in
74  // the archive.
75  REG_UTC = 0x200, // Include for registers that represent times in
76  // UTC. Such registers must consist of one or
77  // more pairs of elements in which the first
78  // element contains a modified Julian day
79  // number, and the second element contains the
80  // corresponding time of day in milliseconds.
81  REG_PCI = 0x400, // A PCI register.
82  REG_BOOL = 0x800, // This register of single bytes
83  REG_CHAR = 0x1000, // This register of single bytes
84  REG_UCHAR = 0x2000, // This register of single bytes
85  REG_SHORT = 0x4000, // This register of shorts
86  REG_USHORT = 0x8000, // This register of shorts
87  REG_INT = 0x10000, // A register of ints
88  REG_UINT = 0x20000, // A register of ints
89  REG_FLOAT = 0x40000, // A register of floating point values
90  REG_DOUBLE = 0x80000, // A register of doubles
91  REG_DEFAULT = REG_UINT,// The default is a register of unsigned ints
92  // which should be summed together on integration
93  REG_DPRAM = 0x100000,// Include if this is a register on the PMAC's
94  // DPRAM. These registers will correspond to an
95  // actual memory space in the PMAC DPRAM, but
96  // are read and written over a serial
97  // connection. Internally these registers are
98  // read from and written to shadow registers.
99  REG_STRING = 0x200000,// Include if this is a register should be
100  // interpreted as a string
101  REG_FIRST = 0x400000,// Include if this register should assume the
102  // first value when integrating it
103 };
104 
105 /*
106  * Record the locations at which VME address spaces are mapped
107  * into VxWorks memory.
108  */
109 #define VME_A16_BASE 0x0
110 #define VME_A24D16_BASE 0x0
111 #define VME_A24D32_BASE 0x0
112 #define VME_A32_BASE 0x0
113 
114 /*
115  * Set the max length of names of register blocks and boards.
116  */
117 #define REG_NAME_LEN 100
118 
119 /*
120  * Define type aliases for the structures that are being declared
121  * below.
122  */
123 typedef struct RegMapBlock RegMapBlock;
124 typedef struct RegMapBoard RegMapBoard;
125 typedef struct RegMap RegMap;
126 
127 /*
128  * Describe an array of registers.
129  */
130 struct RegMapBlock {
131  RegMapBoard* brd_; // The parent register board
132  unsigned number_; // The index of the block on its parent
133  // board
134  char name_[REG_NAME_LEN+1]; // The name of the block of registers
135  std::string* comment_;
136  unsigned flags_; // A bit-set of RegFlags enumerators
137  RegAddrMode addr_mode_; // The addressing mode of the register
138  unsigned location_; // The address of the first register in
139  // VxWorks address-space (0 for non-VME
140  // registers)
141  unsigned ireg_; // The sequential number of the first
142  // register
143  unsigned nreg_; // The total number of elements in the
144  // block
145  int slot_; // The start index of the block in the
146  // archive array (or -1 if [flags &
147  // REG_EXC != 0].
148 
149  sza::util::CoordAxes* axes_; // An axis specifier for this register
150 
151  unsigned iSlot_; // The sequential slot index of the
152  // first register in parent slot array
153  unsigned iArcSlot_; // The sequential slot index of the
154  // first register in parent archived
155  // slot array
156  unsigned iByte_; // The sequential byte index of the
157  // first register in the parent register
158  // map
159  int iArcByte_; // The starting index of this block in
160  // the archive byte array, or -1 if this
161  // register is not archived
162  unsigned nBytePerEl_; // The number of bytes in each element
163  // of this register
164 
165  std::string* carmaUnits_;
166  std::vector<std::pair<std::string, std::string> >* carmaErrors_;
167 
168  int carmaValidityBitIndex_; // Sequential index into the CARMA
169  // validity array of the start of this
170  // block
171 
172  // Methods of the RegMapBlock struct
173 
174  // Constructors
175 
176  RegMapBlock();
177 
178  RegMapBlock(RegMapBoard* parent, void* tbrd, void* tblk,
179  unsigned iBlock, unsigned nper_brd_blocks);
180 
181  // Destructor
182 
183  ~RegMapBlock();
184 
185  // Return the number of bytes in this register block
186 
187  unsigned nByte();
188 
189  // Return the total number of elements in this register
190 
191  unsigned nEl();
192 
193  // Return the number of bytes per element of this register
194 
195  unsigned nBytePerEl() {
196  return nBytePerEl_;
197  }
198 
199  // Return the offset, in bytes, of the requested element of this
200  // register in the register map archive array
201 
202  int byteOffsetInWholeRegMapOf(sza::util::Coord* coord=0);
203  int byteOffsetInArcRegMapOf(sza::util::Coord* coord=0);
204 
205  // Convenience method for the above
206 
207  int byteOffsetInRegMapOf(bool archivedOnly, sza::util::Coord* coord=0) {
208  return archivedOnly ? byteOffsetInArcRegMapOf(coord) :
209  byteOffsetInWholeRegMapOf(coord);
210  }
211 
212  // Methods for returning the slot offset of an element of this
213  // register
214 
215  int slotOffsetInArcRegMapOf(sza::util::Coord* coord=0) {
216  return (int)(iArcSlot_ + elementOffsetOf(coord));
217  }
218 
219  int slotOffsetInWholeRegMapOf(sza::util::Coord* coord=0) {
220  return iSlot_ + (int)elementOffsetOf(coord);
221  }
222 
223  // Return the start index of this block in the archived slot array
224 
225  int slotOffsetInRegMapOf(bool archivedOnly, sza::util::Coord* coord=0) {
226  return archivedOnly ? slotOffsetInArcRegMapOf(coord) :
227  slotOffsetInWholeRegMapOf(coord);
228  }
229 
230  // Methods returning the element offset of the requested coordinate
231 
232  int elementOffsetOf(sza::util::Coord* coord);
233 
234  // Return true if this block is archived
235 
236  bool isArchived();
237 
238  // Return true if the block type matches
239 
240  bool isBool();
241  bool isUchar();
242  bool isString();
243  bool isChar();
244  bool isUshort();
245  bool isShort();
246  bool isUint();
247  bool isInt();
248  bool isFloat();
249  bool isDouble();
250  bool isUtc();
251 
252  bool isSummed(); // True if summed on integration
253  bool isUnioned(); // True if bitwise-unioned on integration
254  bool isPreAveraged(); // True if averaged on integration
255  bool isPostAveraged(); // True if averaged when read
256  bool isFirst(); // True if assumes the first value when
257  // integrating
258  bool isComplex();
259 
263  void checkConsistency();
264 
268  void checkType(unsigned flags);
269 
273  void checkIntegration(unsigned flags);
274 
278  void checkAttributes();
279 
280  friend std::ostream& operator<<(std::ostream& os, RegMapBlock& block);
281 };
282 
283 /*
284  * Collect registers that reside on a given board.
285  */
286 struct RegMapBoard {
287  RegMap *regmap; /* The parent register map */
288  unsigned number; /* The index of the board in the register map */
289  char name[REG_NAME_LEN+1]; /* An unambiguous name for the board */
290  std::string* comment_;
291  std::vector<RegMapBlock*> blocks; /* The registers of the board */
292  std::map<std::string, RegMapBlock*> blockMap_; /* The registers of the board */
293  int nblock; /* The number of register blocks in blocks[] */
294  unsigned nreg; /* The total number of registers on the board */
295  unsigned narchive; /* The number of archived registers on the board */
296 
297  unsigned nByte_;
298  unsigned nArcByte_;
299 
300  unsigned iSlot_; // The sequential index of the first
301  // register of this board in the parent
302  // register map slot array
303  int iArcSlot_; // The sequential index of the first
304  // register of this board in the parent
305  // archived slot array
306  unsigned iByte_; // The sequential index of the first byte
307  // of this board in the parent register map
308  int iArcByte_; // The sequential index of the first byte
309  // of this board in the archived parent
310  // register map
311 
312  // Return the byte offset of this board in the parent register map
313 
314  int byteOffsetInRegMap(bool archivedOnly) {
315  return archivedOnly ? iArcByte_ : iByte_;
316  }
317 
318  // Return the slot offset of this board in the parent register map
319 
320  int slotOffsetInRegMap(bool archivedOnly) {
321  return archivedOnly ? iArcSlot_ : iSlot_;
322  }
323 
324  // Return the number of bytes in this board
325 
326  unsigned nByte(bool archivedOnly) {
327  return archivedOnly ? nArcByte_ : nByte_;
328  }
329 
330  RegMapBoard();
331 
332  RegMapBoard(RegMap* parent, void* vbrd, unsigned iboard,
333  void* vper_brd_blocks=0, unsigned nper_brd_blocks=0);
334 
335  ~RegMapBoard();
336 
337  // Return the named register block
338 
339  RegMapBlock* findRegMapBlock(std::string blockName);
340 
341  // Return a vector of blocks matching the input string
342 
343  std::vector<RegMapBlock*> matchRegMapBlock(std::string regExpStr);
344  std::vector<RegMapBlock*> matchRegMapBlock(std::vector<std::string>& blocks);
345 };
346 
347 /*
348  * Collect information about all boards.
349  */
350 struct RegMap {
351  unsigned ref_count_; // Reference counter
352  std::vector<RegMapBoard*> boards_; // All addressable boards
353  std::map<std::string, RegMapBoard*> boardMap_;
354  int nboard_; // The number of boards
355  unsigned nreg_; // The total number of registers
356  unsigned narchive_; // The total number of archived registers
357  unsigned nByte_; // The size in bytes of all registers in
358  // this register map
359  unsigned nArcByte_; // The size in bytes of all archived
360  // registers in this register map
361 
362  // A constructor
363 
364  RegMap(void *regtmp, bool old=false, bool addRegs=true);
365 
366  // Destructor
367 
368  ~RegMap();
369 
370  void privateConstructor(void* regtmp, bool addRegs=true);
371  void privateConstructorOld(void* regtmp);
372 
373  // Return the offset, in bytes_ of the named board and block from
374  // the start of the archived array
375 
376  int byteOffsetInArcRegMapOf(std::string board, std::string block,
377  sza::util::Coord* coord=0);
378  int byteOffsetInWholeRegMapOf(std::string board, std::string block,
379  sza::util::Coord* coord=0);
380 
381  // Convenience method for the above two
382 
383  int byteOffsetInRegMapOf(bool archivedOnly,
384  std::string board, std::string block,
385  sza::util::Coord* coord=0) {
386  return archivedOnly ? byteOffsetInArcRegMapOf(board, block, coord) :
387  byteOffsetInWholeRegMapOf(board, block, coord);
388  }
389 
390  int byteOffsetInArcRegMapOf(RegMapBlock* blk, sza::util::Coord* coord=0);
391  int byteOffsetInWholeRegMapOf(RegMapBlock* blk, sza::util::Coord* coord=0);
392 
393  // Convenience method for the above two
394 
395  int byteOffsetInRegMapOf(bool archivedOnly,
396  RegMapBlock* blk,
397  sza::util::Coord* coord=0) {
398  return archivedOnly ? byteOffsetInArcRegMapOf(blk, coord) :
399  byteOffsetInWholeRegMapOf(blk, coord);
400  }
401 
402  unsigned nByte() {return nByte_;};
403  unsigned nArcByte() {return nArcByte_;};
404 
405  // Convenience method for the above two
406 
407  int nByte(bool archivedOnly) {
408  return archivedOnly ? nArcByte() : nByte();
409  }
410 
411  // Find the named block
412 
413  RegMapBlock* findRegMapBlock(std::string board_name, std::string block_name,
414  bool doThrow=false);
415 
416 };
417 
418 /* NB. new_RegMap() is prototyped in regtemplate.h */
419 
423 RegMap* del_RegMap(RegMap* regmap);
424 
425 /* Allocate a readonly alias to a given register map. */
426 /* When no longer required this should be discarded by calling */
427 /* del_RegMap(). */
428 
429 RegMap *alias_RegMap(RegMap *regmap);
430 
431 /* Return non-zero if two register maps are equivalent. */
432 
433 int equiv_RegMap(RegMap *regmap1, RegMap *regmap2);
434 
435 RegMapBoard *find_RegMapBoard(RegMap *regmap, std::string board_name);
436 RegMapBlock *find_RegMapBoard_Block(RegMapBoard *board, std::string block_name);
437 RegMapBlock *find_RegMapBlock(RegMap *regmap, std::string board_name,
438  std::string block_name);
439 
440 /*
441  * Enumerate the register-specifications read by input_RegMapReg().
442  * The comment next to each mode indicates the type of input expected,
443  * where "board" is the name of a board, "register" is the name of
444  * a block of registers, and index is the sequential number of
445  * a register within a block.
446  */
447 typedef enum {
448  REG_INPUT_BLOCK, /* board.register */
449  REG_INPUT_ELEMENT, /* board.register[index] */
450  REG_INPUT_RANGE /* board.register[index-index] */
451 } RegInputMode;
452 
453 /*
454  * When the extend argument of input_RegMapReg() is true, and a complex or
455  * utc register-pair specification is read, a member of the following type
456  * is used to record what aspect of the complex register has been selected
457  * by the user. If the user doesn't specify anything then REG_PLAIN is
458  * substituted. Where appropriate these enumerators can be used as
459  * indexes of arrays of REG_NASPECT elements.
460  */
461 typedef enum {
462  REG_ASPECT_UNKNOWN,
463  REG_PLAIN, /* Treat complex register pairs as two registers */
464  REG_REAL, /* The real member of the complex register pair */
465  REG_IMAG, /* The imaginary member of the complex register pair */
466  REG_AMP, /* The amplitude of a complex register pair */
467  REG_PHASE, /* The phase of a complex register pair */
468  REG_DATE, /* The Modified Julian Date of a day/time utc pair */
469  REG_TIME /* The time-of-day of a day/time utc pair */
470 } RegAspect;
471 
472 enum {REG_NASPECT = 8}; /* The number of enumerators in RegAspect */
473 
474 char *name_RegAspect(RegAspect aspect);
475 
476 typedef enum {
477  REG_INT_UNKNOWN,
478  REG_INT_PLAIN, // Treat the register normally
479  REG_INT_INT, // Integrate the register
480  REG_INT_DER // Take the derivative of the register
481 } RegInteg;
482 
483 enum {REG_NINTEG = 4}; /* The number of enumerators in RegInteg */
484 
485 char *name_RegInteg(RegInteg integ);
486 
487 
488 /*
489  * A structure of the following form is filled by input_RegMapReg().
490  * The meanings of reg and nreg depend on the input mode as follows:
491  *
492  * REG_INPUT_BLOCK:
493  * index will be 0.
494  * slot will be the frame index of the first register of the block.
495  * nreg will be the number of registers in the block.
496  * REG_INPUT_ELEMENT:
497  * index will be the block index of the selected member of the block.
498  * slot will be the frame index of the selected member of the block.
499  * nreg will always be 1.
500  * REG_INPUT_RANGE:
501  * index will be the block index of the selected member of the block.
502  * slot will be the frame index of the first selected member of the block.
503  * nreg will be the number of registers in the range.
504  *
505  * Note that if the selected register is not an archived register, the
506  * slot index will be -1.
507  */
508 struct RegMapReg {
509  int board; // The index of the specified board in the
510  // register-map
511  int block; // The index of the specified block on the
512  // regmap board
513  unsigned index; // The block index of the first register
514  // specified
515  signed slot; // The frame index of the first register
516  // specified
517  unsigned nreg; // The number of registers specified. The
518  // associated regmap slots are: slot -> slot +
519  // nreg*size - 1
520  unsigned size; // The number of slots per register. This is 1
521  // unless aspect!=REG_PLAIN, in which case it
522  // becomes 2
523  RegAspect aspect; // The quantity to derive from complex or utc
524  // register pairs
525  RegInteg integ; // The integration status of this register
526  // register pairs
527  int iByte_; // The byte index into the register map of the
528  // first register specified
529  int iArcByte_; // The byte index into the archived register
530  // map of the first register specified
531  unsigned nBytePerEl_;// The number of bytes per element of this register
532 
533  sza::util::CoordAxes* axes_; // An axis specifier for this register
534  sza::util::CoordRange* range_; // An index-range specifier
535 };
536 
537 int find_RegMapReg(RegMap *regmap, std::string board_name, std::string block_name,
538  RegAspect facet, unsigned index, unsigned n,
539  RegMapReg *reg);
540 
541 int init_RegMapReg(RegMap *regmap, unsigned board, unsigned block,
542  unsigned index, unsigned nreg, RegAspect aspect,
543  RegMapReg *reg);
544 
545 typedef enum {
546  REG_VALID=0, /* A valid register was found */
547  REG_UNKNOWN, /* Valid specification syntax, but unknown register */
548  REG_INVALID /* Invalid register specification syntax */
549 } RegValidity;
550 
551 RegValidity input_RegMapReg(InputStream *stream, int tell, RegMap *regmap,
552  RegInputMode mode, int extend, RegMapReg *reg);
553 
554 /*
555  * Save a register specification in the form read by input_RegMapReg().
556  */
557 typedef enum {
558  REG_OUTPUT_BLOCK, /* board.register */
559  REG_OUTPUT_ELEMENT, /* board.register[index] */
560  REG_OUTPUT_RANGE /* board.register[index-index] */
561 } RegOutputMode;
562 
563 int output_RegMapReg(OutputStream *stream, RegMap *regmap, RegOutputMode mode,
564  RegMapReg *reg);
565 
566 void clr_RegMapReg(RegMapReg *reg);
567 
568 /*
569  * If registers are represented as 32-bit integers then we need a method
570  * to pack a string into an array of 32-bit integers. The following function
571  * does this.
572  */
573 int pack_int_string(char *string, int ndata, unsigned *data);
574 
575 /*
576  * Unpack a string that was previously packed by pack_int_string().
577  */
578 int unpack_int_string(unsigned *data, int ndata, int size, char *string);
579 
580 /*
581  * Unpack a string that was previously packed by pack_int_string() and
582  * then assigned to a parallel array of double.
583  */
584 int unpack_double_string(double *data, int ndata, int size, char *string);
585 
586 #endif
Class for managing coordinate axes.
Definition: CoordAxes.h:25
Tagged: Thu Jun 24 17:38:28 UTC 2004.
A class for specifying a coordinate in a multi-dimensional space.
Definition: Coord.h:21
Tagged: Thu Jun 24 17:19:46 UTC 2004.