int8_t ow_eeprom_read(ow_rom_code_t *rom, void *data) { #if ONEWIRE_BUSCOUNT > 1 uint8_t busmask = 1 << (ONEWIRE_STARTPIN); // FIXME: currently only on 1st bus #else uint8_t busmask = ONEWIRE_BUSMASK; #endif int8_t ret; if (rom == NULL) ret = ow_skip_rom(); else { /* check for known family code */ if (!(rom->family == OW_FAMILY_DS2502E48)) return -2; ret = ow_match_rom(rom); } if (ret < 0) return ret; /* transmit command byte */ ow_write_byte(busmask, OW_FUNC_READ_MEMORY); /* transmit address (mac address starts at offset 5 */ ow_write_byte(busmask, 5); ow_write_byte(busmask, 0); /* read back crc sum of the command */ uint8_t crc = ow_read_byte(busmask); /* check crc */ uint8_t crc2 = 0; crc2 = _crc_ibutton_update(crc2, OW_FUNC_READ_MEMORY); crc2 = _crc_ibutton_update(crc2, 5); crc2 = _crc_ibutton_update(crc2, 0); if (crc != crc2) return -2; uint8_t *p = (uint8_t *)data+5; /* read 6 byte of data */ for (uint8_t i = 0; i < 6; i++) *p-- = ow_read_byte(busmask); return 0; }
static void ds18x20GetAllTemps() { uint8_t i, j; uint8_t crc; static uint8_t arr[DS18X20_SCRATCH_LEN]; for (i = 0; i < devCount; i++) { if (ds18x20IsOnBus()) { ds18x20Select(&devs[i]); ds18x20SendByte(DS18X20_CMD_READ_SCRATCH); // Control scratchpad checksum crc = 0; for (j = 0; j < DS18X20_SCRATCH_LEN; j++) { arr[j] = ds18x20GetByte(); crc = _crc_ibutton_update(crc, arr[j]); } if (crc == 0) { // Save first 2 bytes (temperature) of scratchpad for (j = 0; j < DS18X20_SCRATCH_TEMP_LEN; j++) devs[i].sp[j] = arr[j]; } } } return; }
/** * @brief Handles SPI for the motor set command. */ static void spis_cmd_motorset (void) { int16_t mota, motb; uint8_t c = SPDR; /* Still processing input. */ if (spis_pos < 4) { /* Fill buffer. */ spis_buf[ spis_pos++ ] = c; /* Echo recieved. */ SPDR = c; /* Update CRC. */ spis_crc = _crc_ibutton_update( spis_crc, c ); } /* Handle command. */ else { /* Check CRC. */ if (c != spis_crc) { SPIS_CMD_RESET(); LED0_ON(); return; } /* Prepare arguments. */ mota = (spis_buf[0]<<8) + spis_buf[1]; motb = (spis_buf[2]<<8) + spis_buf[3]; /* Set motor. */ motor_set( mota, motb ); /* Clear command. */ SPIS_CMD_RESET(); LED0_OFF(); } }
/** * @brief Handles SPI for the mode set command. */ static void spis_cmd_modeset (void) { uint8_t c = SPDR; if (spis_pos < 1) { /* Fill buffer. */ spis_buf[ spis_pos++ ] = c; /* Echo recieved. */ SPDR = c; /* Update CRC. */ spis_crc = _crc_ibutton_update( spis_crc, c ); } else { /* Check CRC. */ if (c != spis_crc) { SPIS_CMD_RESET(); LED0_ON(); return; } /* Set mode. */ motor_mode( spis_buf[0] ); /* Clear command. */ SPIS_CMD_RESET(); LED0_OFF(); } }
static uint8_t calc_crc8(uint8_t crc, const void * const data, uint8_t len) { while (len--) { crc = _crc_ibutton_update(crc, *(uint8_t *) (data + len)); // TODO } return crc; }
uint8_t one_wire_calc_crc(const void* data, one_wire_size_t size) { one_wire_size_t i = 0; uint8_t crc = 0; for(i = 0; i < size; i ++){ crc = _crc_ibutton_update(crc, ((const uint8_t*)data)[i]); } return crc; }
uint8_t onewire_read_temp (struct onewire_temp_sensor *sensor) //Temperatur eines DS18x20 auslesen und umrechnen { uint8_t spad[9]; uint8_t i; uint8_t crc = 0; float temp_f; //einzelnen Sensor ansprechen onewire_reset(); if (onewire_presence_pulse == 0) { return 0; } onewire_send_byte(match_rom); for (i=0; i<8; i++) { onewire_send_byte(sensor->rom[i]); } //Scratchpad auslesen onewire_send_byte(read_spad); for (i=0; i<9; i++) { spad[i] = onewire_read_byte(); } //CRC Check for (i=0; i<9; i++) { crc = _crc_ibutton_update(crc, spad[i]); } //Temperatur berechnen if (crc == 0) { //0,5°C Bit löschen spad[temperature_lsb] &= ~(1<<0); //Temperatur umrechnen if (spad[temperature_msb] == 0) { temp_f = spad[temperature_lsb]/2.0; } else { i = ~(spad[temperature_lsb]); temp_f = i+1; temp_f = (temp_f*(-1))/2.0; } //Nachkommaberechnung temp_f = temp_f-0.25+(16.0-spad[count_remain])/16.0; //Umrechnung, um Kommazahl als Int zu speichern und abspeichern sensor->temperature = temp_f*100; return 1; } return 0; }
/*! \brief return the crc8 of the string. * * \param str the string */ uint8_t crc8_str(const char *str) { uint8_t i, crc8; crc8 = 0; for (i=0; i<strlen(str); i++) crc8 = _crc_ibutton_update(crc8, *(str + i)); return(crc8); }
uint8_t ds18b20_check_crc(){ if(!ds18b20_reset()){ return 0; } ds18b20_write_byte(DS18B20_SKIP_ROM); ds18b20_write_byte(DS18B20_READ_SCRATCHPAD); uint8_t crc=0; for(int8_t i=0;i<9;i++){ _crc_ibutton_update(crc,ds18b20_read_byte()); } return !crc; }
/*Check crc for scratchpad data*/ uint8_t ds1820_crc_check(uint8_t *scratchpad){ uint8_t crc = 0; for(int i = 0; i < 8; i++) crc = _crc_ibutton_update(crc, scratchpad[i]); if(crc != scratchpad[8]){ return 1; } return 0; }
void PacketTransmit::setReceivedItem(unsigned char item) { if (syncstate==0) { if (item=='>') syncstate++; else syncstate=0; } else if (syncstate==1) { if (item=='*') syncstate++; else syncstate=0; } else if (syncstate==2) { if (item=='>') syncstate++; else syncstate=0; } else if (syncstate==3) { if ((read_index == 2) && (receive_length.value != read_size)) { read_index = 0; syncstate = 0; receive_crc_calc = 0; receive_error = true; } if (read_index < 2) { receive_length.part[read_index] = item; read_index++; } else if (read_index < (read_size + 2)) { *read_pointer = item; receive_crc_calc= _crc_ibutton_update(receive_crc_calc, item); read_index++; read_pointer++; } else if (read_index < (read_size + 4)) { receive_crc.part[read_index-read_size-2] = item; read_index++; } else if (read_index < (read_size + 6)) { if ((receive_length.value == read_size) && (receive_crc_calc == receive_crc.value)) { receive_error = false; data_available = true; } else { receive_error = true; } syncstate=0; receive_crc_calc = 0; } else { receive_error = true; syncstate=0; receive_crc_calc = 0; } } }
uint8_t xpcc::amnb::crcUpdate(uint8_t crc, uint8_t data) { #ifdef __AVR__ return _crc_ibutton_update(crc, data); #else crc = crc ^ data; for (uint_fast8_t i = 0; i < 8; ++i) { if (crc & 0x01) { crc = (crc >> 1) ^ 0x8C; } else {
uint8_t ds18b20_read_temp(double* temp, uint8_t prec){ if(!ds18b20_set_precision(prec)){ return 0; } if(!ds18b20_reset()){ return 0; } ds18b20_write_byte(DS18B20_SKIP_ROM); ds18b20_write_byte(DS18B20_CONVERT_T); // provide power SET_OUTPUT(DS18B20_DDR, DS18B20_DQ); SET_HIGH (DS18B20_PORT, DS18B20_DQ); for(int8_t i=0;i<(1<<prec);i++){ _delay_ms(93.75); } if(!ds18b20_reset()){ return 0; } ds18b20_write_byte(DS18B20_SKIP_ROM); ds18b20_write_byte(DS18B20_READ_SCRATCHPAD); uint8_t crc=0; uint8_t l=ds18b20_read_byte(); _crc_ibutton_update(crc,l); uint8_t h=ds18b20_read_byte(); _crc_ibutton_update(crc,h); for(int8_t i=0;i<7;i++){ _crc_ibutton_update(crc,ds18b20_read_byte()); } if(crc){ return 0; } int16_t t=(h<<8)+l; *temp=t*0.0625; return 1; }
int ds_search_rom(uint8_t *id, uint8_t mask) { uint8_t r, i, j; uint8_t crc, b1, b2; /* Reset the sensor(s) */ r = ds_reset(); if(r != DS_OK) return(r); /* Transmit the SEARCH ROM command */ ds_write_byte(0xF0); /* An ID is made up of 8 bytes (7 + CRC) */ for(crc = i = 0; i < 8; i++) { *id = 0; for(j = 0; j < 8; j++) { /* Read the bit and its complement */ b1 = ds_read_bit(); b2 = ds_read_bit(); /* Both bits should never be 1 */ if(b1 && b2) return(DS_ERROR); /* Both bits are 0 when two or more sensors * respond with a different value */ if(b1 == b2) { b1 = mask & 1; mask >>= 1; /* Test if this is the last ID on the bus */ if(!b1) r = DS_MORE; } /* Let the sensors know which direction we're going */ ds_write_bit(b1); *id >>= 1; if(b1) *id |= 1 << 7; } /* Update the CRC, compare with last byte */ if(i != 7) crc = _crc_ibutton_update(crc, *id); else if(crc != *id) return(DS_BADCRC); id++; }
static void spis_cmd_start (void) { uint8_t c = SPDR; /* Handle package start. */ if (spis_pos==0) { if (c == 0x80) spis_pos = 1; else { SPDR = 0; return; } } /* Handle command. */ else { switch (c) { case DHB_CMD_VERSION: spis_cmd_func = spis_cmd_version; break; case DHB_CMD_MODESET: spis_cmd_func = spis_cmd_modeset; break; case DHB_CMD_MOTORSET: spis_cmd_func = spis_cmd_motorset; break; case DHB_CMD_MOTORGET: sched_flags |= SCHED_SPIS_PREP_MOTORGET; spis_cmd_func = spis_cmd_motorget; break; case DHB_CMD_CURRENT: sched_flags |= SCHED_SPIS_PREP_CURRENT; spis_cmd_func = spis_cmd_current; break; default: SPIS_CMD_RESET(); LED0_ON(); return; } spis_pos = 0; spis_crc = _crc_ibutton_update( 0, c ); } /* Echo. */ SPDR = c; }
uint8_t crc_checksum(void *data, uint8_t length) /* {{{ */ { uint8_t crc = 0; uint8_t *p = (uint8_t *)data; for (uint8_t i = 0; i < length; i++) { crc = _crc_ibutton_update(crc, *p); p++; } return crc; } /* }}} */
uint8_t eeprom_get_chksum (void) { uint8_t eeprom_crc = 0; uint8_t *p = (uint8_t *) EEPROM_CONFIG_BASE; for (uint16_t i = 0; i < (sizeof (struct eeprom_config_t) - 1); i++) { eeprom_crc = _crc_ibutton_update (eeprom_crc, eeprom_read_byte (p)); p++; } return eeprom_crc; }
// Generate 'secure' new random byte. // This should be essentially all entropy and unguessable. // Likely to be slow and may force some peripheral I/O. // Runtime details are likely to be intimately dependent on hardware implementation. uint8_t getSecureRandomByte() { // Use various real noise sources and whiten with PRNG and other counters. // Mix the bits also to help ensure good distribution. uint8_t w1 = clockJitterEntropyByte(); // Real noise. w1 ^= (w1 << 4); // Mix. w1 ^= noisyADCRead(); // Real noise. w1 ^= (w1 >> 4); // Mix. const uint8_t v = w1; w1 ^= randRNG8(); // Whiten. w1 ^= (w1 << 3); // Mix. w1 ^= _crc_ibutton_update(cycleCountCPU() ^ (uint8_t)(intptr_t)&v, ++count8 - v); // Whiten. return(w1); }
// Generate 'secure' new random byte. // This should be essentially all entropy and unguessable. // Likely to be slow and may force some peripheral I/O. // Runtime details are likely to be intimately dependent on hardware implementation. // Not thread-/ISR- safe. // * whiten if true whiten the output a little more, but little or no extra entropy is added; // if false then it is easier to test if the underlying source provides new entropy reliably uint8_t getSecureRandomByte(const bool whiten) { #ifdef WAKEUP_32768HZ_XTAL // Use various real noise sources and whiten with PRNG and other counters. // Mix the bits also to help ensure good distribution. uint8_t w1 = clockJitterEntropyByte(); // Real noise. #else // WARNING: poor substitute if 32768Hz xtal not available. uint8_t w1 = clockJitterWDT() + (clockJitterWDT() << 5); w1 ^= (w1 << 1); // Mix. w1 ^= clockJitterWDT(); w1 ^= (w1 >> 2); // Mix. w1 ^= clockJitterWDT(); w1 ^= (w1 << 2); // Mix. w1 ^= clockJitterWDT(); w1 ^= (w1 >> 3); // Mix. w1 ^= clockJitterWDT(); w1 ^= (w1 << 4); // Mix. w1 ^= clockJitterWDT(); w1 ^= (w1 >> 1); // Mix. w1 ^= clockJitterWDT(); #endif const uint8_t v1 = w1; w1 ^= (w1 << 3); // Mix. w1 ^= noisyADCRead(true); // Some more real noise, possibly ~1 bit. w1 ^= (w1 << 4); // Mix. const uint8_t v2 = w1; w1 ^= clockJitterWDT(); // Possibly ~1 bit more of entropy. w1 ^= (w1 >> 4); // Mix. if(whiten) { w1 ^= randRNG8(); // Whiten. w1 ^= (w1 << 3); // Mix. w1 ^= _crc_ibutton_update(cycleCountCPU() ^ (uint8_t)(intptr_t)&v1, ++count8 - (uint8_t)(intptr_t)&v2); // Whiten. } w1 ^= _crc_ibutton_update(v1, v2); // Complex hash. return(w1); }
static void ds1820_read_scratchpad() { uint8_t i, crc; ds1820_reset(); ds1820_write(DS1820_CMD_SKIP_ROM); ds1820_write(DS1820_CMD_READ); crc = 0; for (i = 0; i < 9; i++) { ds1820[i] = ds1820_read(); crc = _crc_ibutton_update(crc, ds1820[i]); } /* only update temperature if CRC ok */ if (!crc) { temperature[0] = ds1820[0]; temperature[1] = ds1820[1]; } }
unsigned char PacketTransmit::getNextItem() { unsigned char startstring[]={'>','*','>'}; unsigned char return_value; if (write_index < 3) { return_value = startstring[write_index++]; } else if (write_index < 5) { return_value = transmit_length.part[(write_index-3)]; write_index++; } else if (write_index < (write_size + 5)) { transmit_crc.value = _crc_ibutton_update(transmit_crc.value, *write_pointer); return_value = *write_pointer; write_pointer++; write_index++; } else if (write_index < (write_size + 7)) { return_value = transmit_crc.part[write_index-write_size-5]; write_index++; } return return_value; }
uint8_t noisyADCRead(const bool /*powerUpIO*/) { const bool neededEnable = powerUpADCIfDisabled(); #ifndef IGNORE_POWERUPIO const bool poweredUpIO = powerUpIO; if(powerUpIO) { power_intermittent_peripherals_enable(false); } #endif // Sample supply voltage. ADMUX = _BV(REFS0) | 14; // Bandgap vs Vcc. ADCSRB = 0; // Enable free-running mode. bitWrite(ADCSRA, ADATE, 0); // Multiple samples NOT required. ADC_complete = false; bitSet(ADCSRA, ADIE); // Turn on ADC interrupt. bitSet(ADCSRA, ADSC); // Start conversion. uint8_t count = 0; while(!ADC_complete) { ++count; } // Busy wait while 'timing' the ADC conversion. const uint8_t l1 = ADCL; // Capture the low byte and latch the high byte. const uint8_t h1 = ADCH; // Capture the high byte. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR V: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(h1, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINTFMT(l1, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif // Sample internal temperature. ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); // Temp vs bandgap. ADC_complete = false; bitSet(ADCSRA, ADSC); // Start conversion. while(!ADC_complete) { ++count; } // Busy wait while 'timing' the ADC conversion. const uint8_t l2 = ADCL; // Capture the low byte and latch the high byte. const uint8_t h2 = ADCH; // Capture the high byte. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR T: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(h2, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINTFMT(l2, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif uint8_t result = (h1 << 5) ^ (l2) ^ (h2 << 3) ^ count; #if defined(CATCH_OTHER_NOISE_DURING_NAR) result = _crc_ibutton_update(_adcNoise++, result); #endif // Sample all possible ADC inputs relative to Vcc, whatever the inputs may be connected to. // Assumed never to do any harm, eg physical damage, nor to disturb I/O setup. for(uint8_t i = 0; i < 8; ++i) { ADMUX = (i & 7) | (DEFAULT << 6); // Switching MUX after sample has started may add further noise. ADC_complete = false; bitSet(ADCSRA, ADSC); // Start conversion. while(!ADC_complete) { ++count; } const uint8_t l = ADCL; // Capture the low byte and latch the high byte. const uint8_t h = ADCH; // Capture the high byte. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR M: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(h, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINTFMT(l, HEX); V0P2BASE_DEBUG_SERIAL_PRINT(' '); V0P2BASE_DEBUG_SERIAL_PRINT(count); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif result = _crc_ibutton_update(result ^ h, l ^ count); // A thorough hash. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR R: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(result, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif } bitClear(ADCSRA, ADIE); // Turn off ADC interrupt. bitClear(ADCSRA, ADATE); // Turn off ADC auto-trigger. #ifndef IGNORE_POWERUPIO if(poweredUpIO) { power_intermittent_peripherals_disable(); } #endif if(neededEnable) { powerDownADC(); } result ^= l1; // Ensure that the Vcc raw lsbs get directly folded in to the final result. #if 0 && defined(V0P2BASE_DEBUG) V0P2BASE_DEBUG_SERIAL_PRINT_FLASHSTRING("NAR: "); V0P2BASE_DEBUG_SERIAL_PRINTFMT(result, HEX); V0P2BASE_DEBUG_SERIAL_PRINTLN(); #endif return(result); // Use all the bits collected. }
static PT_THREAD(read_temp(struct pt *pt, const ow_addr_t *addr)) { int err; uint8_t scratch[9]; uint8_t crc = 0; PT_BEGIN(pt); // Reset the bus err = ow_reset(); if (err != 1) { shell_output_P(&owtest_command, PSTR("Reset failed.\n")); PT_EXIT(pt); } // Match ROM err = ow_write_byte(0x55); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(*addr); i++) { err = ow_write_byte(addr->u[i]); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } } // Start temperature conversion err = ow_write_byte(0x44); if (err) { shell_output_P(&owtest_command, PSTR("Convert T failed\n")); PT_EXIT(pt); } // Conversion timeout timer_set(&timeout, DS18B20_CONV_TIMEOUT); while (1) { _delay_ms(10); // for good measure // Read a bit from the bus int ret = ow_read_bit(); // Check for stop conditions if (ret == 1) { break; } else if (ret == -1) { shell_output_P(&owtest_command, PSTR("Read status failed.\n")); PT_EXIT(pt); } else if (timer_expired(&timeout)) { shell_output_P(&owtest_command, PSTR("Conversion has taken too long. Giving up.\n")); PT_EXIT(pt); } // Poll the process and yield the thread process_poll(&shell_owtest_process); PT_YIELD(pt); } // Reset and MATCH ROM again err = ow_reset(); if (err != 1) { shell_output_P(&owtest_command, PSTR("Reset failed.\n")); PT_EXIT(pt); } // Match ROM err = ow_write_byte(0x55); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(*addr); i++) { err = ow_write_byte(addr->u[i]); if (err) { shell_output_P(&owtest_command, PSTR("Match ROM failed\n")); PT_EXIT(pt); } } // Read the scratch pad err = ow_write_byte(0xBE); if (err) { shell_output_P(&owtest_command, PSTR("Read scratch pad failed\n")); PT_EXIT(pt); } for (int i = 0; i < sizeof(scratch); i++) { err = ow_read_byte(); if (err < 0) { shell_output_P(&owtest_command, PSTR("Read byte failed\n")); PT_EXIT(pt); } scratch[i] = err; crc = _crc_ibutton_update(crc, scratch[i]); } // Make sure the CRC is valid if (crc) { shell_output_P(&owtest_command, PSTR("CRC check failed!\n")); PT_EXIT(pt); } // Convert temperature to floating point int16_t rawtemp = scratch[0] | (scratch[1] << 8); float temp = (float)rawtemp * 0.0625; shell_output_P(&owtest_command, PSTR("Scratchpad: %02x%02x %02x%02x %02x %02x%02x%02x %02x\n"), scratch[0], scratch[1], // temperature scratch[2], scratch[3], // TH,TL alarm thresholds scratch[4], // config scratch[5], scratch[6], scratch[7], // reserved scratch[8]); // CRC shell_output_P(&owtest_command, PSTR("Reading: %0.2fC\n"), temp); PT_END(pt); }
uint8_t dallas(char *pData_Dallas, uint8_t command){ cli(); DALLAS_PORT&=~DALLAS; RESET //Output Reset. DALLAS_PORT|=DALLAS; //Delay input Presence.// for(uint16_t i=0; i<DELAY_PRESENCE; i++) { if(!(DALLAS_PIN & (DALLAS))) { for(uint8_t t0=0; t0<PAUSE; t0++); //PAUSE// //Output command// for (uint8_t t0=0; t0<8; t0++) { if(command & (1<<t0)) { DALLAS_PORT&=~DALLAS; ONE_COMMAND DALLAS_PORT|=DALLAS; ZERO_COMMAND } else { DALLAS_PORT&=~DALLAS; ZERO_COMMAND DALLAS_PORT|=DALLAS; ONE_COMMAND } } DALLAS_PORT|=DALLAS; //Dalas in HIGH. for(uint8_t t2=0; t2<DELAY_ONE; t2++) { asm volatile ("nop"); if(!(DALLAS_PIN & (DALLAS))) bit++; } DALLAS_PORT&=~DALLAS; //Dalas in LOW. for(uint8_t t2=0; t2<DELAY_ZERO; t2++) asm volatile ("nop"); //Read code// for(uint8_t t0=0; t0<8; t0++) { for(uint8_t t1=0; t1<8; t1++) { DALLAS_PORT|=DALLAS; //Dalas in HIGH. for(uint8_t t2=0; t2<DELAY_ONE; t2++) { asm volatile ("nop"); if(!(DALLAS_PIN & (DALLAS))) bit++; } DALLAS_PORT&=~DALLAS; //Dalas in LOW. for(uint8_t t2=0; t2<DELAY_ZERO; t2++) asm volatile ("nop"); if(bit>ONE) { pData_Dallas[t0]&=~(1<<t1); //0 } else { pData_Dallas[t0]|=(1<<t1); //1 } bit=0; } } uint8_t crc = 0; uint8_t data_temp[8]; for (uint8_t t2=0; t2<8; t2++) data_temp[t2]=pData_Dallas[t2]; for (uint8_t t2=0; t2<7; t2++) crc = _crc_ibutton_update(crc, data_temp[t2]); if(crc==pData_Dallas[7]) { for (uint8_t t2=0; t2<8; t2++) if(pData_Dallas[t2]!=0x00) return 0; return 3; } else { return 2; } }