⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thermo21.c

📁 Small Device C Compiler 面向Inter8051
💻 C
📖 第 1 页 / 共 3 页
字号:
//---------------------------------------------------------------------------
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
// 
// Permission is hereby granted, free of charge, to any person obtaining a 
// copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included 
// in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
// MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES 
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
// OTHER DEALINGS IN THE SOFTWARE.
// 
// Except as contained in this notice, the name of Dallas Semiconductor 
// shall not be used except as stated in the Dallas Semiconductor 
// Branding Policy. 
//---------------------------------------------------------------------------
//
//  thermo21.c - Thermochron iButton utility functions 
//
//  Version: 2.00
//    
//    History:
//           1.03 -> 2.00  Reorganization of Public Domain Kit 
//                         Convert to global CRC utility functions
//                         Y2K fix.

#include <stdio.h>
#include "time.h"
#include <string.h>
#include "ownet.h"
#include "thermo21.h"   

// a hack for sdcc/TINI, just printf to stdout
int fprintf (FILE *fp, char *format, ...) reentrant {
  va_list arg;
  *fp; // hush the compiler
  va_start(arg, format);
  vsprintf(NULL, format, arg);
  va_end(arg);
}

FILE * fopen(char * path, char *mode) {
  path, mode; //hush the compiler
  return (FILE *)0;
}

int fclose(FILE *fp) {
  fp; // hust the compiler
  return 0;
}

static int RunThermoScript(int,ThermoStateType *,ThermoScript script[], FILE *fp);
static int ThermoStep(int,ThermoStateType *,ThermoScript *,int *,int *,int *,char *);
static int ReadPages(int,int,int,int *,uchar *);
static int WriteScratch(int,uchar *,int,int);
static int CopyScratch(int,int,int);
static int WriteMemory(int,uchar *, int, int);

// step constants
enum { ST_SETUP=0, ST_READ_STATUS, ST_READ_ALARM, ST_READ_HIST,
       ST_READ_LOG, ST_CLEAR_MEM, ST_CLEAR_VERIFY, ST_WRITE_TIME,
       ST_WRITE_CONTROL, ST_WRITE_RATE, ST_FINISH, ST_GET_SESSION, 
       ST_FIND_THERMO, ST_REL_SESSION, ST_READ_PAGES, ST_WRITE_MEM,
       ST_CLEAR_SETUP };

// status contants
enum { STATUS_STEP_COMPLETE, STATUS_COMPLETE, STATUS_INPROGRESS,
       STATUS_ERROR_HALT, STATUS_ERROR_TRANSIENT };

// download steps
static ThermoScript Download[] = 
    {{ ST_READ_STATUS,  "Setup to read the mission status"},
     { ST_READ_PAGES,   "Read the status page"},
     { ST_READ_ALARM,   "Setup to read alarm pages"},
     { ST_READ_PAGES,   "Read the alarm pages"},
     { ST_READ_HIST,    "Setup to read histogram pages"},
     { ST_READ_PAGES,   "Read the histogram pages"},
     { ST_READ_LOG,     "Setup to read log pages"},
     { ST_READ_PAGES,   "Read the log pages"},
     { ST_FINISH,       "Finished"}}; 

// read status only steps
static ThermoScript GetStatus[] = 
    {{ ST_READ_STATUS,  "Setup to read the mission status"},
     { ST_READ_PAGES,   "Read the status page"},
     { ST_FINISH,       "Finished"}}; 

