📄 thermo21.c
字号:
//---------------------------------------------------------------------------// 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 stdoutint 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 constantsenum { 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 contantsenum { STATUS_STEP_COMPLETE, STATUS_COMPLETE, STATUS_INPROGRESS, STATUS_ERROR_HALT, STATUS_ERROR_TRANSIENT };// download stepsstatic 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 stepsstatic 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 informationstatic 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 + -