예제 #1
0
파일: ow_k1wm.c 프로젝트: M-o-a-T/owfs
// 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 ;
}
예제 #2
0
파일: ow_ds9490.c 프로젝트: M-o-a-T/owfs
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;
}
예제 #3
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;
}
예제 #4
0
파일: ow_k1wm.c 프로젝트: M-o-a-T/owfs
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 ;
}
예제 #5
0
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;
}
예제 #6
0
파일: ow_ds1wm.c 프로젝트: M-o-a-T/owfs
// 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 ;
}
예제 #7
0
// 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 ;
}
예제 #8
0
파일: ow_k1wm.c 프로젝트: M-o-a-T/owfs
/* 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;
}
예제 #9
0
/* 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;
}
예제 #10
0
/* 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;
	}
}