예제 #1
0
/* It does call lower level functions for higher ones, which of course is pointless since the lower ones don't work either */
GOOD_OR_BAD BadAdapter_detect(struct port_in *pin)
{
	struct connection_in * in = pin->first ;
	pin->type = ct_none ;
	pin->file_descriptor = FILE_DESCRIPTOR_BAD ;
	in->Adapter = adapter_Bad;	/* OWFS assigned value */
	in->iroutines.reset = BadAdapter_reset;
	in->iroutines.next_both = NO_NEXT_BOTH_ROUTINE;
	in->iroutines.PowerByte = NO_POWERBYTE_ROUTINE;
	in->iroutines.ProgramPulse = NO_PROGRAMPULSE_ROUTINE;
	in->iroutines.sendback_data = NO_SENDBACKDATA_ROUTINE;
	in->iroutines.sendback_bits = BadAdapter_sendback_bits;
	in->iroutines.select = NO_SELECT_ROUTINE;
	in->iroutines.select_and_sendback = NO_SELECTANDSENDBACK_ROUTINE;
	in->iroutines.set_config = NO_SET_CONFIG_ROUTINE;
	in->iroutines.get_config = NO_GET_CONFIG_ROUTINE;
	in->iroutines.reconnect = NO_RECONNECT_ROUTINE;
	in->iroutines.close = BadAdapter_close;
	in->iroutines.verify = NO_VERIFY_ROUTINE ;
	in->iroutines.flags = ADAP_FLAG_sham;
	in->adapter_name = "Bad Adapter";
	SAFEFREE( DEVICENAME(in) ) ;
	DEVICENAME(in) = owstrdup("None") ;
	pin->busmode = bus_bad ;
	return gbGOOD;
}
예제 #2
0
/* Choose in order:
 * (first) 0x81
 * (first) 0x01
 * first other family
 * 0x00
 * */
