예제 #1
0
파일: temp.c 프로젝트: JJ5high/program_jing
int Temp_DoRead(int iSensor)
{
	uchar send_block[30], lastcrc8;
	int send_cnt, tsht = 0, i, loop = 0;
//	LED_Set(6);
	if(iSensor >= NumDevices)
		return 0;
//	LED_Set(7);
	owSerialNum(PORTNUM, TempSensorSN[iSensor], FALSE);

	for (loop = 0; loop < 2; loop++) {
		// access the device
		if (owAccess(PORTNUM)) {
			// send the convert command and if nesessary start power delivery
			if (!owWriteByte(PORTNUM, 0x44))
					return 0;

			// access the device
			if (owAccess(PORTNUM)) {
				// create a block to send that reads the temperature
				// read scratchpad command
				send_cnt = 0;
				send_block[send_cnt++] = 0xBE;
				// now add the read bytes for data bytes and crc8
				for (i = 0; i < 9; i++)
					send_block[send_cnt++] = 0xFF;

				// now send the block
				if (owBlock(PORTNUM, FALSE, send_block, send_cnt)) {
					// initialize the CRC8
					setcrc8(PORTNUM, 0);
					// perform the CRC8 on the last 8 bytes of packet
					for (i = send_cnt - 9; i < send_cnt; i++)
						lastcrc8 = docrc8(PORTNUM, send_block[i]);

					// verify CRC8 is correct
					if (lastcrc8 == 0x00) {
						// calculate the high-res temperature
						tsht = send_block[2] << 8;
						tsht = tsht | send_block[1];
						if (tsht & 0x00001000)
							tsht = tsht | 0xffff0000;
						if(!(tsht == 1360 && LastTemperature[iSensor] == 0)){
							LastTemperature[iSensor] = tsht;
						}else{
							tsht = 0;
						}
						// success
						break;
					}
				}
			}
		}
	}
	return tsht;
}
예제 #2
0
/* -----------------------------------------------------------------------
   ----------------------------------------------------------------------- */
int get_ibl_type(int portnum, uchar page, int offset)
{
   uchar send_block[50];
   int send_cnt=0;
   int i;
   ushort lastcrc8=255;

   /* 01/08/2004 [bcl] DigiTemp does this before calling the function
    * owSerialNum(portnum,SNum,FALSE);
    */

   // Recall the Status/Configuration page
   // Recall command
   send_block[send_cnt++] = 0xB8;

   // Page to Recall
   send_block[send_cnt++] = page;

   if(!owBlock(portnum,FALSE,send_block,send_cnt))
      return FALSE;

   send_cnt = 0;

   if(owAccess(portnum))
   {
      // Read the Status/Configuration byte
      // Read scratchpad command
      send_block[send_cnt++] = 0xBE;

      // Page for the Status/Configuration byte
      send_block[send_cnt++] = page;

      for(i=0;i<9;i++)
         send_block[send_cnt++] = 0xFF;

      if(owBlock(portnum,FALSE,send_block,send_cnt))
      {
         setcrc8(portnum,0);

         for(i=2;i<send_cnt;i++)
            lastcrc8 = docrc8(portnum,send_block[i]);

         if(lastcrc8 != 0x00)
            return FALSE;
      } else {
         return FALSE;
      }

      // Return the requested byte
      return send_block[2+offset];
   }//Access

   return -1;
}
예제 #3
0
/*
  ds2338mem_rd

  Reading DS2438 memory

  returns one page of memory

  input parameters 
  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.
  pageno   the page number of memory to be read
 
 */
