Пример #1
0
//--------------------------------------------------------------------------
// Send 1 bit of communication to the 1-Wire Net and verify that the
// bit read from the 1-Wire Net is the same (write operation).
// Delay delay msec and return to normal
//
static GOOD_OR_BAD DS1WM_PowerBit(const BYTE byte, BYTE * resp, const UINT delay, const struct parsedname *pn)
{
	GOOD_OR_BAD ret = gbBAD ; // default
	struct connection_in * in = pn->selected_connection ;
	uint8_t control_register ;
	
	// Set power, bitmode on
	control_register = DS1WM_control(in) ;
	UT_setbit( &control_register,e_ds1wm_stp_sply, 1 ) ;
	UT_setbit( &control_register,e_ds1wm_bit_ctl, 1 ) ;
	in->master.ds1wm.byte_mode = 0 ;
	DS1WM_control(in) = control_register ;

	if ( GOOD( DS1WM_sendback_byte( &byte, resp, in ) ) && GOOD( DS1WM_wait_for_write(in) ) ) {
		UT_delay(delay);
		ret = gbGOOD ;
	}

	// Set power, bitmode off
	control_register = DS1WM_control(in) ;
	UT_setbit( &control_register,e_ds1wm_stp_sply, 0 ) ;
	UT_setbit( &control_register,e_ds1wm_bit_ctl, 0 ) ;
	in->master.ds1wm.byte_mode = 1 ;
	DS1WM_control(in) = control_register ;

	return ret ;
}
Пример #2
0
//--------------------------------------------------------------------------
// Reset all of the devices on the 1-Wire Net and return the result.
//
//          This routine will not function correctly on some
//          Alarm reset types of the DS1994/DS1427/DS2404 with
//          Rev 1,2, and 3 of the DS2480/DS2480B.
static RESET_TYPE K1WM_reset(const struct parsedname * pn)
{
	LEVEL_DEBUG("[%s] BUS reset", __FUNCTION__);
	struct connection_in * in = pn->selected_connection ; 
	if ( in->changed_bus_settings != 0) {
		in->changed_bus_settings = 0 ;
		K1WM_setup(in);	// reset paramters
	}

	// select channel
	K1WM_select_channel(in, in->master.ds1wm.active_channel);

	// read interrupt register to clear all bits
	(void) DS1WM_interrupt(in);

	UT_setbit( &DS1WM_command(in), e_ds1wm_1wr, 1 ) ;
	
	switch( K1WM_wait_for_reset(in) ) {
		case BUS_RESET_SHORT:
			return BUS_RESET_SHORT ;
		case BUS_RESET_OK:
			return BUS_RESET_OK ;
		default:
			return K1WM_wait_for_reset(in) ;
	}
}
Пример #3
0
static void SetupDiscrepancy(const struct device_search *ds, BYTE * discrepancy)
{
	int i;

	/** Play LastDescrepancy games with bitstream */
	memcpy(discrepancy, ds->sn, SERIAL_NUMBER_SIZE);	/* set buffer to zeros */

	if (ds->LastDiscrepancy > -1) {
		UT_setbit(discrepancy, ds->LastDiscrepancy, 1);
	}

	/* This could be more efficiently done than bit-setting, but probably wouldn't make a difference */
	for (i = ds->LastDiscrepancy + 1; i < 64; i++) {
		UT_setbit(discrepancy, i, 0);
	}
}
Пример #4
0
static ZERO_OR_ERROR FS_w_por(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	BYTE data[6];
	RETURN_ERROR_IF_BAD( OW_r_reg(data, pn) );
	UT_setbit(&data[5], 3, OWQ_Y(owq));
	return GB_to_Z_OR_E( OW_w_control(data[5], pn) ) ;
}
Пример #5
0
// set control pins and frequency for defauts and global settings 
static GOOD_OR_BAD K1WM_setup( struct connection_in * in )
{
	uint8_t control_register = DS1WM_control(in) ;
	LEVEL_DEBUG("[%s] control_register before setup: 0x%x", __FUNCTION__, control_register);

	// Set to channel
	K1WM_channel(in) = in->master.ds1wm.active_channel ;

	// set some defaults:
	UT_setbit( &control_register, e_ds1wm_ppm, in->master.ds1wm.presence_mask ) ; // pulse presence masked
	UT_setbit( &control_register, e_ds1wm_en_fow, 0 ) ; // no bit banging
	
	UT_setbit( &control_register, e_ds1wm_stpen, 0 ) ; // strong pullup not supported in K1WM
	UT_setbit( &control_register, e_ds1wm_stp_sply, 0 ) ; // not in strong pullup state, too
	
	in->master.ds1wm.byte_mode = 1 ; // default
	UT_setbit( &control_register, e_ds1wm_bit_ctl, 0 ) ; // byte mode
	
	UT_setbit( &control_register, e_ds1wm_od, in->overdrive ) ; // not overdrive
	UT_setbit( &control_register, e_ds1wm_llm, in->master.ds1wm.longline ) ; // set long line flag
	DS1WM_control(in) = control_register ;
	LEVEL_DEBUG("[%s] control_register after setup: 0x%x", __FUNCTION__, DS1WM_control(in));
	
	if ( DS1WM_control(in) != control_register ) {
		return gbBAD ;
	}

	return gbGOOD ;
}	
Пример #6
0
// set control pins and frequency for defauts and global settings 
static GOOD_OR_BAD DS1WM_setup( struct connection_in * in )
{
	uint8_t control_register = DS1WM_control(in) ;

	DS1WM_clock(in) = 0x00 ; // off (causes reset?)
	
	// set some defaults:
	UT_setbit( &control_register, e_ds1wm_ppm, in->master.ds1wm.presence_mask ) ; // pulse presence masked
	UT_setbit( &control_register, e_ds1wm_en_fow, 0 ) ; // no bit banging
	
	UT_setbit( &control_register, e_ds1wm_stpen, 1 ) ; // allow strong pullup
	UT_setbit( &control_register, e_ds1wm_stp_sply, 0 ) ; // not in strong pullup state, however
	
	in->master.ds1wm.byte_mode = 1 ; // default
	UT_setbit( &control_register, e_ds1wm_bit_ctl, 0 ) ; // byte mode
	
	UT_setbit( &control_register, e_ds1wm_od, in->overdrive ) ; // not overdrive
	UT_setbit( &control_register, e_ds1wm_llm, in->master.ds1wm.longline ) ; // set long line flag
	DS1WM_control(in) = control_register ;
	
	if ( DS1WM_control(in) != control_register ) {
		return gbBAD ;
	}
	
	DS1WM_clock(in) = DS1WM_freq( in->master.ds1wm.frequency ) ;
	
	return gbGOOD ;
}	
Пример #7
0
//--------------------------------------------------------------------------
// Send  and receive 1 bit of communication to the 1-Wire
//
static GOOD_OR_BAD DS1WM_sendback_bits(const BYTE * databits, BYTE * respbits, const size_t len, const struct parsedname * pn)
{
	struct connection_in * in = pn->selected_connection ;
	uint8_t control_register ;
	GOOD_OR_BAD ret ;

	// Set bitmode on
	control_register = DS1WM_control(in) ;
	UT_setbit( &control_register,e_ds1wm_bit_ctl, 1 ) ;
	in->master.ds1wm.byte_mode = 0 ;
	DS1WM_control(in) = control_register ;

	ret = DS1WM_sendback_data( databits, respbits, len, pn ) ;

	// Set bitmode off
	control_register = DS1WM_control(in) ;
	in->master.ds1wm.byte_mode = 1 ;
	UT_setbit( &control_register,e_ds1wm_bit_ctl, 0 ) ;
	DS1WM_control(in) = control_register ;

	return ret ;
}
Пример #8
0
/* data[0] selection  */
static ZERO_OR_ERROR FS_w_s_alarm(struct one_wire_query *owq)
{
	BYTE data[3];
	int i;
	UINT p;
	UINT U = OWQ_U(owq);
	for (i = 0, p = 1; i < 8; ++i, p *= 10) {
		UT_setbit(&data[1], i, ((int) (U / p) % 10) & 0x01);
		UT_setbit(&data[0], i, (((int) (U / p) % 10) & 0x02) >> 1);
	}
	data[2] = ((U / 100000000) % 10) & 0x03;
	return GB_to_Z_OR_E(OW_w_s_alarm(data, PN(owq))) ;
}
Пример #9
0
// Handles: .n
static ZERO_OR_ERROR FS_write_a_bit(struct one_wire_query *owq_bit)
{
	struct one_wire_query * owq_byte = OWQ_create_separate( EXTENSION_BYTE, owq_bit ) ;
	ZERO_OR_ERROR z_or_e = -ENOENT ;
	
	if ( owq_byte != NO_ONE_WIRE_QUERY ) {
		if ( FS_read_local( owq_byte ) >= 0 ) {
			UT_setbit( (BYTE *) &OWQ_U( owq_byte ), OWQ_pn(owq_bit).extension, OWQ_Y(owq_bit) ) ;
			z_or_e = FS_write_owq( owq_byte ) ;
		}
		OWQ_destroy( owq_byte ) ;
	}
	return z_or_e ;
}
Пример #10
0
//--------------------------------------------------------------------------
// Reset all of the devices on the 1-Wire Net and return the result.
//
//          This routine will not function correctly on some
//          Alarm reset types of the DS1994/DS1427/DS2404 with
//          Rev 1,2, and 3 of the DS2480/DS2480B.
static RESET_TYPE DS1WM_reset(const struct parsedname * pn)
{
	struct connection_in * in = pn->selected_connection ; 
	if ( in->changed_bus_settings != 0) {
		in->changed_bus_settings = 0 ;
		DS1WM_setup(in);	// reset paramters
	}

	UT_setbit( &DS1WM_command(in), e_ds1wm_1wr, 1 ) ;
	
	switch( DS1WM_wait_for_reset(in) ) {
		case BUS_RESET_SHORT:
			return BUS_RESET_SHORT ;
		case BUS_RESET_OK:
			return BUS_RESET_OK ;
		default:
			return DS1WM_wait_for_reset(in) ;
	}
}
Пример #11
0
/* 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;
}
Пример #12
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;
}
Пример #13
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;
	}
}