Exemplo n.º 1
0
uint8_t OWI_SearchRom(myOneWire *ow)
{
	uint8_t bitIndex = 0;
	uint8_t byteIndex = 0;
	uint8_t newDeviation = 0;
	uint8_t bitMask = 0x01;
	uint8_t bitA;
	uint8_t bitB;
	
	OWI_SendByte(ow, OWI_SEARCH_ROM);
	
	while (bitIndex < 64) {
		bitA = OWI_ReadBit(ow);
		bitB = OWI_ReadBit(ow);
		
		if(bitA && bitB) {
			newDeviation = -1;
			return newDeviation;
		} else if(bitA ^ bitB) {
			if(bitA)
				ow->address[byteIndex] |= bitMask;
			else
				ow->address[byteIndex] &= ~bitMask;
		} else {
			if(bitIndex == ow->lastDeviation) {
				ow->address[byteIndex] |= bitMask;
			} else if(bitIndex > ow->lastDeviation) {
				ow->address[byteIndex] &= ~bitMask;
				newDeviation = bitIndex;
			} else if(!(ow->address[byteIndex] & bitMask)) {
				newDeviation = bitIndex;
			}
		}
		
		OWI_WriteBit(ow, ow->address[byteIndex] & bitMask);
		
		bitIndex++;
		bitMask <<= 1;
		if(!bitMask) {
			bitMask = 0x01;
			byteIndex++;
		}
	}
	
	return newDeviation;
}
Exemplo n.º 2
0
uint8_t OWI_ReceiveByte(myOneWire* ow)
{
	uint8_t data = 0;
	uint8_t bitsReceived;
	for(bitsReceived = 0; bitsReceived < 8; bitsReceived++) {
		data >>= 1;
		if(OWI_ReadBit(ow)) {
			data |= 0x80;
		}
	}
	
	return data;
}
Exemplo n.º 3
0
/*****************************************************************************
*   Function name : DS18B20_SetDeviceAccuracy
*   Parameters :    bus - вывод микроконтроллера, который выполн¤ет роль 1WIRE шины
*                   *id - им¤ массива из 8-ми элементов, в котором хранитс¤
*                         адрес датчика DS18B20
*                   accuracy - значение точность необходимой дл¤ установлени¤
*						0	-	9bit
*						1	-	10bit
*						2	-	11bit
*						3	-	12bit
*					
*   Purpose :      јдресует датчик DS18B20, записывает в пам¤ть (scratchpad),
*				   копирует scratchpad в EEPROM. 
*				   —ледует вызывать только один раз дл¤ настройки устройства
*****************************************************************************/
void DS18B20_SetDeviceAccuracy(unsigned char bus, unsigned char* id, unsigned char accuracy){
	OWI_DetectPresence(bus);
	OWI_MatchRom(id, bus);
	OWI_SendByte(DS18B20_WRITE_SCRATCHPAD, bus);

	OWI_SendByte(0x00, bus);	//Th
	OWI_SendByte(0x00, bus);	//Tl
	OWI_SendByte(0x1F | ((accuracy & 0x03)<<5), bus);	//Config
	
	OWI_DetectPresence(bus);
	OWI_MatchRom(id, bus);
	OWI_SendByte(DS18B20_COPY_SCRATCHPAD, bus);
	
	while (!OWI_ReadBit(bus));
}
Exemplo n.º 4
0
/*! \brief  Receives one byte of data from the 1-Wire(R) bus.
 *
 *  This function automates the task of receiving a complete byte
 *  of data from the 1-Wire bus.
 *
 *  \param  pin     A bitmask of the bus to read from.
 *
 *  \return     The byte read from the bus.
 */