GOOD_OR_BAD DS9490_ID_this_master(struct connection_in *in)
{
	struct dirblob db ;
	BYTE sn[SERIAL_NUMBER_SIZE] ;
	int device_number ;

	
	RETURN_BAD_IF_BAD( DS9490_root_dir( &db, in ) ) ;

	// Use 0x00 if no devices (homegrown adapters?)
	if ( DirblobElements( &db) == 0 ) {
		DirblobClear( &db ) ;
		memset( in->master.usb.ds1420_address, 0, SERIAL_NUMBER_SIZE ) ;
		LEVEL_DEFAULT("Set DS9490 %s unique id 0x00 (no devices at all)", SAFESTRING(DEVICENAME(in))) ;
		return gbGOOD ;
	}
	
	// look for the special 0x81 device
	device_number = 0 ;
	while ( DirblobGet( device_number, sn, &db ) == 0 ) {
		if (sn[0] == 0x81) {	// 0x81 family code
			memcpy(in->master.usb.ds1420_address, sn, SERIAL_NUMBER_SIZE);
			LEVEL_DEFAULT("Set DS9490 %s unique id to " SNformat, SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
			DirblobClear( &db ) ;
			return gbGOOD ;
		}
		++device_number ;
	}

	// look for the (less specific, for older DS9490s) 0x01 device
	device_number = 0 ;
	while ( DirblobGet( device_number, sn, &db ) == 0 ) {
		if (sn[0] == 0x01) {	// 0x01 family code
			memcpy(in->master.usb.ds1420_address, sn, SERIAL_NUMBER_SIZE);
			LEVEL_DEFAULT("Set DS9490 %s unique id to " SNformat, SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
			DirblobClear( &db ) ;
			return gbGOOD ;
		}
		++device_number ;
	}

	// Take the first device, whatever it is
	DirblobGet( 0, sn, &db ) ;
	memcpy(in->master.usb.ds1420_address, sn, SERIAL_NUMBER_SIZE);
	LEVEL_DEFAULT("Set DS9490 %s unique id to " SNformat, SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
	DirblobClear( &db ) ;
	return gbGOOD;
}
예제 #3
0
파일: ow_ds9490.c 프로젝트: M-o-a-T/owfs
/* When the errors stop the USB device from functioning -- close and reopen.
 * If it fails, re-scan the USB bus and search for the old adapter */
static GOOD_OR_BAD DS9490_reconnect(const struct parsedname *pn)
{
	GOOD_OR_BAD ret;
	struct connection_in * in = pn->selected_connection ;

	if ( in->master.usb.specific_usb_address ) { 
		// special case where a usb bus:dev pair was given
		// only connect to the same spot
		return DS9490_redetect_specific_adapter( in ) ; 
	}

	/* Have to protect usb_find_busses() and usb_find_devices() with
	 * a lock since libusb could crash if 2 threads call it at the same time.
	 * It's not called until DS9490_redetect_low(), but I lock here just
	 * to be sure DS9490_close() and DS9490_open() get one try first. */
	LIBUSBLOCK;
	DS9490_close( in ) ;
	ret = DS9490_redetect_low(in) ;
	LIBUSBUNLOCK;

	if ( GOOD(ret) ) {
		LEVEL_DEFAULT("Found USB DS9490 bus master after USB rescan as [%s]", SAFESTRING(DEVICENAME(in)));
	}
	return ret;
}
예제 #4
0
/* Only error is if parsename fails */
GOOD_OR_BAD DS9490_root_dir( struct dirblob * db, struct connection_in * in )
{
	ASCII path[PATH_MAX] ;
	struct parsedname pn_root ;

	UCLIBCLOCK;
		/* Force this adapter with bus.n path */
		snprintf(path, PATH_MAX, "/uncached/bus.%d", in->index);
	UCLIBCUNLOCK;

	if ( FS_ParsedName(path, &pn_root) != 0 ) {
		LEVEL_DATA("Cannot get root directory on [%s] Parsing %s error.", SAFESTRING(DEVICENAME(in)), path);
		return gbBAD ;
	}
	DirblobInit( db ) ;
	/* First time pretend there are devices */
	pn_root.selected_connection->changed_bus_settings |= CHANGED_USB_SPEED ;	// Trigger needing new configuration
	pn_root.selected_connection->overdrive = 0 ;	// not overdrive at start
	pn_root.selected_connection->flex = Globals.usb_flextime ;
	
	SetReconnect(&pn_root) ;
	FS_dir( DS9490_dir_callback, db, &pn_root ) ;
	LEVEL_DEBUG("Finished FS_dir");
	FS_ParsedName_destroy(&pn_root) ;

	return gbGOOD ;
	// Dirblob must be cleared by recipient.
}
예제 #5
0
/* Re-open a DS2482 */
static GOOD_OR_BAD DS2482_redetect(const struct parsedname *pn)
{
    struct connection_in *head = pn->selected_connection->master.i2c.head;
    int address = head->master.i2c.i2c_address;
    FILE_DESCRIPTOR_OR_ERROR file_descriptor;
    struct address_pair ap ; // to get device name from device:address

    /* open the i2c port */
    Parse_Address( DEVICENAME(head), &ap ) ;
    file_descriptor = open(ap.first.alpha, O_RDWR );
    Free_Address( &ap ) ;
    if ( FILE_DESCRIPTOR_NOT_VALID(file_descriptor) ) {
        ERROR_CONNECT("Could not open i2c device %s", DEVICENAME(head));
        return gbBAD;
    }

    /* address is known */
    if (ioctl(file_descriptor, I2C_SLAVE, address) < 0) {
        ERROR_CONNECT("Cound not set i2c address to %.2X", address);
    } else {
        BYTE c;
        /* write the RESET code */
        if (i2c_smbus_write_byte(file_descriptor, DS2482_CMD_RESET)	// reset
                || BAD(DS2482_readstatus(&c, file_descriptor, DS2482_Chip_reset_usec))	// pause .5 usec then read status
                || (c != (DS2482_REG_STS_LL | DS2482_REG_STS_RST))	// make sure status is properly set
           ) {
            LEVEL_CONNECT("i2c device at %s address %d cannot be reset. Not a DS2482.", DEVICENAME(head), address);
        } else {
            struct connection_in * next ;
            head->master.i2c.current = 0;
            head->pown->file_descriptor = file_descriptor;
            head->pown->state = cs_deflowered ;
            head->pown->type = ct_i2c ;
            head->master.i2c.configchip = 0x00;	// default configuration register after RESET
            LEVEL_CONNECT("i2c device at %s address %d reset successfully", DEVICENAME(head), address);
            for ( next = head->pown->first; next; next = next->next ) {
                /* loop through devices, matching those that have the same "head" */
                /* BUSLOCK also locks the sister channels for this */
                next->reconnect_state = reconnect_ok;
            }
            return gbGOOD;
        }
    }
    /* fellthough, no device found */
    close(file_descriptor);
    return gbBAD;
}
예제 #6
0
GOOD_OR_BAD FS_FindHA7(void)
{
	struct addrinfo *ai;
	struct addrinfo hint;
	struct addrinfo *now;
	int number_found = 0;
	int getaddr_error ;

	LEVEL_DEBUG("Attempting udp multicast search for the HA7Net bus master at %s:%s",HA7_DISCOVERY_ADDRESS,HA7_DISCOVERY_PORT);
	Setup_HA7_hint( &hint ) ;
	if ((getaddr_error = getaddrinfo(HA7_DISCOVERY_ADDRESS, HA7_DISCOVERY_PORT, &hint, &ai))) {
		LEVEL_CONNECT("Couldn't set up HA7 broadcast message %s", gai_strerror(getaddr_error));
		return gbBAD;
	}

	for (now = ai; now; now = now->ai_next) {
		ASCII name[INET_ADDRSTRLEN+20]; // tcp quad + port
		struct port_in * pin ;
		struct connection_in *in;

		if ( Get_HA7_response( now, name ) ) {
			continue ;
		}

		pin = NewPort(NO_CONNECTION) ;
		if (pin == NULL) {
			continue;
		}
		in = pin->first ;

		pin->type = ct_tcp ;
		pin->init_data = owstrdup(name);
		DEVICENAME(in) = owstrdup(name);
		pin->busmode = bus_ha7net;

		LEVEL_CONNECT("HA7Net bus master discovered at %s",DEVICENAME(in));
		++number_found ;
	}
	freeaddrinfo(ai);
	return number_found > 0 ? gbGOOD : gbBAD ;
}
예제 #7
0
파일: ow_ds9490.c 프로젝트: M-o-a-T/owfs
// Open usb device,
// dev already set
static GOOD_OR_BAD DS9490_open_and_name( libusb_device * dev, struct connection_in *in)
{
	if (in->master.usb.lusb_handle != NULL) {
		LEVEL_DEFAULT("DS9490 %s was NOT closed?", DEVICENAME(in));
		return gbBAD ;
	}

	DS9490_port_setup( dev, in->pown ) ;

	if ( BAD( DS9490_open( in ) ) ) {
		STAT_ADD1_BUS(e_bus_open_errors, in);
		return gbBAD ;
	} else if ( BAD( DS9490_setup_adapter(in)) ) {
		LEVEL_DEFAULT("Error setting up USB DS9490 bus master at %s.", DEVICENAME(in));
		DS9490_close( in ) ;
		return gbBAD ;
	}
	DS9490_SetFlexParameters(in);

	return gbGOOD ;
}
예제 #8
0
파일: ow_fake.c 프로젝트: M-o-a-T/owfs
static void SetConninData( int indx, const char * type, struct port_in *pin )
{
	struct connection_in * in = pin->first ;
	char name[20] ;

	pin->file_descriptor = indx;
	pin->type = ct_none ;
	in->master.fake.index = indx;
	in->master.fake.templow = Globals.templow;
	in->master.fake.temphigh = Globals.temphigh;
	LEVEL_CONNECT("Setting up %s Bus Master (%d)", type, indx);

	UCLIBCLOCK ;
	snprintf(name, 18, "%s.%d", type, indx);
	UCLIBCUNLOCK ;

	GetAllDeviceNames( pin ) ;

	// Device name and init_data diverge now
	SAFEFREE(DEVICENAME(in)) ;
	DEVICENAME(in) = owstrdup(name);
}
예제 #9
0
파일: ow_ds9490.c 프로젝트: M-o-a-T/owfs
/* Open a DS9490  -- low level code (to allow for repeats)  */
static GOOD_OR_BAD DS9490_redetect_match( struct connection_in * in)
{
	struct dirblob db ;
	BYTE sn[SERIAL_NUMBER_SIZE] ;
	int device_number ;

	LEVEL_DEBUG("Attempting reconnect on %s",SAFESTRING(DEVICENAME(in)));

	// Special case -- originally untagged adapter
	if ( in->master.usb.ds1420_address[0] == '\0' ) {
		LEVEL_CONNECT("Since originally untagged bus master, we will use first available slot.");
		return gbGOOD ;
	}

	// Generate a root directory
	RETURN_BAD_IF_BAD( DS9490_root_dir( &db, in ) ) ;

	// This adapter has no tags, so not the one we want
	if ( DirblobElements( &db) == 0 ) {
		DirblobClear( &db ) ;
		LEVEL_DATA("Empty directory on [%s] (Doesn't match initial scan).", SAFESTRING(DEVICENAME(in)));
		return gbBAD ;
	}

	// Scan directory for a match to the original tag
	device_number = 0 ;
	while ( DirblobGet( device_number, sn, &db ) == 0 ) {
		if (memcmp(sn, in->master.usb.ds1420_address, SERIAL_NUMBER_SIZE) == 0) {	// same tag device?
			LEVEL_DATA("Matching device [%s].", SAFESTRING(DEVICENAME(in)));
			DirblobClear( &db ) ;
			return gbGOOD ;
		}
		++device_number ;
	}
	// Couldn't find correct ds1420 chip on this adapter
	LEVEL_CONNECT("Couldn't find correct ds1420 chip on this bus master [%s] (want: " SNformat ")", SAFESTRING(DEVICENAME(in)), SNvar(in->master.usb.ds1420_address));
	DirblobClear( &db ) ;
	return gbBAD;
}
예제 #10
0
//open serial port ( called on head of connection_in group from com_open )
GOOD_OR_BAD serial_open(struct connection_in *connection)
{
	struct port_in * pin = connection->pown ;
	FILE_DESCRIPTOR_OR_ERROR fd = open( DEVICENAME(connection), O_RDWR | O_NONBLOCK | O_NOCTTY) ;
	pin->file_descriptor = fd ;
	if ( FILE_DESCRIPTOR_NOT_VALID( fd ) ) {
		// state doesn't change
		ERROR_DEFAULT("Cannot open port: %s Permissions problem?", SAFESTRING(DEVICENAME(connection)));
		return gbBAD;
	}

	if ( pin->state == cs_virgin ) {
		// valgrind warns about uninitialized memory in tcsetattr(), so clear all.
		memset( &(pin->dev.serial.oldSerialTio), 0, sizeof(struct termios));
		if ((tcgetattr( fd, &(pin->dev.serial.oldSerialTio) ) < 0)) {
			ERROR_CONNECT("Cannot get old port attributes: %s", SAFESTRING(DEVICENAME(connection)));
			// proceed anyway
		}
		pin->state = cs_deflowered ;
	}

	return serial_change( connection ) ;
}
예제 #11
0
/* This allows removing Bus Masters while program is running
 * The master is usually only read-locked for normal operation
 * write lock is done in a separate thread when no requests are being processed */
void Del_InFlight( GOOD_OR_BAD (*nomatch)(struct port_in * trial,struct port_in * existing), struct port_in * old_pin )
{
	struct connection_in * old_in ;
	if ( old_pin == NULL ) {
		return ;
	}

	old_in = old_pin->first ;
	LEVEL_DEBUG("Request master be removed: %s", DEVICENAME(old_in));

	if ( nomatch != NULL ) {
		struct port_in * pin ;

		CONNIN_WLOCK ;
		for ( pin = Inbound_Control.head_port ; pin != NULL ; pin = pin->next ) {
			if ( BAD( nomatch( old_pin, pin )) ) {
				LEVEL_DEBUG("Removing BUS index=%d %s",pin->first->index,SAFESTRING(DEVICENAME(pin->first)));
				RemovePort(pin) ;
			}
		}
		CONNIN_WUNLOCK ;
	}
}
예제 #12
0
// Look on a given connection for the device
static INDEX_OR_ERROR CheckThisConnection(int bus_nr, struct parsedname *pn)
{
	struct parsedname s_pn_copy;
	struct parsedname * pn_copy = &s_pn_copy ;
	struct connection_in * in = find_connection_in(bus_nr) ;
	INDEX_OR_ERROR connection_result = INDEX_BAD ;

	if ( in == NO_CONNECTION ) {
		return INDEX_BAD ;
	}
	
	memcpy(pn_copy, pn, sizeof(struct parsedname));	// shallow copy
	pn_copy->selected_connection = in;
	
	if ( BAD( TestConnection(pn_copy) ) ) {
		// Connection currently disconnected
		return INDEX_BAD;
	} else if (BusIsServer(in)) {
		// Server
		if ( INDEX_VALID( ServerPresence(pn_copy) ) ) {
			connection_result =  in->index;
		}
	} else if ( in->iroutines.flags & ADAP_FLAG_sham ) {
		return INDEX_BAD ;
	} else if ( in->iroutines.flags & ADAP_FLAG_presence_from_dirblob ) {
		// local connection with a dirblob (like fake, mock, ...)
		if ( GOOD( PresenceFromDirblob( pn_copy ) ) ) {
			connection_result =  in->index ;
		}
	} else {
		// local connection but need to ask directly
		struct transaction_log t[] = {
			TRXN_NVERIFY,
			TRXN_END,
		};
		if ( GOOD( BUS_transaction(t, pn_copy) ) ) {
			connection_result =  in->index ;
		}
	}
	if ( connection_result == INDEX_BAD ) {
		LEVEL_DEBUG("Presence of "SNformat" NOT found on bus %s",SNvar(pn_copy->sn),SAFESTRING(DEVICENAME(in))) ;
	} else {
		LEVEL_DEBUG("Presence of "SNformat" FOUND on bus %s",SNvar(pn_copy->sn),SAFESTRING(DEVICENAME(in))) ;
		Cache_Add_Device(in->index,pn_copy->sn) ; // add or update cache */
	}
	return connection_result ;
}
예제 #13
0
/* Puts in 9600 baud */
static GOOD_OR_BAD DS9097_pre_reset(struct connection_in *in )
{
	struct port_in * pin = in->pown ;

	RETURN_BAD_IF_BAD( COM_test(in) ) ;

	/* 8 data bits */
	pin->bits = 8 ;
	pin->baud = B9600 ;

	if ( BAD( COM_change(in)) ) {
		ERROR_CONNECT("Cannot set attributes: %s", SAFESTRING(DEVICENAME(in)));
		DS9097_post_reset( in ) ;
		return gbBAD;
	}
	return gbGOOD;
}
예제 #14
0
void TrafficIn( const char * data_type, const BYTE * data, size_t length, const struct connection_in * in )
{
	fprintf(stderr, "TRAFFIC IN  <%s> bus=%d (%s)\n", SAFESTRING(data_type), in->index, DEVICENAME(in) ) ;
	_Debug_Bytes( in->adapter_name, data, length ) ;
}
예제 #15
0
//change serial port settings
GOOD_OR_BAD serial_change(struct connection_in *connection)
{
	struct port_in * pin = connection->pown ;
	struct termios newSerialTio;	/*new serial port settings */
	FILE_DESCRIPTOR_OR_ERROR fd = pin->file_descriptor ;
	size_t baud = pin->baud ;

	// read the attribute structure
	// valgrind warns about uninitialized memory in tcsetattr(), so clear all.
	memset(&newSerialTio, 0, sizeof(struct termios));
	if ((tcgetattr( fd, &newSerialTio) < 0)) {
		ERROR_CONNECT("Cannot get existing port attributes: %s", SAFESTRING(DEVICENAME(connection)));
	}
	
	// set baud in structure
	if (cfsetospeed(&newSerialTio, baud) < 0 || cfsetispeed(&newSerialTio, baud) < 0) {
		ERROR_CONNECT("Trouble setting port speed: %s", SAFESTRING(DEVICENAME(connection)));
		cfsetospeed(&newSerialTio, B9600) ;
		cfsetispeed(&newSerialTio, B9600) ;
		pin->baud = B9600 ;
	}

	// Set to non-canonical mode, and no RTS/CTS handshaking
	newSerialTio.c_iflag &= ~(BRKINT | ICRNL | IGNCR | INLCR | INPCK | ISTRIP | IXON | IXOFF | PARMRK);
	newSerialTio.c_iflag |= IGNBRK | IGNPAR;

	newSerialTio.c_oflag &= ~(OPOST);

	newSerialTio.c_cflag &= ~ HUPCL ;
	newSerialTio.c_cflag |= (CLOCAL | CREAD);

	switch( pin->flow ) {
		case flow_hard:
			newSerialTio.c_cflag |= CRTSCTS ;
			break ;
		case flow_none:
			newSerialTio.c_cflag &= ~CRTSCTS;
			break ;
		case flow_soft:
		default:
			LEVEL_DEBUG("Unsupported COM port flow control");
			return -ENOTSUP ;
	}

	// set bit length
	newSerialTio.c_cflag &= ~ CSIZE ;
	switch (pin->bits) {
		case 5:
			newSerialTio.c_cflag |= CS5 ;
			break ;
		case 6:
			newSerialTio.c_cflag |= CS6 ;
			break ;
		case 7:
			newSerialTio.c_cflag |= CS7 ;
			break ;
		case 8:
		default:
			newSerialTio.c_cflag |= CS8 ;
			break ;
	}

	// parity
	switch (pin->parity) {
		case parity_none:
			newSerialTio.c_cflag &= ~PARENB ;
			break ;
		case parity_even:
			newSerialTio.c_cflag |= PARENB ;
			newSerialTio.c_cflag &= ~( PARODD | CMSPAR ) ;
			break ;
		case parity_odd:
			newSerialTio.c_cflag |= PARENB | PARODD;
			newSerialTio.c_cflag &= ~CMSPAR ;
			break ;
		case parity_mark:
			newSerialTio.c_cflag |= PARENB | PARODD | CMSPAR;
			break ;
	}

	// stop bits
	switch (pin->stop) {
		case stop_15:
			LEVEL_DEBUG("1.5 Stop bits not supported");
			pin->stop = stop_1 ;
			// fall through
		case stop_1:
			newSerialTio.c_cflag &= ~CSTOPB ;
			break ;
		case stop_2:
			newSerialTio.c_cflag |= CSTOPB ;
			break ;
	}


	newSerialTio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG);
	newSerialTio.c_cc[VMIN] = pin->vmin;
	newSerialTio.c_cc[VTIME] = pin->vtime;
	if (tcsetattr( fd, TCSAFLUSH, &newSerialTio)) {
		ERROR_CONNECT("Cannot set port attributes: %s", SAFESTRING(DEVICENAME(connection)));
		return gbBAD;
	}
	tcflush( fd, TCIOFLUSH);
	return gbGOOD;
}
예제 #16
0
/* Try to see if there is a DS2482 device on the specified i2c bus */
static GOOD_OR_BAD DS2482_detect_single(int lowindex, int highindex, char * i2c_device, struct port_in *pin)
{
    int test_address[8] = { 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, };	// the last 4 are -800 only
    int i2c_index;
    FILE_DESCRIPTOR_OR_ERROR file_descriptor;
    struct connection_in * in = pin->first ;

    /* Sanity check */
    if ( lowindex < 0 ) {
        LEVEL_DEBUG("Bad lower bound");
        return gbBAD ;
    }
    if ( highindex >= (int) (sizeof(test_address)/sizeof(int)) ) {
        LEVEL_DEBUG("Bad upper bound");
        return gbBAD ;
    }

    /* open the i2c port */
    file_descriptor = open(i2c_device, O_RDWR);
    if ( FILE_DESCRIPTOR_NOT_VALID(file_descriptor) ) {
        ERROR_CONNECT("Could not open i2c device %s", i2c_device);
        return gbBAD;
    }

    /* Set up low-level routines */
    DS2482_setroutines(in);

    for (i2c_index = lowindex; i2c_index <= highindex; ++i2c_index) {
        int trial_address = test_address[i2c_index] ;
        /* set the candidate address */
        if (ioctl(file_descriptor, I2C_SLAVE, trial_address) < 0) {
            ERROR_CONNECT("Cound not set trial i2c address to %.2X", trial_address);
        } else {
            BYTE c;
            LEVEL_CONNECT("Found an i2c device at %s address %.2X", i2c_device, trial_address);
            /* Provisional setup as a DS2482-100 ( 1 channel ) */
            in->pown->file_descriptor = file_descriptor;
            pin->state = cs_deflowered;
            pin->type = ct_i2c ;
            in->master.i2c.i2c_address = trial_address;
            in->master.i2c.i2c_index = i2c_index;
            in->master.i2c.index = 0;
            in->master.i2c.channels = 1;
            in->master.i2c.current = 0;
            in->master.i2c.head = in;
            in->adapter_name = "DS2482-100";
            in->master.i2c.configreg = 0x00 ;	// default configuration setting desired
            if ( Globals.i2c_APU ) {
                in->master.i2c.configreg |= DS2482_REG_CFG_APU ;
            }
            if ( Globals.i2c_PPM ) {
                in->master.i2c.configreg |= DS2482_REG_CFG_PPM ;
            }
            in->Adapter = adapter_DS2482_100;

            /* write the RESET code */
            if (i2c_smbus_write_byte(file_descriptor, DS2482_CMD_RESET)	// reset
                    || BAD(DS2482_readstatus(&c, file_descriptor, DS2482_Chip_reset_usec))	// pause .5 usec then read status
                    || (c != (DS2482_REG_STS_LL | DS2482_REG_STS_RST))	// make sure status is properly set
               ) {
                LEVEL_CONNECT("i2c device at %s address %.2X cannot be reset. Not a DS2482.", i2c_device, trial_address);
                continue;
            }
            LEVEL_CONNECT("i2c device at %s address %.2X appears to be DS2482-x00", i2c_device, trial_address);
            in->master.i2c.configchip = 0x00;	// default configuration register after RESET
            // Note, only the lower nibble of the device config stored

            // Create name
            SAFEFREE( DEVICENAME(in) ) ;
            DEVICENAME(in) = owmalloc( strlen(i2c_device) + 10 ) ;
            if ( DEVICENAME(in) ) {
                UCLIBCLOCK;
                snprintf(DEVICENAME(in), strlen(i2c_device) + 10, "%s:%.2X", i2c_device, trial_address);
                UCLIBCUNLOCK;
            }

            /* Now see if DS2482-100 or DS2482-800 */
            return HeadChannel(in);
        }
    }
    /* fell though, no device found */
    COM_close( in ) ;
    return gbBAD;
}
예제 #17
0
/* special check, -remote file length won't match local sizes */
static ZERO_OR_ERROR FS_port(struct one_wire_query *owq)
{
	return OWQ_format_output_offset_and_size_z(
		SAFESTRING( DEVICENAME(PN(owq)->selected_connection)),
		owq);
}
예제 #18
0
파일: ow_k1wm.c 프로젝트: M-o-a-T/owfs
static GOOD_OR_BAD K1WM_reconnect(const struct parsedname * pn)
{
	LEVEL_DEBUG("Attempting reconnect on %s",SAFESTRING(DEVICENAME(pn->selected_connection)));
	return K1WM_setup(pn->selected_connection) ;
}
예제 #19
0
/* Device-specific functions */
GOOD_OR_BAD ENET_monitor_detect(struct port_in *pin)
{
	struct connection_in * in = pin->first ;
	struct address_pair ap ;
	pthread_t thread ;
	
	/* init_data has form "scan" or "scan:15" (15 seconds) */
	Parse_Address( pin->init_data, &ap ) ;
	in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ;
	switch ( ap.entries ) {
		case 0:
			in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ;
			break ;
		case 1:
			switch( ap.first.type ) {
				case address_numeric:
					in->master.enet_monitor.enet_scan_interval = ap.first.number ;
					break ;
				default:
					in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ;
					break ;
			}
			break ;
		case 2:
			switch( ap.second.type ) {
				case address_numeric:
					in->master.enet_monitor.enet_scan_interval = ap.second.number ;
					break ;
				default:
					in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ;
					break ;
			}
			break ;
	}
	Free_Address( &ap ) ;

	pin->type = ct_none ;

	// Device name will not be init_data copy
	SAFEFREE(DEVICENAME(in)) ;
	DEVICENAME(in) = owstrdup("ENET bus monitor") ;

	pin->file_descriptor = FILE_DESCRIPTOR_BAD;
	in->iroutines.detect = ENET_monitor_detect;
	in->Adapter = adapter_enet_monitor;
	in->iroutines.reset = NO_RESET_ROUTINE;
	in->iroutines.next_both = NO_NEXT_BOTH_ROUTINE;
	in->iroutines.PowerByte = NO_POWERBYTE_ROUTINE;
	in->iroutines.ProgramPulse = NO_PROGRAMPULSE_ROUTINE;
	in->iroutines.sendback_data = NO_SENDBACKDATA_ROUTINE;
	in->iroutines.sendback_bits = NO_SENDBACKBITS_ROUTINE;
	in->iroutines.select = NO_SELECT_ROUTINE;
	in->iroutines.select_and_sendback = NO_SELECTANDSENDBACK_ROUTINE ;
	in->iroutines.set_config = NO_SET_CONFIG_ROUTINE;
	in->iroutines.get_config = NO_GET_CONFIG_ROUTINE;
	in->iroutines.reconnect = NO_RECONNECT_ROUTINE;
	in->iroutines.close = ENET_monitor_close;
	in->iroutines.verify = NO_VERIFY_ROUTINE ;
	in->iroutines.flags = ADAP_FLAG_sham;
	in->adapter_name = "ENET scan";
	pin->busmode = bus_enet_monitor ; // repeat since can come via usb=scan
	
	Init_Pipe( in->master.enet_monitor.shutdown_pipe ) ;
	if ( pipe( in->master.enet_monitor.shutdown_pipe ) != 0 ) {
		ERROR_DEFAULT("Cannot allocate a shutdown pipe. The program shutdown may be messy");
		Init_Pipe( in->master.enet_monitor.shutdown_pipe ) ;
	}
	if ( BAD( ENET_monitor_in_use(pin) ) ) {
		LEVEL_CONNECT("Second call for ENET scanning ignored") ;
		return gbBAD ;
	}

	if ( pthread_create(&thread, DEFAULT_THREAD_ATTR, ENET_monitor_loop, (void *) in) != 0 ) {
		ERROR_CALL("Cannot create the ENET monitoring program thread");
		return gbBAD ;
	}

	return gbGOOD ;
}