/* Author: Paul Conway Contact Details: PEI Technologies Ltd. Foundation Building National Technological Park Limerick Ireland http://www.ul.ie/~pei Release Date: May 1999. Version: 1.01 Company: Analog Devices */ #include #include "datatype.h" #include "function.h" #include "teds.h" /* This is how the TEDS will be arranged in the Flash Data Area. Note that the flash data area is 640 (0x280) bytes long. It is accessed 4-bytes at a time (4-byte pages). Each address references 4 bytes => the address space is 0x00 - 0xA0. (i.e. 0xA0 x 4 == 0x280 == 640 bytes ) TEDS are written starting from the first field, most significant byte first. _ _ ___ _ |_ 0xA0 _| \ | : \ _ | : / |_ : _ ___ _/ |_ 0x42 _| | | | Ch2 TEDS ( ~96 bytes => ~24 pages => 0x2B-0x42 inclusive) |_ | _|___ |_ 0x2A _| | | | Ch1 TEDS ( ~96 bytes => ~24 pages => 0x13-0x2A inclusive) |_ | _|___ |_ 0x12 _| | | | |_ | _| MetaTEDS ( ~76 bytes => ~19 pages => 0x00->0x12 inclusive) |_ 0x00 _|___ */ // The absolute Start Addresses for the TEDS within the Flash Data area: // -------------------------------------------------------------------- // #define META_TEDS_ADDRESS 0x00 #define CH1_TEDS_ADDRESS 0x13 #define CH2_TEDS_ADDRESS 0x2B // Macros that allow us to manipulate the Flash Data area: // ------------------------------------------------------ // #define READ_BYTEPAGE ECON = 0x01 #define WRITE_BYTEPAGE ECON = 0x02 #define VERIFY_BYTEPAGE ECON = 0x04 #define ERASE_BYTEPAGE ECON = 0x05 #define ERASE_ALL_BYTEPAGES ECON = 0x06 // Setup the TEDS Specific to this Application: // ------------------------------------------- boolean TEDS_SetupMetaTEDS(void) { // Define The Meta-TEDS Contents at Declaration Time // ------------------------------------------------- stMetaTeds idata MetaTEDS = { (U32L)sizeof(stMetaTeds)- sizeof(U32L), // Meta-TEDS length 2, // 1451 Working Grp Num 1, // TEDS Version Num // Universally unique ID: // This UUID represents: 53 deg 30 minutes North, // -------------------- 08 deg 0 minutes West, (i.e. Ireland) // Manufacturers Code: 1, // Year: 1999, // Time: 00:00:00 on May 4th. // 0x97,0x82,0xC0,0x1C,0x20,0x05,0xF3,0xD0,0x59,0x00, 0, // Calib TEDS ext key 0, // NonVolatile Data ext key 0, // Industry TEDS ext key 0, // End User App-Spec ext key NUM_CHANNELS, // Num of implemented chans 2, // Wrst Case Chan Data Model Len 0, // Wrst Case Chan Data Reps 0L, // CH_0 writable TEDS len 0.0025, // Wrst Case Chan Update Time 0.001, // Global Write Setup Time 0.001, // Global Read Setup Time 0.0005, // Wrst Case Chan Samp period 0.0005, // Wrst Case Chan Warmup Time 0.5, // Command Response Time 0.0003, // STIM handshake Time 0.04, // EOF Detection Latency 0.03, // TEDS hold off Time 0.03, // Operational hold off Time 2000000, // Max Data Rate 0, // Chan Grp Data Sub-Block // // There are no Channel Groupings Sub-Blocks // => no iterations for fields 25-28 exist. // 0 // Checksum for this Meta-TEDS }; // The TEDS Data area must be programmed one byte at a time. // Therefore, we need to access the TEDS structure as a byte array. // unsigned char *pTEDSByteArray = &MetaTEDS; // Calculate the Checksum for the Meta-TEDS, and fill it into the // Meta-TEDS data structure. // MetaTEDS.Checksum = DAT_CalcChecksum(pTEDSByteArray); // Now program the Meta-TEDS structure into the TEDS Flash data area. // return TEDS_WriteTEDSToFlash( META_TEDS_ADDRESS, pTEDSByteArray, MetaTEDS.Length+sizeof(U32L) ); } boolean TEDS_SetupCh1TEDS(void) { // Define The Channel 1 TEDS Contents at Declaration Time // ------------------------------------------------------ // // Channel 1: Sensor - AD590 // stChannelTeds idata Ch1TEDS = { (U32L)sizeof(stChannelTeds)- sizeof(U32L), // Channel-TEDS length CAL_NONE, // Calibration Key 0, // Calib TEDS ext key 0, // NonVolatile Data ext key 0, // Industry TEDS ext key 0, // End User App-Spec ext key 0L, // Writable TEDS length SENSOR, // Channel Type Key // Physical Units: 0x04,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 1788.0, // Lower Limit: in ADC counts 3468.0, // Upper Limit: in ADC counts 12.2955, // Worst Case Uncertainty 0, // Self Test Key 0, // Channel Data Model CH1_DATA_MODEL_LENGTH, // Chan Data Model Length 12, // Chan Model Sig Bits 0, // Chan Data Reps 0.0, // Series Origin 0.0, // Series Increment 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Series Units 0.0025, // Chan Update Time 0.001, // Chan Write Setup Time 0.001, // Chan Read Setup Time 0.005, // Chan Samp Period 0.005, // Chan Warmup Time 0.5, // Chan Agg Hold Off Time 1.0, // Timing Correction 0.5, // Trigger Accuracy 0, // Event Sequence Options 0 // Checksum for this Chan-TEDS }; // The TEDS Data area must be programmed one byte at a time. // Therefore, we need to access the TEDS structure as a byte array. // unsigned char *pTEDSByteArray = &Ch1TEDS; // Calculate the Checksum for the Channel 1 TEDS, and fill it into // the Ch1TEDS data structure. // Ch1TEDS.Checksum = DAT_CalcChecksum(pTEDSByteArray); // Now program the Meta-TEDS structure into the TEDS Flash data area. // return TEDS_WriteTEDSToFlash( CH1_TEDS_ADDRESS, pTEDSByteArray, Ch1TEDS.Length+sizeof(U32L) ); } boolean TEDS_SetupCh2TEDS(void) { // Define The Channel 2 TEDS Contents at Declaration Time // ------------------------------------------------------ // // Channel 2: Actuator - Fan // stChannelTeds idata Ch2TEDS = { (U32L)sizeof(stChannelTeds)- sizeof(U32L), // Channel-TEDS length CAL_NONE, // Calibration Key 0, // Calib TEDS ext key 0, // NonVolatile Data ext key 0, // Industry TEDS ext key 0, // End User App-Spec ext key 0L, // Writable TEDS length ACTUATOR, // Channel Type Key // Physical Units: 0x04,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0.0, // Lower Range Limit 255.0, // Upper Range Limit 0.0, // Worst Case Uncertainty 0, // Self Test Key 0, // Channel Data Model CH2_DATA_MODEL_LENGTH, // Chan Data Model Length 1, // Chan Model Sig Bits 0, // Chan Data Reps 0.0, // Series Origin 0.0, // Series Increment 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Series Units 0.0025, // Chan Update Time 0.001, // Chan Write Setup Time 0.001, // Chan Read Setup Time 0.005, // Chan Samp Period 0.005, // Chan Warmup Time 0.5, // Chan Agg Hold Off Time 1.0, // Timing Correction 0.5, // Trigger Accuracy 0, // Event Sequence Options 0 // Checksum for this Chan-TEDS }; // The TEDS Data area must be programmed one byte at a time. // Therefore, we need to access the TEDS structure as a byte array. // unsigned char *pTEDSByteArray = &Ch2TEDS; // Calculate the Checksum for the Channel 1 TEDS, and fill it into // the Ch2TEDS data structure. // Ch2TEDS.Checksum = DAT_CalcChecksum(pTEDSByteArray); // Now program the Meta-TEDS structure into the TEDS Flash data area. // return TEDS_WriteTEDSToFlash( CH2_TEDS_ADDRESS, pTEDSByteArray, Ch2TEDS.Length+sizeof(U32L) ); } // Storing and Retrieving TEDS to/from the Data Flash: // -------------------------------------------------- boolean TEDS_WriteTEDSToFlash( unsigned char ucStartAddress, unsigned char* pTEDSArray, U32L BytesToWrite) { U32L Count=0; boolean bRet=TRUE; // Setup the start address for writing to the Data Flash // EADRL = ucStartAddress; // Write all bytes (4-byte pages at a time) into the data flash // while(Count < (BytesToWrite-1)) { EDATA1 = *(pTEDSArray+Count); EDATA2 = *(pTEDSArray+Count+1); EDATA3 = *(pTEDSArray+Count+2); EDATA4 = *(pTEDSArray+Count+3); // Write the 4 bytes just setup... // WRITE_BYTEPAGE; // ...verify them. If they don't verify, exit false now. // VERIFY_BYTEPAGE; if(ECON != 0x00) { bRet = FALSE; break; } // Incement the 'start address' in flash for writing the next 4-bytes, // and increment the count pointer to the start of the next byte in // memory. // EADRL += 1; Count += 4; } return bRet; } boolean TEDS_ReadTEDSfromFlash( unsigned char ucStartAddress, unsigned char* pTEDSArray ) { U32L Count=0, BytesToRead=0; boolean bRet=TRUE; union { U32L TEDSLength; unsigned char Array[4]; }FourBytes; // Setup the start address for reading from the Data Flash // EADRL = ucStartAddress; // Read the first 4-bytes from the TEDS specified: // READ_BYTEPAGE; FourBytes.Array[0] = EDATA1; FourBytes.Array[1] = EDATA2; FourBytes.Array[2] = EDATA3; FourBytes.Array[3] = EDATA4; BytesToRead = FourBytes.TEDSLength + sizeof(U32L); // Read all bytes, 4-bytes pages at a time, into the buffer provided // while(Count < (BytesToRead-1)) { READ_BYTEPAGE; *(pTEDSArray+Count) = EDATA1; *(pTEDSArray+Count+1) = EDATA2; *(pTEDSArray+Count+2) = EDATA3; *(pTEDSArray+Count+3) = EDATA4; // Incement the 'start address' in flash for reading the next 4-bytes, // and increment the count pointer to the start of the next byte in // buffer memory. // EADRL += 1; Count += 4; } return bRet; } boolean TEDS_InitTEDSFlash(void) { // Erase the FLASH memory area. // ERASE_ALL_BYTEPAGES; // If the flash was erased, all bytes it should be 0xFF. // Pick one at random and verify that it is. // READ_BYTEPAGE; if(EDATA3 == 0xFF) return TRUE; else return FALSE; } // Read the information for a TEDS from the data flash into a buffer in // RAM. The supplied data buffer must be big enough to hold the TEDS data. // boolean TEDS_GetTEDSHandle( unsigned char ucTEDS, unsigned char ucChan, unsigned char *pTEDSBuffer ) { unsigned char ucTEDSAddress; boolean bRet=TRUE; switch(ucTEDS) { case(TEDS_META): ucTEDSAddress = META_TEDS_ADDRESS; break; case(TEDS_CHANNEL): if (ucChan==1) ucTEDSAddress = CH1_TEDS_ADDRESS; else if(ucChan==2) ucTEDSAddress = CH2_TEDS_ADDRESS; // // All other implemented channels should go in here. // else bRet = FALSE; break; // There are no other TEDS implemented, so return FALSE if // they have been requested... // case(TEDS_CHANNEL_ID): case(TEDS_META_ID): case(TEDS_CALIBRATION): case(TEDS_CALIB_ID): case(TEDS_END_USER): default: bRet = FALSE; break; } if(bRet) TEDS_ReadTEDSfromFlash(ucTEDSAddress, pTEDSBuffer); return bRet; }