unsigned char OWI_ReceiveByte( unsigned char pin )
{
   unsigned char data;
   unsigned char i;

   // Clear the temporary input variable.
   data = 0x00;

   // Do once for each bit
   for ( i = 0; i < 8 ; i++ )
   {
      // Shift temporary input variable right.
      data >>= 1;
      // Set the msb if a '1' value is read from the bus.
      // Leave as it is ('0') else.
      if ( OWI_ReadBit(pin) )
      {
         // Set msb
         data |= 0x80;
      }
   }
   return data;
}
Exemplo n.º 5
0
/*****************************************************************************
*   Function name :   DS18B20_ReadTemperature
*   Returns :       коды - READ_CRC_ERROR, если считанные данные не прошли проверку
*                          READ_SUCCESSFUL, если данные прошли проверку
*   Parameters :    bus - вывод микроконтроллера, который выполняет роль 1WIRE шины
*                   *id - имя массива из 8-ми элементов, в котором хранится
*                         адрес датчика DS18B20
*                   *ds18b20_temperature - указатель на шестнадцати разрядную переменную
*                                в которой будет сохранено считанного зн. температуры
*   Purpose :      Адресует датчик DS18B20, дает команду на преобразование температуры
*                  ждет, считывает его память - scratchpad, проверяет CRC,
*                  сохраняет значение температуры в переменной, возвращает код ошибки
*****************************************************************************/
BYTE DS18B20_ReadTemperature(BYTE bus, BYTE * id, WORD* ds18b20_temperature)
{
    unsigned char scratchpad[9];
    unsigned char i;

    /*подаем сигнал сброса
    команду для адресации устройства на шине
    подаем команду - запук преобразования */
    OWI_DetectPresence(bus);
    OWI_MatchRom(id, bus);
    OWI_SendByte(DS18B20_CONVERT_T ,bus);

    /*ждем, когда датчик завершит преобразование*/
    while (!OWI_ReadBit(bus));

    /*подаем сигнал сброса
    команду для адресации устройства на шине
    команду - чтение внутренней памяти
    затем считываем внутреннюю память датчика в массив
    */
    OWI_DetectPresence(bus);
    OWI_MatchRom(id, bus);
    OWI_SendByte(DS18B20_READ_SCRATCHPAD, bus);
    for (i = 0; i<=8; i++){
      scratchpad[i] = OWI_ReceiveByte(bus);
    }

    if(OWI_CheckScratchPadCRC(scratchpad) != OWI_CRC_OK){
      return READ_CRC_ERROR;
    }


    *ds18b20_temperature = MAKEWORD(scratchpad[0], scratchpad[1]);


    return READ_SUCCESSFUL;
}
Exemplo n.º 6
0
unsigned char OWI_SearchAlarm( unsigned char * bitPattern, unsigned char lastDeviation, unsigned char pin )
{
   unsigned char currentBit = 1;
   unsigned char newDeviation = 0;
   unsigned char bitMask = 0x01;
   unsigned char bitA;
   unsigned char bitB;

   // Send SEARCH ROM command on the bus.
   OWI_SendByte(OWI_ROM_ALARM, pin);

   // Walk through all 64 bits.
   while ( currentBit <= 64 )
   {
      // Read bit from bus twice.
      bitA = OWI_ReadBit(pin);
      bitB = OWI_ReadBit(pin);

      if ( bitA && bitB )
      {
         // Both bits 1 (Error).
         newDeviation = OWI_ROM_SEARCH_FAILED;

         return newDeviation;
      }
      else if ( bitA ^ bitB )
      {
         // Bits A and B are different. All devices have the same bit here.
         // Set the bit in bitPattern to this value.
         if ( bitA )
         {
            ( *bitPattern ) |= bitMask;

         }
         else
         {
            ( *bitPattern ) &= ~bitMask;
         }
      }
      else // Both bits 0
      {
         // If this is where a choice was made the last time,
         // a '1' bit is selected this time.
         if ( currentBit == lastDeviation )
         {
            ( *bitPattern ) |= bitMask;
         }
         // For the rest of the id, '0' bits are selected when
         // discrepancies occur.
         else if ( currentBit > lastDeviation )
         {
            ( *bitPattern ) &= ~bitMask;
            newDeviation = currentBit;
         }
         // If current bit in bit pattern = 0, then this is
         // out new deviation.
         else if ( !( *bitPattern & bitMask ) )
         {
            newDeviation = currentBit;
         }
         // IF the bit is already 1, do nothing.
         else
         {

         }
      }

      // Send the selected bit to the bus.
      if ( ( *bitPattern ) & bitMask )
      {
         OWI_WriteBit1(pin);
      }
      else
      {
         OWI_WriteBit0(pin);
      }

      // Increment current bit.
      currentBit++;

      // Adjust bitMask and bitPattern pointer.
      bitMask <<= 1;
      if ( !bitMask )
      {
         bitMask = 0x01;
         bitPattern++;
      }
   }
   return newDeviation;
}
Exemplo n.º 7
0
/*
 * owiADCConvert(unsigned char bus_pattern, unsigned char * id)
 *
 *
 * this function implements the convert function
 * using the 0x3C command
 *
 * CRC checks are not performed
 *
 * input:
 *    bus_pattern:
 *                 pattern of bus lines to send command to
 *    id         :
 *                 1-wire device id 8 byte char array
 *                    - if set, i.e. not NULL, only device with this id is addressed (MATCH_ROM)
 *                    - else every device is used (ROM_SKIP)
 *
 * return:
 *    0: ok
 *    1: failed
 *
 */