// mission steps (assume already did StatusThermo)
static ThermoScript Mission[] = 
    {{ ST_CLEAR_SETUP,  "Setup clear memory"},
     { ST_WRITE_MEM,    "Write clear memory bit"},
     { ST_CLEAR_MEM,    "Clear the memory"},
     { ST_READ_STATUS,  "Setup to read the mission status"},
     { ST_READ_PAGES,   "Read the status page"},
     { ST_CLEAR_VERIFY, "Verify memory is clear"},
     { ST_WRITE_TIME,   "Setup to write the real time clock"},
     { ST_WRITE_MEM,    "Write the real time clock"},
     { ST_WRITE_CONTROL,"Setup to write the control"},
     { ST_WRITE_MEM,    "Write the control"},
     { ST_WRITE_RATE,   "Setup to write the sample rate to start mission"},
     { ST_WRITE_MEM,    "Write the sample rate"},
     { ST_READ_STATUS,  "Read the new mission status"},
     { ST_FINISH,       "Finished"}}; 

// global state information
static int current_speed[MAX_PORTNUM];

//--------------------------------------------------------------------------
// The 'DownloadThermo' downloads the specified Thermochron in 'SerialNum'
// and puts the data in the state variable 'ThermoState'.  Progress output
// is printed to the specified file 'fp'. 
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number is provided to
//                 indicate the symbolic port number.
// 'SerialNum'   - Device serial number to download
// 'ThermoState' - pointer to a structure type that holds the raw and
//                 translated Thermochron data.
// 'fp'          - file pointer to print status information to
//
// Returns:   TRUE (1) : Thermochron download with raw data in ThermoState
//            FALSE (0): not downloaded.  Abort due to repeated errors
//                       or user keypress.
//
int DownloadThermo(int portnum, uchar *SerialNum, 
                   ThermoStateType *ThermoState, FILE *fp)
{
   // set the serial num
   owSerialNum(portnum, SerialNum, FALSE);

   // run the script and download thermochron
   return RunThermoScript(portnum,ThermoState,Download,fp);
}

//--------------------------------------------------------------------------
// The 'ReadThermoStatus' reads the Thermochron status in 'SerialNum'
// and puts the data in the state variable 'ThermoState'.  Progress output
// is printed to the specified file 'fp'. 
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number is provided to
//                 indicate the symbolic port number.
// 'SerialNum'   - Device serial number to download
// 'ThermoState' - pointer to a structure type that holds the raw and
//                 translated Thermochron data.
// 'fp'          - file pointer to print status information to
//
// Returns:   TRUE (1) : Thermochron status read with raw data in ThermoState
//            FALSE (0): status not read.  Abort due to repeated errors
//                       or user keypress.
//
int ReadThermoStatus(int portnum, uchar *SerialNum, 
                   ThermoStateType *ThermoState, FILE *fp)
{
   // set the serial num
   owSerialNum(portnum, SerialNum, FALSE);

   // run the script and read status of thermochron
   return RunThermoScript(portnum,ThermoState,GetStatus,fp);
} 

//--------------------------------------------------------------------------
// The 'MissionThermo' starts a new Thermochron mission on 'SerialNum'
// from the state information provided in 'ThermoState'. Progress output
// is printed to the specified file 'fp'. 
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number is provided to
//                 indicate the symbolic port number.
// 'SerialNum'   - Device serial number to download
// 'ThermoState' - pointer to a structure type that holds the raw and
//                 translated Thermochron data.
// 'fp'          - file pointer to print status information to
//
// Returns:   TRUE (1) : Thermochron missioned
//            FALSE (0): not missioned.  Abort due to repeated errors
//                       or user keypress.
//
int MissionThermo(int portnum, uchar *SerialNum, 
                   ThermoStateType *ThermoState, FILE *fp)
{
   // set the serial num
   owSerialNum(portnum, SerialNum, FALSE);

   // run the script and mission thermochron
   return RunThermoScript(portnum,ThermoState,Mission,fp);
}