int 
ds2438mem_rd(int portnum, uchar *SNum, uchar *pagemem, uchar pageno, char *device) {
   int block_cnt;
   int i;
   ushort lastcrc8;

   owSerialNum(portnum,SNum,FALSE);

   block_cnt = 0;

   // Recall the Status/Configuration page
   // Recall command
   pagemem[block_cnt++] = 0xB8;
   // Page to Recall
   pagemem[block_cnt++] = pageno;
   owAccess(portnum);
   owBlock(portnum,FALSE,pagemem,block_cnt);     
   syslog(LOG_DEBUG, "ds2438mem_rd: recall memory (B8h %xh): %s\n", 
     pageno, ppagemem(pagemem));
   block_cnt = 0;
   // Read the Status/Configuration byte
   // Read scratchpad command
   pagemem[block_cnt++] = 0xBE;
   // Page for the Status/Configuration byte
   pagemem[block_cnt++] = pageno;
   for(i=0;i<9;i++)
     pagemem[block_cnt++] = 0xFF;
   owAccess(portnum);
   owBlock(portnum,FALSE,pagemem,block_cnt);     
   syslog(LOG_DEBUG,"ds2438mem_rd: read scratchpad (BEh %xh): %s \n", 
       pageno, ppagemem( pagemem));

   setcrc8(portnum,0);
   for(i=2;i<block_cnt;i++) {
     lastcrc8 = docrc8(portnum,pagemem[i]);
   }
   if(lastcrc8 != 0x00) {
     syslog(LOG_ALERT, "ds2438mem_rd: CRC error ");
     bitprint( lastcrc8, "lastcrc8");
     return 1;
   }

   return 0;
}
예제 #4
0
//----------------------------------------------------------------------
// Read the temperature of a DS1920/DS1820
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number was provided to
//                 OpenCOM to indicate the port number.
// 'SerialNum'   - Serial Number of DS1920/DS1820 to read temperature from
// 'Temp '       - pointer to variable where that temperature will be 
//                 returned
//
// Returns: TRUE(1)  temperature has been read and verified
//          FALSE(0) could not read the temperature, perhaps device is not
//                   in contact
//
int ReadTemperature(int portnum, uchar *SerialNum, float *Temp)
{
   int rt=FALSE;
   uchar send_block[30],lastcrc8;
   int send_cnt=0, tsht, i, loop=0;
   float tmp,cr,cpc;
   
   
   setcrc8(portnum,0);

   // set the device serial number to the counter device
   owSerialNum(portnum,SerialNum,FALSE);

   for (loop = 0; rt==FALSE && loop < 2; loop ++)
   {
      // access the device 
      if (owAccess(portnum))
      {
         // send the convert temperature command
         owTouchByte(portnum,0x44);

         // set the 1-Wire Net to strong pull-up
         if (owLevel(portnum,MODE_STRONG5) != MODE_STRONG5)
            return FALSE;
 
         // sleep for 1 second
         msDelay(1000);

         // turn off the 1-Wire Net strong pull-up
         if (owLevel(portnum,MODE_NORMAL) != MODE_NORMAL)
            return FALSE;

         // access the device 
         if (owAccess(portnum))
         {
            // create a block to send that reads the temperature
            // read scratchpad command
            send_block[send_cnt++] = 0xBE;
            // now add the read bytes for data bytes and crc8
            for (i = 0; i < 9; i++)
               send_block[send_cnt++] = 0xFF;

            // now send the block
            if (owBlock(portnum,FALSE,send_block,send_cnt))
            {
               // perform the CRC8 on the last 8 bytes of packet
               for (i = send_cnt - 9; i < send_cnt; i++)
                  lastcrc8 = docrc8(portnum,send_block[i]);

               // verify CRC8 is correct
               if (lastcrc8 == 0x00)
               {
                  // calculate the high-res temperature
                  tsht = send_block[1]/2;
                  if (send_block[2] & 0x01)
                     tsht |= -128;
                  tmp = (float)(tsht);
                  cr = send_block[7];
                  cpc = send_block[8];
                  if (((cpc - cr) == 1) && (loop == 0))
                     continue;
                  if (cpc == 0)
                     return FALSE;   
                  else
                     tmp = tmp - (float)0.25 + (cpc - cr)/cpc;
   
                  *Temp = tmp;
                  // success
                  rt = TRUE;
               }
            }
         }
      }
        
   }
   
 // return the result flag rt
      return rt;
      
}
//--------------------------------------------------------------------------
//! Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
//! search state.
//! @return TRUE  : device found, ROM number in ROM_NO buffer
//!         FALSE : device not found, end of search
//
int OWSearch()
{
   int id_bit_number;
   int last_zero, rom_byte_number, search_result;
   int id_bit, cmp_id_bit;
   uchar rom_byte_mask, search_direction;

   // initialize for search
   id_bit_number = 1;
   last_zero = 0;
   rom_byte_number = 0;
   rom_byte_mask = 1;
   search_result = 0;
   crc8 = 0;

   // if the last call was not the last one
   if (!LastDeviceFlag)
   {
      // 1-Wire reset
      if (!OWReset())
      {
         // reset the search
         LastDiscrepancy = 0;
         LastDeviceFlag = FALSE;
         LastFamilyDiscrepancy = 0;
         return FALSE;
      }
      // issue the search command
      OWWriteByte(0xF0);


      // loop to do the search
      do
      {
         // read a bit and its complement
          id_bit = OWReadBit();
          cmp_id_bit = OWReadBit();



         // check for no devices on 1-wire
         if ((id_bit == 1) && (cmp_id_bit == 1))
            break;
         else
         {
            // all devices coupled have 0 or 1
            if (id_bit != cmp_id_bit)
               search_direction = id_bit;  // bit write value for search
            else
            {
               // if this discrepancy if before the Last Discrepancy
               // on a previous next then pick the same as last time
               if (id_bit_number < LastDiscrepancy)
                  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
               else
                  // if equal to last pick 1, if not then pick 0
                  if (id_bit_number == LastDiscrepancy)
                      search_direction = 1;
                  else
                      search_direction = 0;

               // if 0 was picked then record its position in LastZero
               if (search_direction == 0)
               {
                  last_zero = id_bit_number;

                  // check for Last discrepancy in family
                  if (last_zero < 9)
                     LastFamilyDiscrepancy = last_zero;
               }
            }

            // set or clear the bit in the ROM byte rom_byte_number
            // with mask rom_byte_mask
            if (search_direction == 1)
              ROM_NO[rom_byte_number] |= rom_byte_mask;
            else
              ROM_NO[rom_byte_number] &= ~rom_byte_mask;

            // serial number search direction write bit
            OWWriteBit(search_direction);

            // increment the byte counter id_bit_number
            // and shift the mask rom_byte_mask
            id_bit_number++;
            rom_byte_mask <<= 1;

            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
            if (rom_byte_mask == 0)
            {
                docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRC
                rom_byte_number++;
                rom_byte_mask = 1;
            }
         }
      }
      while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7

      // if the search was successful then
      if (!((id_bit_number < 65) || (crc8 != 0)))
      {
         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
         LastDiscrepancy = last_zero;

         // check for last device
         if (LastDiscrepancy == 0)
            LastDeviceFlag = TRUE;

         search_result = TRUE;
      }
   }

   // if no device found then reset counters so next 'search' will be like a first
   if (!search_result || !ROM_NO[0])
   {
      LastDiscrepancy = 0;
      LastDeviceFlag = FALSE;
      LastFamilyDiscrepancy = 0;
      search_result = FALSE;
   }

   return search_result;
}
예제 #6
0
/*

  SetupVsens

  setup DS2438 to read Vsens voltage difference

  enable IAD, CA and EE of status configuration register ( page <0h> byte <0h>)

  Vsens A/D conversion occurs with a frequency of 36.41 measurements/sec
  once IAD is enabled ( set to '1'). No special command necessary.
 
  input parameters
    portnum    port number
    SNum       serial number of DS2438
    device     device (USB DS2490 or serial DS9097U)

*/
int SetupVsens(int portnum, uchar *SNum, char *device)
{
   uchar datablock[50];
   uchar conf_reg = 0x00;
   int send_cnt = 0;
   int i;
   ushort lastcrc8;
   int busybyte;
   double ti, tf;
   struct timezone tz;
   struct timeval  tv; 

   gettimeofday( &tv, &tz);
   ti = tv.tv_sec+1.0e-6*tv.tv_usec;

   /* enable IAD, CA and EE of configuration byte */
   conf_reg |= IAD | CA | EE;

   owSerialNum(portnum,SNum,FALSE);
   // Recall the Status/Configuration page
   // Recall command
   datablock[send_cnt++] = 0xB8;

   // Page to Recall
   datablock[send_cnt++] = 0x00;

   if(!owBlock(portnum,FALSE,datablock,send_cnt))
      return FALSE;

   send_cnt = 0;

   
   if(owAccess(portnum))
   {
      // Read the Status/Configuration byte
      // Read scratchpad command
      datablock[send_cnt++] = 0xBE;

      // Page for the Status/Configuration byte
      datablock[send_cnt++] = 0x00;

      for(i=0;i<9;i++)
         datablock[send_cnt++] = 0xFF;

      if(owBlock(portnum,FALSE,datablock,send_cnt))
      {
         setcrc8(portnum,0);

         for(i=2;i<send_cnt;i++)
            lastcrc8 = docrc8(portnum,datablock[i]);

         if(lastcrc8 != 0x00)
            return FALSE;
      }//Block
      else
         return FALSE;

      if ( datablock[2] & conf_reg ) {
        syslog(LOG_DEBUG, "SetupVsens: IAD, CA and EE are set: return!\n");

	gettimeofday( &tv, &tz);
	tf = tv.tv_sec+1.0e-6*tv.tv_usec;
        syslog(LOG_DEBUG,
	       "SetupVsens: elapsed time: %f\n", tf -ti);

        return TRUE;
      } else {
	  syslog(LOG_DEBUG,
		 "SetupVsens: IAD, CA and EE are not set. Continue to setup\n");
      }

   }//Access

   if(owAccess(portnum))
   {
      send_cnt = 0;
      // Write the Status/Configuration byte
      // Write scratchpad command
      datablock[send_cnt++] = 0x4E;

      // Write page
      datablock[send_cnt++] = 0x00;

      // IAD, CA and EE set to "1"
      datablock[send_cnt++] |= conf_reg;

      // do not change the rest
      for(i=0;i<7;i++)
         datablock[send_cnt++] = datablock[i+3];

      if(owBlock(portnum,FALSE,datablock,send_cnt))
      {
         send_cnt = 0;

         if(owAccess(portnum))
         {
            // Copy the Status/Configuration byte
            // Copy scratchpad command
            datablock[send_cnt++] = 0x48;

            // Copy page
            datablock[send_cnt++] = 0x00;

            if(owBlock(portnum,FALSE,datablock,send_cnt))
            {
               busybyte = owReadByte(portnum);
         
               while(busybyte == 0)
                  busybyte = owReadByte(portnum);

	       gettimeofday( &tv, &tz);
	       tf = tv.tv_sec+1.0e-6*tv.tv_usec;
               syslog(LOG_DEBUG,
		      "SetupVsens: elapsed time: %f\n", tf -ti);
               return TRUE;
            }//Block
         }//Access
      }//Block

   }//Access

   return FALSE;
}
예제 #7
0
//----------------------------------------------------------------------
//  Family 0x10 Demo
//
void main(void)
{
  int   temp;
  int   sign;
  BYTE  i;

  //----------------------------------------
  ADCON1      = 0x07;     // PortB digital

  bTRD6       = 1;        // RD6 = Serial Input
  bTRD7       = 0;        // RD7 = Serial Output
  bLD7        = 1;

  printf("\nFamily 0x10 Demo\n%");

////////////////////////////////////////////////////////////
// Initialise the OneWire network (bus)
  // attempt to acquire the 1-Wire Nets
  if (!owAcquire(0, NULL)) {
    printf("Acquire failed.\n%");
    while(1)
      ;
  }
  
////////////////////////////////////////////////////////////
// Let's set the alarmtemps of all devices on the bus.
// To demonstrate this, we write a low alarmtemp of 19
// and a high alarmtemp of 21 to all devices.
// Finally we copy the alarmtemps to non-volatile EEPROM.
  printf("\nStart - Set AlarmTemperatures.\n%");
  // Reset the devices
  owTouchReset(0);
  // Address all devices on the net
  owWriteByte(0, OW_SKIPROM);
  // Use the WriteScratchpad command to set AlarmTemps
  owWriteByte(0, OW_WRITESCRATCHPAD);
  owWriteByte(0, 19);  // Valid RoomTemperature
  owWriteByte(0, 21);  //   19 <= Temp < 21
  printf("End   - Set AlarmTemperatures.\n%");
  // Set alarmtemps done
    
  // Copy the temps to EEPROM
  printf("\nStart - Write AlarmTemperatures to EEPROM.\n%");
  // Reset the devices
  owTouchReset(0);
  // Address all devices on the net
  owWriteByte(0, OW_SKIPROM);
  // send the CopyScratchpad command to copy the AlarmTemps to EEPROM
  // If the bus supports Strong PullUp, we use it (because
  // there might be parasite powered devices on this bus).
  if(owHasPowerDelivery(0)) {
    printf("The bus has a Strong PullUp\n%");
    owWriteBytePower(0, OW_COPYSCRATCHPAD);
    // Eeprom update takes 10 milliseconds max. 11ms is safer
    Wait(11);
    // turn off the strong pull-up
    owLevel(0, MODE_NORMAL);
  } else {
    printf("The bus has NO Strong PullUp\n%");
    owWriteByte(0, OW_COPYSCRATCHPAD);
    // Eeprom update takes 10 milliseconds max. 11ms is safer
    Wait(11);
  }
  printf("End   - Write AlarmTemperatures to EEPROM.\n%");
  // Copy the temps to EEPROM done
  
  while(1) {
////////////////////////////////////////////////////////////
    // We do a temp conversion on all DS18S20's
    printf("\nStart - TemperatureConversions\n%");
    // Reset the devices
    owTouchReset(0);
    // Address all devices on this net
    owWriteByte(0, OW_SKIPROM);
    // Send the convert command and start power delivery if available.
    // Note that we use a different way here to determine
    // Strong PullUp capability.
    if(owWriteBytePower(0, OW_CONVERTT)) {
      printf("We are using a Strong PullUp.\n%");
    } else {
      printf("No Strong PullUp configured.\n%");
      owWriteByte(0, OW_CONVERTT);
    }

    // Coversion takes 750 milliseconds max. 751ms is safer
    Wait(751);
    // turn off the 1-Wire Net strong pull-up
    owLevel(0, MODE_NORMAL);
    printf("End - TemperatureConversions\n%");

////////////////////////////////////////////////////////////
    // We will now demonstrate an alarmsearch
    printf("\nStart - Find devices in alarmstate\n%");
    // Find the devices with temp < 19 or temp >= 21
    if(!owFirst(0, TRUE, TRUE)) {
      printf("No devices in AlarmState found.\n%");
    } else {
      do {
        printf("Device in AlarmState found: 0x%02X%02X%02X%02X%02X%02X%02X%02X\n%",
               owNetCurrent.SerialNum[7],
               owNetCurrent.SerialNum[6],
               owNetCurrent.SerialNum[5],
               owNetCurrent.SerialNum[4],
               owNetCurrent.SerialNum[3],
               owNetCurrent.SerialNum[2],
               owNetCurrent.SerialNum[1],
               owNetCurrent.SerialNum[0]);
      } while(owNext(0, TRUE, TRUE));
    }
    printf("End   - Find devices in alarmstate\n%");

////////////////////////////////////////////////////////////
    // We will now demonstrate a normal search. For
    // every device found, it's temperature is retrieved.
    printf("\nStart - Find devices and get their temperatures.\n%");
    if(!owFirst(0, TRUE, FALSE)) {
      printf("No devices found.\n%");
    } else {
      do {
        printf("Device found: 0x%02X%02X%02X%02X%02X%02X%02X%02X%",
               owNetCurrent.SerialNum[7],
               owNetCurrent.SerialNum[6],
               owNetCurrent.SerialNum[5],
               owNetCurrent.SerialNum[4],
               owNetCurrent.SerialNum[3],
               owNetCurrent.SerialNum[2],
               owNetCurrent.SerialNum[1],
               owNetCurrent.SerialNum[0]);
        // Init the crc
        setcrc8(0, 0);
        // Read the device's memory
        owWriteByte(0, OW_READSCRATCHPAD);
        for(i = 0; i < SCRATCHPAD_SIZE; i++) {
          ScratchPad[i] = owReadByte(0);
          docrc8(0, ScratchPad[i]);
        }
        // Check the CRC
        if(owNetCurrent.utilcrc8 != 0) {
          printf(", crc is NOT OK.\n%");          
        } else {
          // We don't want to use float's
          temp = ((int)ScratchPad[SCRATCHPAD_TEMPERATUREMSB] << 8) |
                  (int)ScratchPad[SCRATCHPAD_TEMPERATURELSB];
          if(temp < 0) {
            temp = -temp;
            sign = '-';
          } else if(temp == 0) {
            sign = ' ';
          } else {
            sign = '+';
          }
          printf(", Temperature is %c%d.%d degrees\n%",
                 sign,
                 (temp >> 1),
                 (temp & 0x01) ? 5 : 0);
        }
      } while(owNext(0, TRUE, FALSE));
    }   
    printf("End   - Find devices and get their temperatures.\n%");
     
////////////////////////////////////////////////////////////
    Wait(1);  // Just a convenient way to set a breakpoint
  }
}
예제 #8
0
/* MAXIM App. Note #187 */
static int ds24xx_search_rom()
{
	int id_bit_number;
	int last_zero, rom_byte_number, search_result;
	int id_bit, cmp_id_bit;
	unsigned char rom_byte_mask, search_direction;
	unsigned char crc8 = 0;

	/* initialize for search */
	id_bit_number = 1;
	last_zero = 0;
	rom_byte_number = 0;
	rom_byte_mask = 1;
	search_result = 0;

	/* if the last call was not the last one */
	if (!LastDeviceFlag) {
		/* 1-Wire reset */
		if (!ds24xx_reset()) {
			 /* reset the search*/
			 dbg_info("1-Wire: reset fail\n");
			 LastDiscrepancy = 0;
			 LastDeviceFlag = 0;
			 LastFamilyDiscrepancy = 0;
			 return 0;
		}

		/* issue the search command */
		ds24xx_write_byte(ROM_COMMAND_SEARCH);

		/* loop to do the search */
		do
		{
			/* read a bit and its complement */
			id_bit = ds24xx_read_bit();
			cmp_id_bit = ds24xx_read_bit();

			/* check for no devices on 1-Wire */
			if ((id_bit == 1) && (cmp_id_bit == 1))
				break;
			else {
				/* all devices coupled have 0 or 1 */
				if (id_bit != cmp_id_bit)
					search_direction = id_bit;
				else {
					/*
					 * if this discrepancy if before
					 * the Last Discrepancy on a previous
					 * next then pick the same as last time
					 */
					if (id_bit_number < LastDiscrepancy)
						search_direction =
							((buf[rom_byte_number]
							& rom_byte_mask) > 0);
					else
						/*
						 * if equal to last pick 1,
						 * if not then pick 0
						 */
						search_direction
						= (id_bit_number
							== LastDiscrepancy);

					/*
					 * if 0 was picked then record its
					 * position in LastZero
					 */
					if (search_direction == 0) {
						last_zero = id_bit_number;
						/*
						 * check for Last discrepancy
						 * in family
						 */
						if (last_zero < 9)
							LastFamilyDiscrepancy
								= last_zero;
					}
				}

				/*
				 * set or clear the bit in the ROM byte
				 * rom_byte_number with mask rom_byte_mask
				 */
				if (search_direction == 1)
					buf[rom_byte_number] |= rom_byte_mask;
				else
					buf[rom_byte_number] &= ~rom_byte_mask;

				/* serial number search direction write bit */
				if (search_direction == 1)
					ds24xx_write_bit(1);
				else
					ds24xx_write_bit(0);

				/*
				 * increment the byte counter id_bit_number
				 * and shift the mask rom_byte_mask
				 */
				id_bit_number++;
				rom_byte_mask <<= 1;

				/*
				 * if the mask is 0 then go to new SerialNum
				 * byte rom_byte_number and reset mask
				 */
				if (rom_byte_mask == 0) {
					crc8 = docrc8(crc8,
						buf[rom_byte_number]);
					rom_byte_number++;
					rom_byte_mask = 1;
				}
			}
		} while(rom_byte_number < 8);  /* loop until through all ROM bytes 0-7 */

		/* if the search was successful then */
		if (!((id_bit_number < 65) || (crc8 != 0))) {
			/* search successful so set LastDiscrepancy,LastDeviceFlag,search_result */
			LastDiscrepancy = last_zero;

			/* check for last device */
			if (LastDiscrepancy == 0)
				LastDeviceFlag = 1;

			search_result = 1;
		}
	}

	/* if no device found then reset counters so next 'search' will be like a first */
	if (!search_result || !buf[0]) {
		LastDiscrepancy = 0;
		LastDeviceFlag = 0;
		LastFamilyDiscrepancy = 0;
		search_result = 0;
	}

	return search_result;
}
예제 #9
0
파일: temp28.c 프로젝트: ckgt/bladeRF
//----------------------------------------------------------------------
// Read the temperature of a DS18B20 (family code 0x28)
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number was provided to
//                 OpenCOM to indicate the port number.
// 'SerialNum'   - Serial Number of DS18B20 to read temperature from
// 'Temp '       - pointer to variable where that temperature will be
//                 returned
//
// Returns: TRUE(1)  temperature has been read and verified
//          FALSE(0) could not read the temperature, perhaps device is not
//                   in contact
//
int ReadTemperature28(int portnum, uchar *SerialNum, float *Temp)
{
   uchar rt=FALSE;
   uchar send_block[30],lastcrc8;
   int send_cnt, tsht, i, loop=0;
   int power;

   // set the device serial number to the counter device
   owSerialNum(portnum,SerialNum,FALSE);

   for (loop = 0; loop < 2; loop ++)
   {
      // check if the chip is connected to VDD
      if (owAccess(portnum))
      {
         owWriteByte(portnum,0xB4);
         power = owReadByte(portnum);
      } 

      // access the device
      if (owAccess(portnum))
      {
         // send the convert command and if nesessary start power delivery
         if (power) { 
            if (!owWriteBytePower(portnum,0x44))
               return FALSE;
         } else {
            if (!owWriteByte(portnum,0x44))
               return FALSE;
         }

         // sleep for 1 second
         msDelay(1000);

         // turn off the 1-Wire Net strong pull-up
         if (power) { 
            if (owLevel(portnum,MODE_NORMAL) != MODE_NORMAL)
               return FALSE;
         }

         // access the device
         if (owAccess(portnum))
         {
            // create a block to send that reads the temperature
            // read scratchpad command
            send_cnt = 0;
            send_block[send_cnt++] = 0xBE;
            // now add the read bytes for data bytes and crc8
            for (i = 0; i < 9; i++)
               send_block[send_cnt++] = 0xFF;

            // now send the block
            if (owBlock(portnum,FALSE,send_block,send_cnt))
            {
               // initialize the CRC8
               setcrc8(portnum,0);
               // perform the CRC8 on the last 8 bytes of packet
               for (i = send_cnt - 9; i < send_cnt; i++)
                  lastcrc8 = docrc8(portnum,send_block[i]);

               // verify CRC8 is correct
               if (lastcrc8 == 0x00)
               {
                  // calculate the high-res temperature
            	  tsht =        send_block[2] << 8;
            	  tsht = tsht | send_block[1];
            	  if (tsht & 0x00001000)
            		  tsht = tsht | 0xffff0000;
                  *Temp = ((float) tsht)/16;
                  // success
                  rt = TRUE;
                  break;
               }
            }
         }
      }

   }

   // return the result flag rt
   return rt;
}
예제 #10
0
파일: temp28.c 프로젝트: rmanders/owpy
//----------------------------------------------------------------------
// Read the temperature of a DS18B20
//
// 'portnum'     - number 0 to MAX_PORTNUM-1.  This number was provided to
//                 OpenCOM to indicate the port number.
// 'SerialNum'   - Serial Number of DS1920/DS1820 to read temperature from
// 'Temp '       - pointer to variable where that temperature will be
//                 returned
//
// Returns: TRUE(1)  temperature has been read and verified
//          FALSE(0) could not read the temperature, perhaps device is not
//                   in contact
//
int ReadTemperature28(int portnum, uchar *SerialNum, float *Temp)
{
   uchar rt=FALSE;
   uchar send_block[30],lastcrc8;
   int send_cnt, tsht, i, loop=0;
   float tmp,cr,cpc;

   // set the device serial number to the counter device
   owSerialNum(portnum,SerialNum,FALSE);

   for (loop = 0; loop < 2; loop ++)
   {
      // access the device
      if (owAccess(portnum))
      {
         // send the convert command and start power delivery
         if (!owWriteBytePower(portnum,0x44))
            return FALSE;

         // sleep for 1 second
         msDelay(1000);

         // turn off the 1-Wire Net strong pull-up
         if (owLevel(portnum,MODE_NORMAL) != MODE_NORMAL)
            return FALSE;

         // access the device
         if (owAccess(portnum))
         {
            // create a block to send that reads the temperature
            // read scratchpad command
            send_cnt = 0;
            send_block[send_cnt++] = 0xBE;
            // now add the read bytes for data bytes and crc8
            for (i = 0; i < 9; i++)
               send_block[send_cnt++] = 0xFF;

            // now send the block
            if (owBlock(portnum,FALSE,send_block,send_cnt))
            {
               // initialize the CRC8
               setcrc8(portnum,0);
               // perform the CRC8 on the last 8 bytes of packet
               for (i = send_cnt - 9; i < send_cnt; i++)
                  lastcrc8 = docrc8(portnum,send_block[i]);

               // verify CRC8 is correct
               if (lastcrc8 == 0x00)
               {
                  // calculate the high-res temperature
                  tsht = (send_block[1] >> 4) + ((send_block[2] & 0x07) << 4);
                  if (send_block[2] & 0x80)
                     tsht |= -128;
                  tmp = (float)(tsht);

                  //cr = send_block[7];
                  //cpc = send_block[8];
                  //if (((cpc - cr) == 1) && (loop == 0))
                  //   continue;
                  //if (cpc == 0)
                  //   return FALSE;
                  //else
                  //   tmp = tmp - (float)0.25 + (cpc - cr)/cpc;

	  	  // TODO: Check config register

		  if(send_block[1] & 0x01) {
			tmp += 0.0625f;
                  }
		  else if(send_block[1] & 0x02) {
			tmp += 0.125f;
                  }
		  else if(send_block[1] & 0x04) {
			tmp += 0.25f;
                  }
		  else if(send_block[1] & 0x08) {
			tmp += 0.5f;
                  }

                  *Temp = tmp;
                  // success
                  rt = TRUE;
                  break;
               }
            }
         }
      }

   }
예제 #11
0
//--------------------------------------------------------------------------
// The 'OWSearch' 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.
//
// Returns:   TRUE (1) : when a 1-Wire device was found and it's
//                       Serial Number placed in the global ROM
//            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.
//
int DallasOneWire::OWSearch(void)
{
	DATA(F("OWSearch"));

	unsigned char last_zero,pos;
	unsigned char tmp_rom[8];
	unsigned char readbuffer[20],sendpacket[40];
	unsigned char i,sendlen=0;

	// if the last call was the last one
	if (LastDeviceFlag)
	{
		DATA(F("OWSearch: the last call was the last one"));
		// reset the search
		LastDiscrepancy = 0;
		LastDeviceFlag = FALSE;
		LastFamilyDiscrepancy = 0;
		return FALSE;
	}

	// reset the 1-wire
	// if there are no parts on 1-wire, return FALSE
	if (!OWReset())
	{
		DEBUG(F("OWSearch: there are no parts on 1-wire, return FALSE"));
		// reset the search
		LastDiscrepancy = 0;
		LastFamilyDiscrepancy = 0;
		return FALSE;
	}

	// build the command stream
	// call a function that may add the change mode command to the buff
	// check for correct mode
	if (UMode != MODSEL_DATA)
	{
		DATA(F("OWSearch: UMode != MODSEL_DATA"));
		UMode = MODSEL_DATA;
		sendpacket[sendlen++] = MODE_DATA;
	}

	// search command
	sendpacket[sendlen++] = 0xF0;

	// change back to command mode
	UMode = MODSEL_COMMAND;
	sendpacket[sendlen++] = MODE_COMMAND;

	// search mode on
	sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed);

	// change back to data mode
	UMode = MODSEL_DATA;
	sendpacket[sendlen++] = MODE_DATA;

	// set the temp Last Discrepancy to 0
	last_zero = 0;

	// add the 16 bytes of the search
	pos = sendlen;
	for (i = 0; i < 16; i++)
		sendpacket[sendlen++] = 0;

	// only modify bits if not the first search
	if (LastDiscrepancy != 0)
	{
		DATA(F("OWSearch: LastDiscrepancy != 0"));
		// set the bits in the added buffer
		for (i = 0; i < 64; i++)
		{
			// before last discrepancy
			if (i < (LastDiscrepancy - 1))
				bitacc(WRITE_FUNCTION,
						bitacc(READ_FUNCTION,0,i,&ROM_NO[0]),
						(short)(i * 2 + 1),
						&sendpacket[pos]);
			// at last discrepancy
			else if (i == (LastDiscrepancy - 1))
				bitacc(WRITE_FUNCTION,1,(short)(i * 2 + 1),
						&sendpacket[pos]);
			// after last discrepancy so leave zeros
		}
	}

	// change back to command mode
	UMode = MODSEL_COMMAND;
	sendpacket[sendlen++] = MODE_COMMAND;

	// search OFF command
	sendpacket[sendlen++] = (unsigned char)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed);

	// flush the buffers
	flush();

	// send the packet
	if (WriteCOM(sendlen,sendpacket))
	{
		// read back the 1 byte response
		if (ReadCOM(17,readbuffer) == 17)
		{
			// interpret the bit stream
			for (i = 0; i < 64; i++)
			{
				// get the ROM bit
				bitacc(WRITE_FUNCTION,
						bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),i,
						&tmp_rom[0]);
				// check LastDiscrepancy
				if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) &&
						(bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0))
				{
					last_zero = i + 1;
					// check LastFamilyDiscrepancy
					if (i < 8)
						LastFamilyDiscrepancy = i + 1;
				}
			}

			// do dowcrc
			crc8 = 0;
			for (i = 0; i < 8; i++)
				docrc8(tmp_rom[i]);

			// check results
			if ((crc8 != 0) || (LastDiscrepancy == 63) || (tmp_rom[0] == 0))
			{
				// error during search
				// reset the search
				LastDiscrepancy = 0;
				LastDeviceFlag = FALSE;
				LastFamilyDiscrepancy = 0;
				return FALSE;
			}
			// successful search
			else
			{
				// set the last discrepancy
				LastDiscrepancy = last_zero;

				// check for last device
				if (LastDiscrepancy == 0)
					LastDeviceFlag = TRUE;

				// copy the ROM to the buffer
				for (i = 0; i < 8; i++)
					ROM_NO[i] = tmp_rom[i];

				return TRUE;
			}
		}
	}

	WARNING(F("OWSearch: an error occured so re-sync with DS2480B"));
	// an error occured so re-sync with DS2480B
	DS2480B_Detect();

	// reset the search
	LastDiscrepancy = 0;
	LastDeviceFlag = FALSE;
	LastFamilyDiscrepancy = 0;

	return FALSE;
}
예제 #12
0
파일: ownet.c 프로젝트: ckgt/bladeRF
//--------------------------------------------------------------------------
// 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)
{
   uchar bit_test, search_direction, bit_number;
   uchar last_zero, serial_byte_number, next_result;
   uchar serial_byte_mask;
   uchar lastcrc8;

   // initialize for search
   bit_number = 1;
   last_zero = 0;
   serial_byte_number = 0;
   serial_byte_mask = 1;
   next_result = 0;
   setcrc8(portnum,0);

   // if the last call was not the last one
   if (!LastDevice[portnum])
   {
      // check if reset first is requested
      if (do_reset)
      {
         // reset the 1-wire
         // if there are no parts on 1-wire, return FALSE
         if (!owTouchReset(portnum))
         {
            // printf("owTouchReset failed\r\n");
            // reset the search
            LastDiscrepancy[portnum] = 0;
            LastFamilyDiscrepancy[portnum] = 0;
            OWERROR(OWERROR_NO_DEVICES_ON_NET);
            return FALSE;
         }
      }

      // If finding alarming devices issue a different command
      if (alarm_only)
         owWriteByte(portnum,0xEC);  // issue the alarming search command
      else
         owWriteByte(portnum,0xF0);  // issue the search command

      //pause before beginning the search
      //usDelay(100);

      // loop to do the search
      do
      {
         // read a bit and its compliment
         bit_test = owTouchBit(portnum,1) << 1;
         bit_test |= owTouchBit(portnum,1);

         // check for no devices on 1-wire
         if (bit_test == 3)
            break;
         else
         {
            // all devices coupled have 0 or 1
            if (bit_test > 0)
              search_direction = !(bit_test & 0x01);  // bit write value for search
            else
            {
               // if this discrepancy if before the Last Discrepancy
               // on a previous next then pick the same as last time
               if (bit_number < LastDiscrepancy[portnum])
                  search_direction = ((SerialNum[portnum][serial_byte_number] & serial_byte_mask) > 0);
               else
                  // if equal to last pick 1, if not then pick 0
                  search_direction = (bit_number == LastDiscrepancy[portnum]);

               // if 0 was picked then record its position in LastZero
               if (search_direction == 0)
               {
                  last_zero = bit_number;

                  // check for Last discrepancy in family
                  if (last_zero < 9)
                     LastFamilyDiscrepancy[portnum] = last_zero;
               }
            }

            // set or clear the bit in the SerialNum[portnum] byte serial_byte_number
            // with mask serial_byte_mask
            if (search_direction == 1)
              SerialNum[portnum][serial_byte_number] |= serial_byte_mask;
            else
              SerialNum[portnum][serial_byte_number] &= ~serial_byte_mask;

            // serial number search direction write bit
            owTouchBit(portnum,search_direction);

            // increment the byte counter bit_number
            // and shift the mask serial_byte_mask
            bit_number++;
            serial_byte_mask <<= 1;

            // if the mask is 0 then go to new SerialNum[portnum] byte serial_byte_number
            // and reset mask
            if (serial_byte_mask == 0)
            {
               // The below has been added to accomidate the valid CRC with the
               // possible changing serial number values of the DS28E04.
               if (((SerialNum[portnum][0] & 0x7F) == 0x1C) && (serial_byte_number == 1))
                  lastcrc8 = docrc8(portnum,0x7F);
               else
                  lastcrc8 = docrc8(portnum,SerialNum[portnum][serial_byte_number]);  // accumulate the CRC

               serial_byte_number++;
               serial_byte_mask = 1;
            }
         }
      }
      while(serial_byte_number < 8);  // loop until through all SerialNum[portnum] bytes 0-7

      // if the search was successful then
      if (!((bit_number < 65) || lastcrc8))
      {
         // search successful so set LastDiscrepancy[portnum],LastDevice[portnum],next_result
         LastDiscrepancy[portnum] = last_zero;
         LastDevice[portnum] = (LastDiscrepancy[portnum] == 0);
         next_result = TRUE;
      }
   }

   // if no device found then reset counters so next 'next' will be
   // like a first
   if (!next_result || !SerialNum[portnum][0])
   {
      LastDiscrepancy[portnum] = 0;
      LastDevice[portnum] = FALSE;
      LastFamilyDiscrepancy[portnum] = 0;
      next_result = FALSE;
   }

   return next_result;
}
int Ow_Search()
{
   int id_bit_number;
   int last_zero, rom_byte_number, search_result;
   int id_bit, cmp_id_bit;
   unsigned char rom_byte_mask, search_direction;
   // initialize for search
   id_bit_number = 1;
   last_zero = 0;
   rom_byte_number = 0;
   rom_byte_mask = 1;
   search_result = 0;
   crc8 = 0;
   // if the last call was not the last one
   if (!LastDeviceFlag)
   {
                 // 1-Wire reset
                 if (Ow_Reset())
                 {
                        // reset the search
                        LastDiscrepancy = 0;
                        LastDeviceFlag = 0;
                        LastFamilyDiscrepancy = 0;
                        return 0;
                 }


                 // issue the search command
                 Ow_Write_Byte(0xF0);

                // loop to do the search
                do
                {
                  // read a bit and its complement
                  id_bit = OW_Read_Bit();
                  cmp_id_bit = OW_Read_Bit();
                  
                  // check for no devices on 1-wire
                 if ((id_bit == 1) && (cmp_id_bit == 1))
                        break;
                 else
                 {
                        // all devices coupled have 0 or 1
                        if (id_bit != cmp_id_bit)
                          search_direction = id_bit; // bit write value for search
                        else
                        {
                           // if this discrepancy is before the Last Discrepancy
                           // on a previous next then pick the same as last time
                         
                           if (id_bit_number < LastDiscrepancy)
                                 search_direction = ((ROM_NO[rom_byte_number] &  rom_byte_mask) > 0);
                           else
                                 // if equal to last pick 1, if not then pick 0
                                 search_direction = (id_bit_number == LastDiscrepancy);
                           
                          // if 0 was picked then record its position in LastZero
                         if (search_direction == 0)
                         {
                                 last_zero = id_bit_number;
                                 // check for Last discrepancy in family
                                 if (last_zero < 9) LastFamilyDiscrepancy = last_zero;
                         }
                        }
                  
                        // set or clear the bit in the ROM byte rom_byte_number
                        // with mask rom_byte_mask
                  
                        //postavlja vrednost procitanog bita
                        if (search_direction == 1)
                           ROM_NO[rom_byte_number] |= rom_byte_mask;
                        else
                           ROM_NO[rom_byte_number] &= ~rom_byte_mask;
                         
                         
                        // serial number search direction write bit
                        if (search_direction)
                           Ow_Write_One();
                        else
                           Ow_Write_Zero();


                        // increment the byte counter id_bit_number
                        // and shift the mask rom_byte_mask
                  
                        id_bit_number++;
                        rom_byte_mask <<= 1;

                        // if the mask is 0 then go to new SerialNum byte rom_byte_number
                        //and reset mask
                  
                        if (rom_byte_mask == 0)
                        {
                           docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC
                           rom_byte_number++;
                           rom_byte_mask = 1;
                        }
                  }
                }   // End of search loop
                while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
                //IntToStr(id_bit_number,tmp);
                //Lcd_Out(1,1,tmp);
                // if the search was successful then
                if (id_bit_number == 65)
                {
                  // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
                  LastDiscrepancy = last_zero;
                  //Lcd_Out(2,1,"mlp");
                  // check for last device
                  if (LastDiscrepancy == 0) 
                     LastDeviceFlag = 1;
                  search_result = 1;
                  //IntToStr(search_result,tmp1);
                  //Lcd_Out(1,9,tmp1);
                }
   }
   // if no device found then reset counters so next 'search' will be
   // like a first
   
  if (!search_result || !ROM_NO[0])
  {
    LastDiscrepancy = 0;
    LastDeviceFlag = 0;
    LastFamilyDiscrepancy = 0;
    search_result = 0;
  }

  return search_result;
}   // End of Ow-Search function
예제 #14
0
파일: ownetu.c 프로젝트: BitMax/openitg
//--------------------------------------------------------------------------
// 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 was provided to
//                OpenCOM to indicate the 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
//            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)
{
   uchar last_zero,pos;
   uchar tmp_serial_num[8];
   uchar readbuffer[20],sendpacket[40];
   uchar i,sendlen=0;
   uchar lastcrc8;

   // 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
      // 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 command stream
   // call a function that may add the change mode command to the buff
   // check if correct mode
   if (UMode[portnum] != MODSEL_DATA)
   {
      UMode[portnum] = MODSEL_DATA;
      sendpacket[sendlen++] = MODE_DATA;
   }

   // search command
   if (alarm_only)
      sendpacket[sendlen++] = 0xEC; // issue the alarming search command
   else
      sendpacket[sendlen++] = 0xF0; // issue the search command

   // change back to command mode
   UMode[portnum] = MODSEL_COMMAND;
   sendpacket[sendlen++] = MODE_COMMAND;

   // search mode on
   sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHON | USpeed[portnum]);

   // change back to data mode
   UMode[portnum] = MODSEL_DATA;
   sendpacket[sendlen++] = MODE_DATA;

   // set the temp Last Descrep to none
   last_zero = 0;

   // add the 16 bytes of the search
   pos = sendlen;
   for (i = 0; i < 16; i++)
      sendpacket[sendlen++] = 0;

   // only modify bits if not the first search
   if (LastDiscrepancy[portnum] != 0)
   {
      // set the bits in the added buffer
      for (i = 0; i < 64; i++)
      {
         // before last discrepancy
         if (i < (LastDiscrepancy[portnum] - 1))
               bitacc(WRITE_FUNCTION,
                   bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),
                   (short)(i * 2 + 1),
                   &sendpacket[pos]);
         // at last discrepancy
         else if (i == (LastDiscrepancy[portnum] - 1))
                bitacc(WRITE_FUNCTION,1,
                   (short)(i * 2 + 1),
                   &sendpacket[pos]);
         // after last discrepancy so leave zeros
      }
   }

   // change back to command mode
   UMode[portnum] = MODSEL_COMMAND;
   sendpacket[sendlen++] = MODE_COMMAND;

   // search OFF
   sendpacket[sendlen++] = (uchar)(CMD_COMM | FUNCTSEL_SEARCHOFF | USpeed[portnum]);

   // flush the buffers
   FlushCOM(portnum);

   // send the packet
   if (WriteCOM(portnum,sendlen,sendpacket))
   {
      // read back the 1 byte response
      if (ReadCOM(portnum,17,readbuffer) == 17)
      {
         // interpret the bit stream
         for (i = 0; i < 64; i++)
         {
            // get the SerialNum bit
            bitacc(WRITE_FUNCTION,
                   bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]),
                   i,
                   &tmp_serial_num[0]);
            // check LastDiscrepancy
            if ((bitacc(READ_FUNCTION,0,(short)(i * 2),&readbuffer[1]) == 1) &&
                (bitacc(READ_FUNCTION,0,(short)(i * 2 + 1),&readbuffer[1]) == 0))
            {
               last_zero = i + 1;
               // check LastFamilyDiscrepancy
               if (i < 8)
                  LastFamilyDiscrepancy[portnum] = i + 1;
            }
         }

         // do dowcrc
         setcrc8(portnum,0);