uint8_t owiADCConvert(unsigned char currentPins, unsigned char * id)
{
	printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("bus_pattern: %#x starting conversion sequence"), currentPins );

	static uint16_t maxConversionTime = OWI_ADC_MAX_CONVERSION_TIME_MILLISECONDS;
	static uint32_t count;
	static uint32_t maxcount;
	static unsigned char timeout_flag;
	uint8_t trialsCounter = 0;
	uint8_t result = RESULT_OK;
    uint16_t receive_CRC;

	maxcount = ( OWI_ADC_CONVERSION_DELAY_MILLISECONDS > 0 ) ? maxConversionTime / OWI_ADC_CONVERSION_DELAY_MILLISECONDS : 1;
	count = maxcount;
	timeout_flag = FALSE;

	/*
	 * CONVERT [3CH]
	 *
	 * The Convert command is used to initiate the analog to digital conversion for one or more channels at the
	 * resolution specified in memory page 1, control/status data. The conversion takes between 60 and 80 μs
	 * per bit plus an offset time of maximum 160 μs every time the convert command is issued. For four
	 * channels with 12-bit resolution each, as an example, the convert command will not take more than
	 * 4x12x80 μs plus 160 μs offset, which totals 4 ms. If the DS2450 gets its power through the VCC pin, the
	 * bus master may communicate with other devices on the 1-Wire bus while the DS2450 is busy with A/D
	 * conversions. If the device is powered entirely from the 1-Wire bus, the bus master must instead provide a
	 * strong pullup to 5V for the estimated duration of the conversion in order to provide sufficient energy.
	 *
	 * The conversion is controlled by the input select mask (Figure 7a) and the read-out control byte (Figure
	 * 7b). In the input select mask the bus master specifies which channels participate in the conversion. A
	 * channel is selected if the bit associated to the channel is set to 1. If more than one channel is selected, the
	 * conversion takes place one channel after another in the sequence A, B, C, D, skipping those channels that
	 * are not selected. The bus master can read the result of a channel’s conversion before the conversion of all
	 * the remaining selected channels is completed. In order to distinguish between the previous result and the
	 * new value the bus master uses the read-out control byte. This byte allows presetting the conversion readout
	 * registers for each selected channel to all 1’s or all 0’s. If the expected result is close to 0 then one
	 * should preset to all 1’s or to all 0’s if the conversion result will likely be a high number. In applications
	 * where the bus master can wait until all selected channels are converted before reading, a preset of the
	 * read-out registers is not necessary. Note that for a channel not selected in the input select mask, the
	 * channel’s read-out control setting has no effect. If a channel constantly yields conversion results close to
	 * 0 the channel’s output transistor may be conducting. See section Device Registers for details.
	 *
	 * INPUT SELECT MASK (CONVERSION COMMAND) Figure 7a
	 * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
	 * “don’t care” D C B A
	 *
	 * READ-OUT CONTROL (CONVERSION COMMAND) Figure 7b
	 * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
	 * Set D Clear D Set C Clear C Set B Clear B Set A Clear A
	 *
	 * Set Clear Explanation
	 * 0 0 no preset, leave as is
	 * 0 1 preset to all 0’s
	 * 1 0 preset to all 1’s
	 * 1 1 (illegal code)
	 *
	 * Following the Convert command byte the bus master transmits the input select mask and the read-out
	 * control byte. Now the bus master reads the CRC16 of the command byte, select mask and control byte.
	 * The conversion will start no earlier than 10 μs after the most significant bit of the CRC is received by the
	 * bus master.
	 *
	 * With a parasitic power supply the bus master must activate the strong pullup within this 10 μs window for
	 * a duration that is estimated as explained above. After that, the data line returns to an idle high state and
	 * communication on the bus can resume. The bus master would normally send a reset pulse to exit the
	 * Convert command. Read data time slots generated after the strong pullup has ended but before issuing a
	 * reset pulse should result in all 1’s if the conversion time was calculated correctly.
	 *
	 * With VCC power supply the bus master may either send a reset pulse to exit the Convert command or
	 * continuously generate read data time slots. As long as the DS2450 is busy with conversions the bus
	 * master will read 0’s. After the conversion is completed the bus master will receive 1’s instead. Since in a
	 * open-drain environment a single 0 overwrites multiple 1’s the bus master can monitor multiple devices
	 * converting simultaneously and immediately knows when the last one is ready. As in the parasite
	 * powered scenario the bus master finally has to exit the Convert command by issuing a rest pulse.
	 *
	 * from data sheet: http://datasheets.maximintegrated.com/en/ds/DS2450.pdf
	 */

	while( trialsCounter < OWI_SEND_BYTE_MAX_TRIALS )
	{
		trialsCounter++;
        receive_CRC = 0;
    	result = RESULT_OK;

		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("bus_pattern: %#x sending command, mask, readout byte"),currentPins );
		/* select one or all, depending if id is given */
		if ( NULL == id)
		{
			/*
			 * SKIP ROM [CCH]
			 *
			 * This command can save time in a single drop bus system by allowing the bus master to access the
			 * memory/convert functions without providing the 64-bit ROM code. If more than one slave is present on
			 * the bus and a read command is issued following the Skip ROM command, data collision will occur on the
			 * bus as multiple slaves transmit simultaneously (open drain pulldowns will produce a wired-AND result).
			 */
			OWI_SkipRom(currentPins);

			result = owiSendBytesAndCheckCRC16(currentPins, 3,
					DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL);
			result = RESULT_OK; /*disable CRC check for skip rom*/
		}
		else
		{
			/*
			 * MATCH ROM [55H]
			 *
			 * The match ROM command, followed by a 64-bit ROM sequence, allows the bus master to address a
			 * specific DS2450 on a multidrop bus. Only the DS2450 that exactly matches the 64-bit ROM sequence
			 * will respond to the following memory/convert function command. All slaves that do not match the 64-bit
			 * ROM sequence will wait for a reset pulse. This command can be used with a single or multiple devices
			 * on the bus.
			 */
			OWI_MatchRom(id, currentPins); // Match id found earlier
			result = owiSendBytesAndCheckCRC16(currentPins, 3,
					DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL);
			result = RESULT_OK; /*disable CRC check for skip rom*/
		}

		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 3 bytes %#x ?"), owiComputeCRC16(0x0000, 3, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );
		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 4 bytes %#x ?"), owiComputeCRC16(0x0000, 4, OWI_ROM_SKIP, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );
		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 3 bytes %#x ?"), owiComputeCRC16(0xFFFF, 3, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );
		//		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("crc16 checksum 4 bytes %#x ?"), owiComputeCRC16(0xFFFF, 4, OWI_ROM_SKIP, DS2450_CONVERT, DS2450_CONVERSION_CHANNEL_SELECT_MASK, DS2450_CONVERSION_READOUT_CONTROL) );


		if ( RESULT_OK == result )
		{
			break;
		}
		else
		{
			if (OWI_SEND_BYTE_MAX_TRIALS != trialsCounter)
			{
				printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("CRC16 check send byte failed - trial no. %i, computed %#x != received %#x"), trialsCounter);

				/* ending the Convert command sequence in any case by issuing a Reset Pulse*/
				OWI_DetectPresence(currentPins); /*the "DetectPresence" function includes sending a Reset Pulse*/
				continue;
			}
			else
			{
				CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("CRC16 check reached max trials (%i) on send byte"), OWI_SEND_BYTE_MAX_TRIALS);
				result = RESULT_FAILURE;
				break;
			}
		}
	}

	//loop that waits for the conversion to be done
	if ( RESULT_OK == result )
	{
		result = RESULT_OK;
		while ( OWI_ReadBit(currentPins) == 0 )
		{
			_delay_ms(OWI_ADC_CONVERSION_DELAY_MILLISECONDS);

			/* timeout check */
			if ( 0 == --count)
			{
				timeout_flag = TRUE;
				result = RESULT_FAILURE;
				break;
			}
		}
		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("waited %i times a delay of %i ms"), maxcount - count, OWI_ADC_CONVERSION_DELAY_MILLISECONDS);

		/* ending the Convert command sequence in any case by issuing a Reset Pulse*/
		OWI_DetectPresence(currentPins); /*the "DetectPresence" function includes sending a Reset Pulse*/
	}

	/* post conversion status analysis*/
	if (RESULT_OK == result)
	{
		owiAdcTimeoutAndFailureBusMask &= ~(currentPins);
		result = RESULT_OK;
		printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("OWI ADC Conversion failed (bus_pattern: %#x)"), currentPins);
	}
	else
	{
		result = RESULT_FAILURE;

		if ( NULL == id )
		{
			owiAdcTimeoutAndFailureBusMask |= currentPins;
			if ( FALSE != timeout_flag )
			{
				CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion timeout (bus_pattern: %#x"), currentPins);
				printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("OWI Adc Conversion timeout (>%i ms) on bus_mask (%#x)"),  maxConversionTime, currentPins);
			}
			CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion failed (bus_pattern: %#x)"), currentPins);
		}
		else
		{
			owiCreateIdString(owi_id_string, id);
			if ( FALSE != timeout_flag )
			{
				CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion timeout (id: %s"), owi_id_string);
				printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("OWI Adc Conversion timeout (>%i ms) (id: %s)"),  maxConversionTime, owi_id_string);
			}
			CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI ADC Conversion failed (id: %s)"), owi_id_string);
		}
	}

	return result;
}