//--------------------------------------------------------------------------
// Run the specified script.  Return TRUE if all steps completed else FALSE.
// Status is printed to file 'fp'.  
//
int RunThermoScript(int portnum, ThermoStateType *ThermoState,
                    ThermoScript script[], FILE *fp)
{
   char msg[256],LastDescription[256],LastMsg[256];
   int StepCount,SubStep,ErrorCount,Status;
   int last_clear_step=0;
   
   // reset the step to the begining
   StepCount = 0;
   SubStep = 0;
   ErrorCount = 0;
   Status = STATUS_INPROGRESS;
 
   // loop to perform all of the steps to download the Thermochron
   do
   {   
      // switch on the status of the last step done
      switch(Status)
      {
         // step complete so go to the next
         case STATUS_STEP_COMPLETE:
            StepCount++;
            SubStep = 0;
            ErrorCount = 0;
            Status = STATUS_INPROGRESS;
            LastDescription[0] = 0;
            LastMsg[0] = 0;
            break;
         // in progress so call again
         case STATUS_INPROGRESS:
            // record the step position of the last memory clear
            // this is in case we need to attempt a clear again
            if (script[StepCount].Step == ST_CLEAR_SETUP)
               last_clear_step = StepCount;               

            // print step description if different 
            if (strcmp(LastDescription,
                script[StepCount].StepDescription) != 0)
            {
               fprintf(fp,"%s --> ",script[StepCount].StepDescription);
               sprintf(LastDescription,"%s",script[StepCount].StepDescription);
            }

            // perform a step in the job
            ThermoStep(portnum,ThermoState,&script[StepCount],&SubStep, 
                      &Status, &ErrorCount, msg);

            // print results if different
            if (strcmp(LastMsg,msg) != 0)
            {
               fprintf(fp,"%s\n",msg);
               sprintf(LastMsg,"%s",msg);
            }
            else
               fprintf(fp,".");
            break;     
         // encountered a transient error
         case STATUS_ERROR_TRANSIENT:
            // check if transient error is a memory clear
            if (script[StepCount].Step == ST_CLEAR_VERIFY)
            {
               // put back to starting clear over again
               StepCount = last_clear_step;
               SubStep = 0;
               ErrorCount = 0;
               Status = STATUS_INPROGRESS;
               break; 
            }    
            // if 20 tansient errors in a row then abort
            if (ErrorCount > 20)
               Status = STATUS_ERROR_HALT;
            else
               Status = STATUS_INPROGRESS;
            break;
         // all steps complete
         case STATUS_COMPLETE:
            fprintf(fp,"End script normally\n");
            return TRUE;
            break;
         // non-recoverable error
         case STATUS_ERROR_HALT:
            fprintf(fp,"Aborting script due to non-recoverable error\n");
            return FALSE;
            break;
      }
   }
   while (!Serial0CharArrived());
 
   // key abort
   fprintf(fp,"Aborting script due to key press\n");
   return FALSE;
}

