file: hrhflash.html
09 Apr 2002

FLASH CARD INTERNAL FORMAT - HRH

The following describes the data storage format of the 8MB Intel-Compatible FLASH memory card used in ASIMET instrumentation.

Major Divisions by card address:

Address Range      Description

000000h - 0000FFh reserved system area (256 bytes) 000100h - 0004FFh EEPROM image backup (1024 bytes) (see EEPROM data structure below) 000500h - 01FFFFh reserved (129792 bytes) 020000h - 3FFFFFh data records (8257536 bytes) total capacity: 16128 records (1 hour each) (see HRH_record data structure below)

Description of HRH data storage area beginning at 20000h

The HRH data storage area consumes most of the 8MB FLASH card. Each record is 512 bytes long, containing the date and time written, 60 minutes of IEEE single-precision relative humidity data, 60 minutes of IEEE single-precision temperature data, a flag which is set to 0xA5A5 when the record is written, and a 2 byte CRC of the previous 510 bytes. The actual C language struct is reproduced here to show the format of the stored image.

   /* this is the HRH data record structure, 512 bytes */
   struct HRH_record
     {
     struct time_type time1;  /* 8 bytes of time */
     float rh_cal[60];       /* 60 minutes of RH% data */
     float tmp_cal[60];      /* 60 minutes of TMP data */
     unsigned char unused[20];
     unsigned short used;   /* set to 0xA5A5 upon record write */
     unsigned short hrh_CRC;  /* CRC of previous 510 bytes */
     };

struct time_type { unsigned char hour; unsigned char min; unsigned char sec; unsigned char day; unsigned char dow; /* day of week - NOT USED */ unsigned char mon; unsigned int year; };

Note that time structure is NOT ANSI-compatible.

The offsets and sizes of the record components is shown below. Remember that the first HRH record is stored at offset 20000h in the FLASH card.

   byte #  size    name          comment
     0      8       time        8 bytes of time
     8      4       rh_cal[0]   minute 0 RH% data
    12      4       rh_cal[1]   minute 1 RH% data
      .
      .
      .
   240      4       rh_cal[58]   minute 58 RH% data
   244      4       rh_cal[59]   minute 59 RH% data
   248      4       tmp_cal[0]   minute 0 temperature data
   252      4       tmp_cal[1]   minute 1 temperature data
      .
      .
      .
   480      4       tmp_cal[58]   minute 58 temperature data
   484      4       tmp_cal[59]   minute 59 temperature data
   488     20       reserved
   508      2       used flag set to A5A5h when record is written
   510      2       hrh_CRC      CRC of previous 510 bytes

Data is written to the FLASH card immediately following the acquisition of data at the rollover to the 59th minute of each hour. This is reflected in the time stamp on each record, typically 1 second into minute 59.


*** IMPORTANT NOTE ***

The byte order of the some numeric values stored by the VOSHRH53 firmware is reversed relative to Intel-based PC's. That is, a long integer (4 bytes) or short integer (2 bytes) stored by a PC will be LS byte first in memory. The VOSHRH53 firmware stores MS byte first in memory. This must be accounted for when processing the data.

Note that single precision IEEE float values are little-endian, and thus compatible with Intel-based PC's. See the float storage format below.


The "used" flag value is used to simplify finding the end of valid records in the FLASH card on module startup. The FLASH card is cleared to all FFh before deploying the module; as each record is written, the "used" flag is set to A5A5h to provide a distinct pattern to search on for good records.

The CRC is NOT IMPLEMENTED.

Description of EEPROM image storage area

The EEPROM image area contains miscellaneous text information about the VOS module, as well as any calibration constants required by the module. The actual C language struct is reproduced here to show the format of the stored image.

      struct ee_page0_type
         {
         char spare[8];       /* */
         char modmfg[16];     /* module manufacturer */
         char modmod[16];     /* model number */
         char modser[8];      /* serial number */
         char moddat[8];      /* manufacture date */
         char senmfg[16];     /* sensor manufacturer */
         char senmod[16];     /* model number */
         char senser[8];      /* serial number */
         char sendat[8];      /* manufacture date */
         char sftmfg[16];     /* program origin */
         char sftnam[16];     /* program name */
         char sftrev[8];      /* serial number */
         char sftdat[8];      /* revision date */
         char sftpce[8];      /* not used */
         char calfac[16];     /* calibration facility */
         char calper[16];     /* calibration technician */
         char caldat[8];      /* calibration date */
         char modadr[8];      /* module address (bytes 200-207) */
         char mode[8];        /* comms mode: 232 or 485 - NOT USED */
         char spare2[40];
         char datfrm[64];     /* cal data format */
         char datdes[64];     /* cal data description */
         char datuni[64];     /* cal data units */
         char spare3[64];
         char rawfrm[64];     /* raw data format */
         char rawdes[64];     /* raw data description */
         char rawuni[64];     /* raw data units */
         char spare4[64];
         float calset[8][5];  /* array of 8 sets of 5 cal terms */
         };

The HRH module uses the first 4 terms of cal constant sets 0 and 1 (for RH and temp), i.e. calset[0][0] is the offset term A1, and calset[0][1] is the gain value B1, calset[0][2] and calset[0][3] are C1 and D1. The cal equation used is:

      y = A1 + (B1 * x) + (C1 * x * x) + (D1 * x * x * x)

The 2 dimensional array of calibration terms is the standard format for all VOS instruments, regardless of how many sets of terms are required.


"float" 4 byte values are IEEE-754 single-precision float.

Storage format for these float values is as follows:

      byte addr      +0         +1           +2         +3
      contents     MMMMMMMM   MMMMMMMM    EMMMMMMM    SEEEEEEE

            where S => Sign bit;  1 = negative,  0 = positive
                  E => Exponent (2's comp) with offset 127 (decimal)
                  M => 23-bit normal mantissa (highest bit always 1 and
                           therefore not stored)