//         for (i = 0; i < 8; i++)
//            lastcrc8 = docrc8(portnum,tmp_serial_num[i]);
         // The above has been commented out for the DS28E04.  The
         // below has been added to accomidate the valid CRC with the
         // possible changing serial number values of the DS28E04.
         for (i = 0; i < 8; i++)
         {
            if (((tmp_serial_num[0] & 0x7F) == 0x1C) && (i == 1))
               lastcrc8 = docrc8(portnum,0x7F);
            else            
               lastcrc8 = docrc8(portnum,tmp_serial_num[i]);
         }


         // check results
         if ((lastcrc8 != 0) || (LastDiscrepancy[portnum] == 63) || (tmp_serial_num[0] == 0))
         {
            // error during search
            // reset the search
            LastDiscrepancy[portnum] = 0;
            LastDevice[portnum] = FALSE;
            LastFamilyDiscrepancy[portnum] = 0;
            OWERROR(OWERROR_SEARCH_ERROR);
            return FALSE;
         }
         // successful search
         else
         {
            // set the last discrepancy
            LastDiscrepancy[portnum] = last_zero;

            // check for last device 
            if (LastDiscrepancy[portnum] == 0)
               LastDevice[portnum] = TRUE;

            // copy the SerialNum to the buffer
            for (i = 0; i < 8; i++)
               SerialNum[portnum][i] = tmp_serial_num[i];

            // set the count
            return TRUE;
         }
      }
      else
         OWERROR(OWERROR_READCOM_FAILED);
   }
   else
      OWERROR(OWERROR_WRITECOM_FAILED);
   
   // an error occured so re-sync with DS2480
   DS2480Detect(portnum);

   // reset the search
   LastDiscrepancy[portnum] = 0;
   LastDevice[portnum] = FALSE;
   LastFamilyDiscrepancy[portnum] = 0;

   return FALSE;
}
예제 #15
0
파일: usbwnet.c 프로젝트: AriZuu/OneWire
//--------------------------------------------------------------------------
// 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;
}
예제 #16
0
//--------------------------------------------------------------------------
// 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.
//
BYTE owNext(BYTE portnum, BYTE do_reset, BYTE alarm_only)
{
   BYTE bit_test, search_direction, bit_number;
   BYTE last_zero, serial_byte_number, next_result;
   BYTE serial_byte_mask;
   BYTE lastcrc8;

   owSetCurrentPort(portnum);

   // initialize for search
   bit_number = 1;
   last_zero = 0;
   serial_byte_number = 0;
   serial_byte_mask = 1;
   next_result = 0;
   setcrc8(portnum, 0);

   // if the last call was not the last one
   if(!owNetCurrent.LastDevice) {
     // check if reset first is requested
     if(do_reset) {
       // reset the 1-wire
       // if there are no parts on 1-wire, return FALSE
       if(!owTouchReset(owCurrentPortnum)) {
         // reset the search
         owNetCurrent.LastDiscrepancy       = 0;
         owNetCurrent.LastFamilyDiscrepancy = 0;
         OWERROR(OWERROR_NO_DEVICES_ON_NET);
         return FALSE;
       }
     }

     // If finding alarming devices issue a different command
     if(alarm_only) {
       owWriteByte(owCurrentPortnum, 0xEC);  // issue the alarming search command
     } else {
       owWriteByte(owCurrentPortnum, 0xF0);  // issue the search command
     }

     //pause before beginning the search
     //usDelay(100);

     // loop to do the search
     do {
       // read a bit and its compliment
       bit_test  = owTouchBit(owCurrentPortnum, 1) << 1;
       bit_test |= owTouchBit(owCurrentPortnum, 1);

       // check for no devices on 1-wire
       if(bit_test == 3) {
         break;
       }

       // all devices coupled have 0 or 1
       if(bit_test > 0) {
         search_direction = !(bit_test & 0x01);  // bit write value for search
       } else {
         // if this discrepancy if before the Last Discrepancy
         // on a previous next then pick the same as last time
         if(bit_number < owNetCurrent.LastDiscrepancy) {
           search_direction = ((owNetCurrent.SerialNum[serial_byte_number] & serial_byte_mask) > 0);
         } else {
           // if equal to last pick 1, if not then pick 0
           search_direction = (bit_number == owNetCurrent.LastDiscrepancy);
         }
         
         // if 0 was picked then record its position in LastZero
         if(search_direction == 0) {
           last_zero = bit_number;

           // check for Last discrepancy in family
           if(last_zero < 9) {
             owNetCurrent.LastFamilyDiscrepancy = last_zero;
           }
         }
       }

       // set or clear the bit in the SerialNum byte serial_byte_number
       // with mask serial_byte_mask
       if(search_direction == 1) {
         owNetCurrent.SerialNum[serial_byte_number] |= serial_byte_mask;
       } else {
         owNetCurrent.SerialNum[serial_byte_number] &= ~serial_byte_mask;
       }
       
       // serial number search direction write bit
       owTouchBit(owCurrentPortnum, search_direction);

       // increment the byte counter bit_number
       // and shift the mask serial_byte_mask
       bit_number++;
       serial_byte_mask <<= 1;

       // if the mask is 0 then go to new SerialNum byte serial_byte_number
       // and reset mask
       if(serial_byte_mask == 0) {
         lastcrc8 = docrc8(owCurrentPortnum, owNetCurrent.SerialNum[serial_byte_number]);  // accumulate the CRC
         serial_byte_number++;
         serial_byte_mask = 1;
       }
     } while(serial_byte_number < 8);  // loop until through all SerialNum bytes 0-7

     // if the search was successful then
     if(!((bit_number < 65) || lastcrc8)) {
       // search successful so set LastDiscrepancy, LastDevice, next_result
       owNetCurrent.LastDiscrepancy = last_zero;
       if(last_zero == 0) {
         owNetCurrent.LastDevice = TRUE;
       } else {
         owNetCurrent.LastDevice = FALSE;
       }
//         owNetCurrent.LastDevice = (last_zero == 0);
          
       next_result = TRUE;
     }
   }

   // if no device found then reset counters so next 'next' will be
   // like a first
   if(!next_result || !owNetCurrent.SerialNum[0]) {
     owNetCurrent.LastDiscrepancy = 0;
     owNetCurrent.LastDevice = FALSE;
     owNetCurrent.LastFamilyDiscrepancy = 0;
     next_result = FALSE;
   }

   return next_result;
}