//-------------------------------------------------------------------------- // Replacement for sleep // // dwMilliseconds - the number of milliseconds to sleep // void Sleep(long dwMilliseconds) { long limit; // setup the limit limit = msGettick() + dwMilliseconds; // do the delay while (limit >= msGettick()) { // yield this process //??? Yield here does bad things, Yield(); } }
//------------------------------------------------------------------- // Read an array of bytes to the COM port, verify that it was // sent out. Assume that baud rate has been set and the buffers have // been flushed. // // portnum - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // inlen - the length of the data that was read // outbuf - the input data // // Returns number of characters read // int ReadCOM(int portnum, int inlen, uchar *inbuf) { COMSTAT ComStat; short result; ulong m; ulong more; // declare and set the default timeout int timeout = 20 * inlen + 60; //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DODEBUG short i; #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// m = (ulong)msGettick() + (ulong)timeout; do { GetCommError(ComID[portnum],&ComStat); if ((short)ComStat.cbInQue >= inlen) { result = ReadComm(ComID[portnum],inbuf,inlen); if (result == (int)inlen) { GetCommError(ComID[portnum],&ComStat); more = ComStat.cbInQue; //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DODEBUG printf("R["); for (i = 0; i < inlen; i++) printf("%02X ",inbuf[i]); printf("]"); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// return result; } else return FALSE; } //else // yield this process //Yield(); } while ((ulong)msGettick() <= m); return FALSE; }
// ------------------------------------------------------------------------- // SUBROUTINE - ReadWet // // 'temp' - The temperature from the DS1820 in F // 'dir' - The wind direction from 0-15 // 'revol' - The wind speed in revolutions per second // // Returns: TRUE, if the reads were successfull and FALSE if they were not. // int ReadWet(int portnum, WeatherStruct *wet, float *temp, int *dir, double *revol) { int ret = TRUE; unsigned long start_count=0, end_count=0, start_time, end_time; float current_temp; // read the current counter // use this reference to calculate wind speed later if (!ReadCounter(portnum, &wet->ds2423[0], 15, &start_count)) { printf("\nError reading counter, verify device present:%d\n", (int)owVerify(portnum, FALSE)); ret = FALSE; } // get a time stamp (mS) start_time = msGettick(); // read the temperature and print in F if (ReadTemperature(portnum, &wet->ds1820[0],¤t_temp)) *temp = current_temp * 9 / 5 + 32; else { printf("\nError reading temperature, verify device present:%d\n", (int)owVerify(portnum, FALSE)); ret = FALSE; } // read the wind direction *dir = TrueDir(portnum, wet); // read the counter again if (!ReadCounter(portnum, &wet->ds2423[0], 15, &end_count)) { printf("Error reading counter, verify device present:%d\n", (int)owVerify(portnum, FALSE)); ret = FALSE; } // get a time stamp (mS) end_time = msGettick(); // calculate the wind speed based on the revolutions per second *revol = (((end_count - start_count) * 1000.0) / (end_time - start_time)) / 2.0; return ret; }
//-------------------------------------------------------------------------- // Add a page to the hash table. If the page is already in the hash table // it is updated and a new time stamp is given. If the page is new then // it is added to the table. The data in buf is put in the page and the // Space location number is returned. // // portnum the port number of the port being used for the // 1-Wire Network. // SNum the serial number for the part that the read is // to be done on. // pg the page to add // buf the buffer of the page data // len len of data for the page // // return the space number for the new page // uchar AddPage(int portnum, uchar *SNum, PAGE_TYPE pg, uchar *buf, int len) { uchar hs,p=0xFF; short i=0,m; PAGE_TYPE page; int tlen; uchar cache_page[32]; page = pg; // attempt to see if page already there if(!FindPage(portnum,SNum,&page,(uchar)(len & 0x80),FALSE, &cache_page[0],&tlen,&p)) return FALSE; if (p == 0xFF) { // page not found so add one hs = HashFunction(SNum,page); p = FindNew(hs); // attach the device to the chain (if there is one) // no other page in hash location if (Hash[hs] == 0xFF) { Hash[hs] = p; // hash p to new page Space[p].Fptr = 0xFF; // np front p to nothing Space[p].Bptr = 0xFF; // np back p to nothing Space[p].Hptr = hs; // np hash p to hash location } // some other page already there else { // insert as first page Space[p].Fptr = Hash[hs]; // np front p to old first page Space[Hash[hs]].Bptr = p; // old first page back p to np Hash[hs] = p; // hash p to np Space[p].Hptr = hs; // np hash p to hash location } // set the page number Space[p].Page = page; // set the rom for (i = 0; i < 8; i++) Space[p].ROM[i] = SNum[i]; } // set the data Space[p].Data[0] = (uchar)len; m = ((len & 0x1F) <= 0x1D) ? (len & 0x1F) : 0; for (i = 0; i < m; i++) Space[p].Data[i+1] = buf[i]; // set the time stamp limit of X seconds Space[p].Tstamp = msGettick() + CACHE_TIMEOUT; // (3.10) // return the Space number of the new page return p; }
//------------------------------------------------------------------- // Write an array of bytes to the COM port, verify that it was // sent out. Assume that baud rate has been set and the buffers have // been flushed. // // portnum - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // outlen - the length of the data to be written // outbuf - the output data // // Returns TRUE for success and FALSE for failure // int WriteCOM(int portnum, int outlen, uchar *outbuf) { short result; COMSTAT ComStat; ulong m; // declare and set the default timeout int timeout = 20 * outlen + 60; //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DODEBUG short i; printf("W["); for (i = 0; i < outlen; i++) printf("%02X ",outbuf[i]); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// // Send data to write buffer result = WriteComm(ComID[portnum],outbuf,outlen); //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// #ifdef DODEBUG printf("(%d)]",result); #endif //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// // loop to wait for the write to complete if (result == outlen) { m = (ulong)msGettick() + (ulong)timeout; do { // yield this process //Yield(); GetCommError(ComID[portnum],&ComStat); if ((short)ComStat.cbOutQue == 0) return result; } while ((ulong)msGettick() <= m); } else return FALSE; }
//-------------------------------------------------------------------------- // Search the hash cache to find the page discribed by the rom and page. // If it is found and it has not expired, then return its Space number // or 0xFF if it can not be found. 'mflag' is the memory section flag // where 0x00 is normal memory space and 0x80 is status memory space. // // portnum the port number of the port being used for the // 1-Wire Network. // SNum the serial number for the part that the read is // to be done on. // page the page to start looking // mflag the flag to compare in looking for the right page // time the expired time to check // buf the buffer of the page data // len the length of the data on the page // space_num the space number in the table for the data of the page // // return true if the page data was found // SMALLINT FindPage(int portnum, uchar *SNum, PAGE_TYPE *page, uchar mflag, uchar time, uchar *buf, int *len, uchar *space_num) { static uchar DidInit=0; uchar hs,ptr=0xFF; short i=0; ulong tm; // initialize the file page cache (DSS 3.11) automatically if (!DidInit) { InitDHash(); DidInit = 1; } hs = HashFunction(SNum,*page); // if not empty if (Hash[hs] != 0xFF) { // get the current time tm = msGettick(); ptr = Hash[hs]; // point to first at hash spot do { // check to see if this record is expired if (time) { if (tm > Space[ptr].Tstamp) { ptr = FreePage(ptr); continue; // skip to loop check } } // check to see if this page is the correct one (and correct mem space) if ((Space[ptr].Page == *page) && (mflag == (Space[ptr].Data[0] & 0x80))) { for (i = 0; i < 8; i++) if (Space[ptr].ROM[i] != SNum[i]) break; if (i == 8) break; } // point to next page at hash location ptr = Space[ptr].Fptr; } while (ptr != 0xFF); } // check if need to copy over the data if (ptr != 0xFF) { if ((Space[ptr].Data[0] & 0x1F) <= 0x1D) { *len = Space[ptr].Data[0]; for (i = 1; i <= (*len & 0x1F); i++) buf[i-1] = Space[ptr].Data[i]; } else ptr = 0xFF; } // check result if(ptr == 0xFF) return FALSE; *space_num = ptr; return TRUE; }
//-------------------------------------------------------------------------- // Find a empty page in Space and return its pointer. First look at the // expected spot. If an empty or expired page is not found then search // thru the pages. If one cannot be found then void the oldest one. // // hashnum the number of the page that might be empty. // // return the space location // uchar FindNew(uchar hashnum) { ulong tm,otm; static uchar spot = 0; // spot pointer uchar t = 0xFF; uchar oldest,i; uchar freepg; // if current spot is empty then use that if (BitMap[spot] == 0xFF) t = spot; // not empty so first try and find an empty spot in bitmap else { // get the current time tm = msGettick(); // set the oldest time to the current spot otm = Space[spot].Tstamp; oldest = spot; // check to see if spot is void if (tm > Space[spot].Tstamp) { freepg = FreePage(spot); t = spot; } else { // loop through all of the bitmap for (i = 0; i < DEPTH; i++) { if (BitMap[i] == 0xFF) // check for empty { t = i; break; } else if (tm > Space[i].Tstamp) // check for expired { freepg = FreePage((uchar)i); t = i; break; } else if (Space[i].Tstamp < otm) // find oldest { otm = Space[i].Tstamp; oldest = i; } } // check to see if not found one if (i == DEPTH) { // free the current spot freepg = FreePage(oldest); t = oldest; } } } // set next spot to the current spot + 1 spot = (spot == (DEPTH-1)) ? 0 : spot + 1; // set the bitmap to say where the page is going BitMap[t] = hashnum; // return the space location return t; }
//--------------------------------------------------------------------------- // Stop any on-going pulses // // Returns: TRUE - pulse stopped // FALSE - Could not stop pulse // SMALLINT DS2490HaltPulse(usb_dev_handle *hDevice) { STATUS_PACKET status; uchar nResultRegisters; SETUP_PACKET setup; SMALLINT ret; long limit; // set a time limit limit = msGettick() + 300; // loop until confirm pulse has ended or timeout do { // HalExecWhenIdle, Resume Execution to stop an infinite pulse // HalExecWhenIdle setup.RequestTypeReservedBits = 0x40; setup.Request = CONTROL_CMD; setup.Value = CTL_HALT_EXE_IDLE; setup.Index = 0x00; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure break; } // Resume Execution setup.RequestTypeReservedBits = 0x40; setup.Request = CONTROL_CMD; setup.Value = CTL_RESUME_EXE; setup.Index = 0x00; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); if (ret < 0) { // failure break; } // read the status to see if the pulse has been stopped if (!DS2490GetStatus(hDevice, &status, &nResultRegisters)) { // failure break; } else { // check the SPU flag if ((status.StatusFlags & STATUSFLAGS_SPUA) == 0) { // success // disable both pulse types setup.RequestTypeReservedBits = 0x40; setup.Request = MODE_CMD; setup.Value = MOD_PULSE_EN; setup.Index = 0; setup.Length = 0x00; setup.DataOut = FALSE; // call the libusb driver ret = usb_control_msg(hDevice, setup.RequestTypeReservedBits, setup.Request, setup.Value, setup.Index, NULL, setup.Length, TIMEOUT_LIBUSB); return TRUE; } } } while (limit > msGettick()); return FALSE; }
//-------------------------------------------------------------------------- // Check if timelimit number of ms have elapse from the call to MarkTime // // timelimit - the time limit for the elapsed time // // Return TRUE if the time has elapse else FALSE. // SMALLINT ElapsedTime(long timelimit) { // check if time elapsed return ((TimeStamp + timelimit) < msGettick()); }
//-------------------------------------------------------------------------- // Mark time stamp for later comparison // void MarkTime(void) { // get the timestamp TimeStamp = msGettick(); }
//-------------------------------------------------------------------------- // The 'owNext' function does a general search. This function // continues from the previos search state. The search state // can be reset by using the 'owFirst' function. // This function contains one parameter 'alarm_only'. // When 'alarm_only' is TRUE (1) the find alarm command // 0xEC is sent instead of the normal search command 0xF0. // Using the find alarm command 0xEC will limit the search to only // 1-Wire devices that are in an 'alarm' state. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to // indicate the symbolic port number. // 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not // perform reset before search. // 'alarm_only' - TRUE (1) the find alarm command 0xEC is // sent instead of the normal search command 0xF0 // // Returns: TRUE (1) : when a 1-Wire device was found and it's // Serial Number placed in the global SerialNum[portnum] // FALSE (0): when no new device was found. Either the // last search was the last device or there // are no devices on the 1-Wire Net. // SMALLINT owNext(int portnum, SMALLINT do_reset, SMALLINT alarm_only) { SETUP_PACKET setup; short rt=FALSE,i,ResetSearch=FALSE; BYTE rom_buf[16]; BYTE ret_buf[16]; WORD buf_len; uchar lastcrc8; WORD nBytes = 8; ULONG nOutput = 0; long limit; STATUS_PACKET status; BYTE nResult; // if the last call was the last one if (LastDevice[portnum]) { // reset the search LastDiscrepancy[portnum] = 0; LastDevice[portnum] = FALSE; LastFamilyDiscrepancy[portnum] = 0; return FALSE; } // check if reset first is requested if (do_reset) { // reset the 1-wire // extra reset if last part was a DS1994/DS2404 (due to alarm) if ((SerialNum[portnum][0] & 0x7F) == 0x04) owTouchReset(portnum); // if there are no parts on 1-wire, return FALSE if (!owTouchReset(portnum)) { // reset the search LastDiscrepancy[portnum] = 0; LastFamilyDiscrepancy[portnum] = 0; OWERROR(OWERROR_NO_DEVICES_ON_NET); return FALSE; } } // build the rom number to put to the USB chip for (i = 0; i < 8; i++) rom_buf[i] = SerialNum[portnum][i]; // take into account LastDiscrepancy if (LastDiscrepancy[portnum] != 0xFF) { if (LastDiscrepancy[portnum] > 0) bitacc(WRITE_FUNCTION,1,(short)(LastDiscrepancy[portnum] - 1),rom_buf); for (i = LastDiscrepancy[portnum]; i < 64; i++) bitacc(WRITE_FUNCTION,0,i,rom_buf); } // put the ROM ID in EP2 nBytes = 8; if (!DS2490Write(usbhnd[portnum], rom_buf, &nBytes)) { AdapterRecover(portnum); return FALSE; } // setup for search command call setup.RequestTypeReservedBits = 0x40; setup.Request = COMM_CMD; setup.Value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; // the number of devices to read (1) with the search command setup.Index = 0x0100 | (((alarm_only) ? 0xEC : 0xF0) & 0x00FF); setup.Length = 0; setup.DataOut = FALSE; // call the driver if (!DeviceIoControl(usbhnd[portnum], DS2490_IOCTL_VENDOR, &setup, sizeof(SETUP_PACKET), NULL, 0, &nOutput, NULL)) { // failure AdapterRecover(portnum); return FALSE; } // set a time limit limit = msGettick() + 200; // loop to wait on EP3 ready (device will go idle) do { // read the status to see if the pulse has been stopped if (!DS2490GetStatus(usbhnd[portnum], &status, &nResult)) { // failure break; } else { // look for any fail conditions for (i = 0; i < nResult; i++) { // only check for error conditions when the condition is not a ONEWIREDEVICEDETECT if (status.CommResultCodes[i] != ONEWIREDEVICEDETECT) { // failure break; } } } } while (((status.StatusFlags & STATUSFLAGS_IDLE) == 0) && (limit > msGettick())); // check results of the waite for idel if ((status.StatusFlags & STATUSFLAGS_IDLE) == 0) { AdapterRecover(portnum); return FALSE; } // check for data if (status.ReadBufferStatus > 0) { // read the load buf_len = 16; if(!DS2490Read(usbhnd[portnum], ret_buf, &buf_len)) { AdapterRecover(portnum); return FALSE; } // success, get rom and desrepancy LastDevice[portnum] = (buf_len == 8); // extract the ROM (and check crc) setcrc8(portnum,0); for (i = 0; i < 8; i++) { SerialNum[portnum][i] = ret_buf[i]; lastcrc8 = docrc8(portnum,ret_buf[i]); } // crc OK and family code is not 0 if (!lastcrc8 && SerialNum[portnum][0]) { // loop through the descrepancy to get the pointers for (i = 0; i < 64; i++) { // if descrepancy if (bitacc(READ_FUNCTION,0,i,&ret_buf[8]) && (bitacc(READ_FUNCTION,0,i,&ret_buf[0]) == 0)) { LastDiscrepancy[portnum] = i + 1; } } rt = TRUE; } else { ResetSearch = TRUE; rt = FALSE; } } // check if need to reset search if (ResetSearch) { LastDiscrepancy[portnum] = 0xFF; LastDevice[portnum] = FALSE; for (i = 0; i < 8; i++) SerialNum[portnum][i] = 0; } return rt; }