// Wait max time needed for reset static RESET_TYPE K1WM_wait_for_reset( struct connection_in * in ) { LEVEL_DEBUG("[%s]", __FUNCTION__); long int t_reset = in->overdrive ? (74000+63000) : (636000+626000) ; // nsec uint8_t interrupt ; struct timespec t = { 0, t_reset, } ; if ( nanosleep( & t, NULL ) != 0 ) { return gbBAD ; } interrupt = DS1WM_interrupt(in) ; if ( UT_getbit( &interrupt, e_ds1wm_pd ) == 0 ) { LEVEL_DEBUG("[%s] presence_detect bit == 0", __FUNCTION__); return BUS_RESET_ERROR ; } if ( UT_getbit( &interrupt, e_ds1wm_ow_short ) == 1 ) { LEVEL_DEBUG("[%s] short bit == 1", __FUNCTION__); return BUS_RESET_SHORT ; } in->AnyDevices = ( UT_getbit( &interrupt, e_ds1wm_pdr ) == 0 ) ? anydevices_yes : anydevices_no ; LEVEL_DEBUG("[%s] in->AnyDevices == %i", __FUNCTION__, in->AnyDevices); return BUS_RESET_OK ; }
static int FindDiscrepancy(BYTE * last_sn, BYTE * discrepancy_sn) { int i; for (i = 63; i >= 0; i--) { if ((UT_getbit(discrepancy_sn, i) != 0) && (UT_getbit(last_sn, i) == 0)) { return i; } } return 0; }
/* From registers 0x8B-0x8D */ static ZERO_OR_ERROR FS_r_s_alarm(struct one_wire_query *owq) { BYTE d[6]; int i, p; UINT U; RETURN_ERROR_IF_BAD( OW_r_reg(d, PN(owq)) ); /* register 0x8D */ U = (d[5] & 0x03) * 100000000; /* registers 0x8B and 0x8C */ for (i = 0, p = 1; i < 8; ++i, p *= 10) { U += UT_getbit(&d[3], i) | (UT_getbit(&d[4], i) << 1) * p; } OWQ_U(owq) = U; return 0; }
static GOOD_OR_BAD K1WM_wait_for_write( const struct connection_in * in ) { int i ; if ( UT_getbit( &DS1WM_interrupt(in), e_ds1wm_tbe ) == 1 ) { return gbGOOD ; } for ( i=0 ; i < 5 ; ++i ) { RETURN_BAD_IF_BAD( K1WM_wait_for_byte(in) ) ; if ( UT_getbit( &DS1WM_interrupt(in), e_ds1wm_tbe ) == 1 ) { return gbGOOD ; } } return gbBAD ; }
static ZERO_OR_ERROR FS_r_por(struct one_wire_query *owq) { BYTE data[6]; RETURN_ERROR_IF_BAD( OW_r_reg(data, PN(owq)) ); OWQ_Y(owq) = UT_getbit(&data[5], 3); return 0; }
// Wait max time needed for reset static RESET_TYPE DS1WM_wait_for_reset( struct connection_in * in ) { long int t_reset = in->overdrive ? (74000+63000) : (636000+626000) ; // nsec uint8_t interrupt ; struct timespec t = { 0, t_reset, } ; if ( nanosleep( & t, NULL ) != 0 ) { return gbBAD ; } interrupt = DS1WM_interrupt(in) ; if ( UT_getbit( &interrupt, e_ds1wm_pd ) == 0 ) { return BUS_RESET_ERROR ; } if ( UT_getbit( &interrupt, e_ds1wm_ow_short ) == 1 ) { return BUS_RESET_SHORT ; } in->AnyDevices = ( UT_getbit( &interrupt, e_ds1wm_pdr ) == 0 ) ? anydevices_yes : anydevices_no ; return BUS_RESET_OK ; }
// handles: BYTE static ZERO_OR_ERROR FS_write_as_bits( struct one_wire_query *owq_byte ) { struct one_wire_query * owq_bit = OWQ_create_separate( 0, owq_byte ) ; size_t elements = OWQ_pn(owq_byte).selected_filetype->ag->elements; size_t extension ; ZERO_OR_ERROR z_or_e = 0 ; if ( owq_bit == NO_ONE_WIRE_QUERY ) { return -ENOENT ; } for ( extension = 0 ; extension < elements ; ++extension ) { ZERO_OR_ERROR z ; OWQ_pn(owq_bit).extension = extension ; OWQ_Y(owq_bit) = UT_getbit( (BYTE *) &OWQ_U(owq_byte), extension ) ; z = FS_write_owq( owq_bit ) ; if ( z != 0 ) { z_or_e = z ; } } OWQ_destroy( owq_bit ) ; return z_or_e ; }
/* search = normal and alarm */ static enum search_status K1WM_next_both(struct device_search *ds, const struct parsedname *pn) { LEVEL_DEBUG("[%s] BUS search", __FUNCTION__); int mismatched; BYTE sn[SERIAL_NUMBER_SIZE]; BYTE bitpairs[SERIAL_NUMBER_SIZE*2]; BYTE dummy ; struct connection_in * in = pn->selected_connection ; int i; LEVEL_DEBUG("[%s] ds->LastDevice == true ?", __FUNCTION__); if (ds->LastDevice) { LEVEL_DEBUG("[%s] ds->LastDevice == true -> search_done", __FUNCTION__); return search_done; } LEVEL_DEBUG("[%s] BUS_select failed ?", __FUNCTION__); if ( BAD( BUS_select(pn) ) ) { LEVEL_DEBUG("[%s] BUS_select failed -> search_error", __FUNCTION__); return search_error; } // Standard SEARCH ROM using SRA // need the reset done in BUS-select to set AnyDevices if ( in->AnyDevices == anydevices_no ) { LEVEL_DEBUG("[%s] in->AnyDevices == anydevices_no -> search_done", __FUNCTION__); ds->LastDevice = 1; return search_done; } // clear sn to satisfy static error checking (Coverity) memset( sn, 0, SERIAL_NUMBER_SIZE ) ; // build the command stream // call a function that may add the change mode command to the buff // check if correct mode // issue the search command // change back to command mode // search mode on // change back to data mode // set the temp Last Descrep to none mismatched = -1; // add the 16 bytes of the search memset(bitpairs, 0, SERIAL_NUMBER_SIZE*2); LEVEL_DEBUG("[%s] ds->LastDiscrepancy == %i", __FUNCTION__, ds->LastDiscrepancy); // set the bits in the added buffer for (i = 0; i < ds->LastDiscrepancy; i++) { // before last discrepancy UT_set2bit(bitpairs, i, UT_getbit(ds->sn, i) << 1); } // at last discrepancy if (ds->LastDiscrepancy > -1) { UT_set2bit(bitpairs, ds->LastDiscrepancy, 1 << 1); } // after last discrepancy so leave zeros // search ON // Send search rom or conditional search byte if ( BAD( K1WM_sendback_byte(&(ds->search), &dummy, in) ) ) { LEVEL_DEBUG("[%s] Sending SearchROM/SearchByte '0x%x' failed -> search_error", __FUNCTION__, ds->search); return search_error; } // Set search accelerator UT_setbit( &DS1WM_command(in), e_ds1wm_sra, 1 ) ; // send the packet // cannot use single-bit mode with search accerator // search OFF if ( BAD( K1WM_sendback_data(bitpairs, bitpairs, SERIAL_NUMBER_SIZE*2, pn) ) ) { LEVEL_DEBUG("[%s] Sending the packet (bitpairs) failed -> search_error", __FUNCTION__); return search_error; } // Turn off search accelerator UT_setbit( &DS1WM_command(in), e_ds1wm_sra, 0 ) ; // interpret the bit stream for (i = 0; i < SERIAL_NUMBER_BITS; i++) { // get the SerialNum bit UT_setbit(sn, i, UT_get2bit(bitpairs, i) >> 1); // check LastDiscrepancy if (UT_get2bit(bitpairs, i) == SEARCH_BIT_ON ) { mismatched = i; } } if ( sn[0]==0xFF && sn[1]==0xFF && sn[2]==0xFF && sn[3]==0xFF && sn[4]==0xFF && sn[5]==0xFF && sn[6]==0xFF && sn[7]==0xFF ) { // special case for no alarm present LEVEL_DEBUG("[%s] sn == 0xFFFFFFFFFFFFFFFF -> search_error", __FUNCTION__); return search_done ; } // CRC check if (CRC8(sn, SERIAL_NUMBER_SIZE) || (ds->LastDiscrepancy == SERIAL_NUMBER_BITS-1) || (sn[0] == 0)) { LEVEL_DEBUG("[%s] CRC check failed -> search_error", __FUNCTION__); return search_error; } // successful search // check for last one if ((mismatched == ds->LastDiscrepancy) || (mismatched == -1)) { ds->LastDevice = 1; } // copy the SerialNum to the buffer memcpy(ds->sn, sn, 8); // set the count ds->LastDiscrepancy = mismatched; LEVEL_DEBUG("SN found: " SNformat, SNvar(ds->sn)); return search_good; }
/* uses the "Triple" primative for faster search */ static enum search_status DS2482_next_both(struct device_search *ds, const struct parsedname *pn) { int search_direction = 0; /* initialization just to forestall incorrect compiler warning */ int bit_number; int last_zero = -1; FILE_DESCRIPTOR_OR_ERROR file_descriptor = pn->selected_connection->pown->file_descriptor; BYTE bits[3]; // initialize for search // if the last call was not the last one if (ds->LastDevice) { return search_done; } if ( BAD( BUS_select(pn) ) ) { return search_error ; } // need the reset done in BUS-select to set AnyDevices if ( pn->selected_connection->AnyDevices == anydevices_no ) { ds->LastDevice = 1; return search_done; } /* Make sure we're using the correct channel */ /* Appropriate search command */ if ( BAD(BUS_send_data(&(ds->search), 1, pn)) ) { return search_error; } // loop to do the search for (bit_number = 0; bit_number < 64; ++bit_number) { LEVEL_DEBUG("bit number %d", bit_number); /* Set the direction bit */ if (bit_number < ds->LastDiscrepancy) { search_direction = UT_getbit(ds->sn, bit_number); } else { search_direction = (bit_number == ds->LastDiscrepancy) ? 1 : 0; } /* Appropriate search command */ if ( BAD( DS2482_triple(bits, search_direction, file_descriptor) ) ) { return search_error; } if (bits[0] || bits[1] || bits[2]) { if (bits[0] && bits[1]) { /* 1,1 */ /* No devices respond */ ds->LastDevice = 1; return search_done; } } else { /* 0,0,0 */ last_zero = bit_number; } UT_setbit(ds->sn, bit_number, bits[2]); } // loop until through serial number bits if (CRC8(ds->sn, SERIAL_NUMBER_SIZE) || (bit_number < 64) || (ds->sn[0] == 0)) { /* Unsuccessful search or error -- possibly a device suddenly added */ return search_error; } // if the search was successful then ds->LastDiscrepancy = last_zero; ds->LastDevice = (last_zero < 0); LEVEL_DEBUG("SN found: " SNformat "", SNvar(ds->sn)); return search_good; }
/* Not used by more advanced adapters */ enum search_status BUS_next_both_bitbang(struct device_search *ds, const struct parsedname *pn) { if ( BAD( BUS_select(pn) ) ) { return search_error ; } else { int search_direction = 0; /* initialization just to forestall incorrect compiler warning */ int bit_number; int last_zero = -1; BYTE bits[3]; // initialize for search // if the last call was not the last one if (ds->LastDevice) { return search_done; } /* Appropriate search command */ if ( BAD( BUS_send_data(&(ds->search), 1, pn)) ) { return search_error ; } // Need data from a reset for AnyDevices -- obtained from BUS_data_send above if (pn->selected_connection->AnyDevices == anydevices_no) { ds->LastDevice = 1; return search_done; } // loop to do the search for (bit_number = 0;; ++bit_number) { bits[1] = bits[2] = 0xFF; if (bit_number == 0) { /* First bit */ /* get two bits (AND'ed bit and AND'ed complement) */ if ( BAD( BUS_sendback_bits(&bits[1], &bits[1], 2, pn) ) ) { return search_error; } } else { bits[0] = search_direction; if (bit_number < 64) { /* Send chosen bit path, then check match on next two */ if ( BAD( BUS_sendback_bits(bits, bits, 3, pn) ) ) { return search_error; } } else { /* last bit */ if ( BAD( BUS_sendback_bits(bits, bits, 1, pn) ) ) { return search_error; } break; } } if (bits[1]) { if (bits[2]) { /* 1,1 */ /* No devices respond */ ds->LastDevice = 1; return search_done; } else { /* 1,0 */ search_direction = 1; // bit write value for search } } else if (bits[2]) { /* 0,1 */ search_direction = 0; // bit write value for search } else if (bit_number > ds->LastDiscrepancy) { /* 0,0 looking for last discrepancy in this new branch */ // Past branch, select zeros for now search_direction = 0; last_zero = bit_number; } else if (bit_number == ds->LastDiscrepancy) { /* 0,0 -- new branch */ // at branch (again), select 1 this time search_direction = 1; // if equal to last pick 1, if not then pick 0 } else if (UT_getbit(ds->sn, bit_number)) { /* 0,0 -- old news, use previous "1" bit */ // this discrepancy is before the Last Discrepancy search_direction = 1; } else { /* 0,0 -- old news, use previous "0" bit */ // this discrepancy is before the Last Discrepancy search_direction = 0; last_zero = bit_number; } UT_setbit(ds->sn, bit_number, search_direction); } // loop until through serial number bits if ( (CRC8(ds->sn, SERIAL_NUMBER_SIZE)!=0) || (bit_number < 64) || (ds->sn[0] == 0)) { /* A minor "error" */ return search_error; } // if the search was successful then ds->LastDiscrepancy = last_zero; // printf("Post, lastdiscrep=%d\n",si->LastDiscrepancy) ; ds->LastDevice = (last_zero < 0); return search_good; } }