//----------------------------------------------------------------------
//  Use the script to perform a step and return.
//
int ThermoStep(int portnum, ThermoStateType *ThermoState, 
               ThermoScript *StateScript, int *SubStep, 
               int *Status, int *ErrorCount, char *msg)
{
   short  rslt;
   static int read_page_num, read_pages, write_addr, write_len;
   static uchar *read_buf, *write_buf;
   static uchar tbuf[5];

   ErrorCount; // hush the compiler

   // do the current step
   switch (StateScript->Step)
   {
      // the operation is complete      
      case ST_FINISH:
         sprintf(msg,"Operation complete");
         *Status = STATUS_COMPLETE;
         break;      

      // read the mission status page
      case ST_READ_STATUS:
         read_page_num = STATUS_PAGE;
         read_pages = 1;
         read_buf = ThermoState->MissStat.status_raw;
         sprintf(msg,"Ready to read status page %d",
                      read_page_num);
         *Status = STATUS_STEP_COMPLETE;
         break;      

      // set up to read the alarm registers
      case ST_READ_ALARM:
         read_page_num = 17;
         read_pages = 3;
         read_buf = ThermoState->AlarmData.alarm_raw;
         sprintf(msg,"Ready to read alarm pages %d to %d",
                      read_page_num, read_page_num + read_pages - 1);
         *Status = STATUS_STEP_COMPLETE;
         break;
         
      // set up to read the histogram data
      case ST_READ_HIST:
         read_page_num = 64;
         read_pages = 4;
         read_buf = ThermoState->HistData.hist_raw;
         sprintf(msg,"Ready to read histogram pages %d to %d",
                      read_page_num, read_page_num + read_pages - 1);
         *Status = STATUS_STEP_COMPLETE;
         break;

      // set up to read the log data
      case ST_READ_LOG:
         read_page_num = 128;
         read_pages = 64;
         read_buf = ThermoState->LogData.log_raw;
         sprintf(msg,"Ready to read log pages %d to %d",
                      read_page_num, read_page_num + read_pages - 1);
         *Status = STATUS_STEP_COMPLETE;
         break;

      // read the specified pages
      case ST_READ_PAGES:
         // check for last page
         if (*SubStep == 0)
            // set the sub-step to the current page being read
            *SubStep =  read_page_num;
         // read the status page
         rslt = ReadPages(portnum, read_page_num, read_pages, SubStep, read_buf);
         if (rslt == FALSE)
         {
            sprintf(msg,"Thermochron not on 1-Wire Net");
            *Status = STATUS_INPROGRESS;
         }
         else 
         {
            sprintf(msg,"Pages read from Thermochron");
            *Status = STATUS_STEP_COMPLETE;
         }
         break;      

      // setup the clear memory
      case ST_CLEAR_SETUP:
         // create a small buff to write to start the clear memory
         tbuf[0] = 0x40;
         write_buf = &tbuf[0];
         write_len = 1;
         write_addr = 0x20E;
         sprintf(msg,"Write to setup clear memory");
         *Status = STATUS_STEP_COMPLETE;
         break;

      // clear the memory
      case ST_CLEAR_MEM:
         // set the clear memory command (not check return because verify)        
         owAccess(portnum);
         owWriteByte(portnum,0x3C);
         msDelay(3);
         owTouchReset(portnum);
         sprintf(msg,"Clear memory command sent");
         *Status = STATUS_STEP_COMPLETE;
         break;

      // clear the memory
      case ST_CLEAR_VERIFY:
         // look at the memory clear bit
         if ((ThermoState->MissStat.status_raw[0x14] & 0x40) == 0x40)
         {
            sprintf(msg,"Memory is clear");
            *Status = STATUS_STEP_COMPLETE;
            break;
         }
         else
         {
            sprintf(msg,"Memory did NOT clear");
            *Status = STATUS_ERROR_TRANSIENT;
            break;
         }
         break;      

      // setup write time, clock alarm, control, trips
      case ST_WRITE_TIME:
         // create the write buffer
         FormatMission(&ThermoState->MissStat);
         write_buf = &ThermoState->MissStat.status_raw[0x00];
         write_len = 13;
         write_addr = 0x200;
         sprintf(msg,"Write time, clock alarm, and trips setup");
         *Status = STATUS_STEP_COMPLETE;
         break;

      // write the control, mission delay and clear flags
      case ST_WRITE_CONTROL:
         write_buf = &ThermoState->MissStat.status_raw[0x0E];
         write_len = 7;
         write_addr = 0x20E;
         sprintf(msg,"Write control, mission delay, clear flags setup");
         *Status = STATUS_STEP_COMPLETE;
         break;

      case ST_WRITE_RATE:
         write_buf = &ThermoState->MissStat.status_raw[0x0D];
         write_len = 1;
         write_addr = 0x20D;
         sprintf(msg,"Write sample rate setup");
         *Status = STATUS_STEP_COMPLETE;
         break;

      // write the specified memory location 
      case ST_WRITE_MEM:
         if (WriteMemory(portnum, write_buf, write_len, write_addr))
         {
            sprintf(msg,"Memory written to Thermochron");
            *Status = STATUS_STEP_COMPLETE;
         }
         else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -