uint8_t ow_reset(void) { uint8_t err; OW_OUT_LOW(); OW_DIR_OUT(); // pull OW-Pin low for 480us _delay_us(480); ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // set Pin as input - wait for clients to pull low OW_DIR_IN(); // input #if OW_USE_INTERNAL_PULLUP OW_OUT_HIGH(); #endif _delay_us(64); // was 66 err = OW_GET_IN(); // no presence detect // if err!=0: nobody pulled to low, still high } // after a delay the clients should release the line // and input-pin gets back to high by pull-up-resistor _delay_us(480 - 64); // was 480-66 if ( OW_GET_IN() == 0 ) { err = 1; // short circuit, expected low but got high } return err; }
uint8_t ow_reset(void) { uint8_t err; uint8_t sreg; OW_OUT_LOW(); // disable internal pull-up (maybe on from parasite) OW_DIR_OUT(); // pull OW-Pin low for 480us _delay_us(480); sreg=SREG; cli(); // set Pin as input - wait for clients to pull low OW_DIR_IN(); // input _delay_us(66); err = OW_GET_IN(); // no presence detect // nobody pulled to low, still high SREG=sreg; // sei() // after a delay the clients should release the line // and input-pin gets back to high due to pull-up-resistor _delay_us(480-66); if( OW_GET_IN() == 0 ) // short circuit err = 1; return err; }
/* Timing issue when using runtime-bus-selection (!OW_ONE_BUS): The master should sample at the end of the 15-slot after initiating the read-time-slot. The variable bus-settings need more cycles than the constant ones so the delays had to be shortened to achive a 15uS overall delay Setting/clearing a bit in I/O Register needs 1 cyle in OW_ONE_BUS but around 14 cyles in configureable bus (us-Delay is 4 cyles per uS) */ uint8_t ow_bit_io( uint8_t b ) { uint8_t sreg; sreg=SREG; cli(); OW_DIR_OUT(); // drive bus low _delay_us(2); // Recovery-Time wuffwuff was 1 // normal 6 us if ( b ) OW_DIR_IN(); // if bit is 1 set bus high (by ext. pull-up) // wuffwuff delay was 15uS-1 see comment above _delay_us(15-2-OW_CONF_DELAYOFFSET); if( OW_GET_IN() == 0 ) b = 0; // sample at end of read-timeslot _delay_us(60-15); OW_DIR_IN(); SREG=sreg; // sei(); _delay_us(10); // bei langen Kabeln kann dieser Wert wohl auch um einiges größer sein! (recovery time) return b; }
/* Timing issue when using runtime-bus-selection (!OW_ONE_BUS): The master should sample at the end of the 15-slot after initiating the read-time-slot. The variable bus-settings need more cycles than the constant ones so the delays had to be shortened to achive a 15uS overall delay Setting/clearing a bit in I/O Register needs 1 cyle in OW_ONE_BUS but around 14 cyles in configureable bus (us-Delay is 4 cyles per uS) */ uint8_t ow_bit_io( uint8_t b ) { uint8_t sreg; sreg=SREG; cli(); OW_DIR_OUT(); // drive bus low _delay_us(1); // Recovery-Time wuffwuff was 1 if ( b ) OW_DIR_IN(); // if bit is 1 set bus high (by ext. pull-up) // wuffwuff delay was 15uS-1 see comment above //_delay_us(15-1-OW_CONF_DELAYOFFSET); _delay_us(15); if( OW_GET_IN() == 0 ) b = 0; // sample at end of read-timeslot _delay_us(60-15); OW_DIR_IN(); SREG=sreg; // sei(); return b; }
/****************************************************************** Timing issue when using runtime-bus-selection (!OW_ONE_BUS): The master should sample at the end of the 15-slot after initiating the read-time-slot. The variable bus-settings need more cycles than the constant ones so the delays had to be shortened to achive a 15uS overall delay Setting/clearing a bit in I/O Register needs 1 cyle in OW_ONE_BUS but around 14 cyles in configureable bus (us-Delay is 4 cyles per uS) *********************************************************************/ uint8_t ow_bit_io( uint8_t b ) { uint8_t sreg; sreg=SREG; /*TRY it*/// CLI(); OW_DIR_OUT(); /* drive bus low*/ // delay_us(1); /* Recovery-Time wuffwuff was 1*/ usecsleep(1,1); //timer1_Delay(1); if ( b ) OW_DIR_IN(); /* if bit is 1 set bus high (by ext. pull-up)*/ /* wuffwuff delay was 15uS-1 see comment above*/ // delay_us(15-1-OW_CONF_DELAYOFFSET); usecsleep(1,15-1-OW_CONF_DELAYOFFSET); //timer1_Delay(15-1-OW_CONF_DELAYOFFSET); if( OW_GET_IN() == 0 ) b = 0; /* sample at end of read-timeslot*/ // delay_us(60-15); usecsleep(1,60-15); //timer1_Delay(60-15); OW_DIR_IN(); /*TRY it*///SREG=sreg; /* sei();*/ SEI(); return b; }
/********************************* *RESET -*********************************/ uint8_t ow_reset(void) { uint8_t err; uint8_t sreg; OW_OUT_LOW(); // disable internal pull-up (maybe on from parasite) OW_DIR_OUT(); // pull OW-Pin low for 480us // delay_us(480); usecsleep(2,240); //timer1_Delay(480); sreg=SREG; /*TRY it*/// CLI(); /* set Pin as input - wait for clients to pull low*/ OW_DIR_IN(); /* input*/ // delay_us(66); usecsleep(2,33); //timer1_Delay(480); err = OW_GET_IN(); /* no presence detect*/ /* nobody pulled to low, still high*/ /*TRY it*///SREG=sreg; /* SEI(); /* after a delay the clients should release the line and input-pin gets back to high due to pull-up-resistor*/ // delay_us(480-66); usecsleep(2,207); //timer1_Delay(480-66); if( OW_GET_IN() == 0 )/* short circuit*/ err = 1; return err; }
void ow_write_bit(uint8_t bit) { cli(); if (bit) { // Write '1' bit OW_DIR_OUT(); // drive bus low _delay_us(6); OW_DIR_IN(); _delay_us(64); // Complete the time slot and 10us recovery } else { // Write '0' bit OW_DIR_OUT(); // drive bus low _delay_us(60); OW_DIR_IN(); _delay_us(10); } sei(); }
uint8_t ow_read_bit() { cli(); int result; OW_DIR_OUT(); // drive bus low _delay_us(6); OW_DIR_IN(); _delay_us(6); //Recommended values say 9 if( OW_GET_IN() == 0 ) result = 0; else result=1; // sample at end of read-timeslot (Reading only possible with high bit) _delay_us(58); // Complete the time slot and 10us recovery sei(); return result; }
/* Timing issue when using runtime-bus-selection (!OW_ONE_BUS): The master should sample at the end of the 15-slot after initiating the read-time-slot. The variable bus-settings need more cycles than the constant ones so the delays had to be shortened to achive a 15uS overall delay Setting/clearing a bit in I/O Register needs 1 cyle in OW_ONE_BUS but around 14 cyles in configureable bus (us-Delay is 4 cyles per uS) */ static uint8_t ow_bit_io_intern( uint8_t b, uint8_t with_parasite_enable ) { /*ATOMIC_BLOCK(ATOMIC_RESTORESTATE) */{ #if OW_USE_INTERNAL_PULLUP OW_OUT_LOW(); #endif OW_DIR_OUT(); // drive bus low _delay_us(2); // T_INT > 1usec accoding to timing-diagramm if ( b ) { OW_DIR_IN(); // to write "1" release bus, resistor pulls high #if OW_USE_INTERNAL_PULLUP OW_OUT_HIGH(); #endif } // "Output data from the DS18B20 is valid for 15usec after the falling // edge that initiated the read time slot. Therefore, the master must // release the bus and then sample the bus state within 15ussec from // the start of the slot." _delay_us(15-2-OW_CONF_DELAYOFFSET); if( OW_GET_IN() == 0 ) { b = 0; // sample at end of read-timeslot } _delay_us(60-15-2+OW_CONF_DELAYOFFSET); #if OW_USE_INTERNAL_PULLUP OW_OUT_HIGH(); #endif OW_DIR_IN(); if ( with_parasite_enable ) { ow_parasite_enable(); } } /* ATOMIC_BLOCK */ _delay_us(OW_RECOVERY_TIME); // may be increased for longer wires return b; }
void ow_parasite_enable(void) { OW_OUT_HIGH(); OW_DIR_OUT(); }