コード例 #1
0
ファイル: ow_ds9490.c プロジェクト: M-o-a-T/owfs
static GOOD_OR_BAD DS9490_setup_adapter(struct connection_in * in)
{
	struct parsedname s_pn;
	struct parsedname * pn = &s_pn ;
	BYTE buffer[ DS9490_getstatus_BUFFER_LENGTH + 1 ];
	int readlen = 0 ;

	FS_ParsedName_Placeholder(pn);	// minimal parsename -- no destroy needed
	pn->selected_connection = in;
	// reset the device (not the 1-wire bus)
	if ( BAD(USB_Control_Msg(CONTROL_CMD, CTL_RESET_DEVICE, 0x0000, pn))) {
		LEVEL_DATA("ResetDevice error");
		return gbBAD;
	}
	// set the strong pullup duration to infinite
	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_SET_DURATION | COMM_IM, 0x0000, pn)) ) {
		LEVEL_DATA("StrongPullup error");
		return gbBAD;
	}
	// set the 12V pullup duration to 512us
	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_SET_DURATION | COMM_IM | COMM_TYPE, PROGRAM_PULSE_DURATION_CODE, pn)) ) {
		LEVEL_DATA("12VPullup error");
		return gbBAD;
	}
	// enable both program and strong pulses
	if ( BAD( USB_Control_Msg(MODE_CMD, MOD_PULSE_EN, ENABLE_PROGRAM_AND_PULSE, pn)) ) {
		LEVEL_DATA("EnableProgram error");
		return gbBAD;
	}
	// enable speed changes
	if ( BAD( USB_Control_Msg(MODE_CMD, MOD_SPEED_CHANGE_EN, 1, pn)) ) {
		LEVEL_DATA("SpeedEnable error");
		return gbBAD;
	}

	if ( DS9490_getstatus(buffer, &readlen, pn) != BUS_RESET_OK ) {
		LEVEL_DATA("getstatus failed error");
		return gbBAD;
	}

	return gbGOOD;
}
コード例 #2
0
ファイル: ow_ds9490.c プロジェクト: M-o-a-T/owfs
static GOOD_OR_BAD DS9490_sendback_data(const BYTE * const_data, BYTE * resp, size_t len, const struct parsedname *pn)
{
	size_t location = 0 ;
	BYTE data[len] ; // to avoid const problem

	memcpy( data, const_data, len ) ;

	while ( location < len ) {
		BYTE buffer[ DS9490_getstatus_BUFFER_LENGTH + 1 ];
		int readlen ;

		size_t block = len - location ;
		if ( block > USB_FIFO_EACH ) {
			block = USB_FIFO_EACH ;
		}

		if ( DS9490_write( &data[location], block, pn) < (int) block) {
			LEVEL_DATA("USBsendback bulk write problem");
			return gbBAD;
		}

		// COMM_BLOCK_IO | COMM_IM | COMM_F == 0x0075
		readlen = block ;
		if (( BAD( USB_Control_Msg(COMM_CMD, COMM_BLOCK_IO | COMM_IM | COMM_F, block, pn)) )
			|| ( DS9490_getstatus(buffer, &readlen, pn)  != BUS_RESET_OK )	// wait for len bytes
			) {
			LEVEL_DATA("USBsendback control error");
			STAT_ADD1_BUS(e_bus_errors, pn->selected_connection);
			return gbBAD;
		}

		if ( DS9490_read( &resp[location], block, pn) < 0) {
			LEVEL_DATA("USBsendback bulk read error");
			return gbBAD;
		}

		location += block ;
	}
	return gbGOOD;
}
コード例 #3
0
ファイル: ow_interface.c プロジェクト: GrandHsu/iicontrollibs
static ZERO_OR_ERROR FS_r_ds2490status(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	char res[256];
	char buffer[ DS9490_getstatus_BUFFER_LENGTH ];
	int ret;
	res[0] = '\0';
	if (get_busmode(pn->selected_connection) == bus_usb) {
#if OW_USB
		ret = DS9490_getstatus(buffer, 0, PN(owq));
		if (ret < 0) {
			sprintf(res, "DS9490_getstatus failed: %d\n", ret);
		} else {
			sprintf(res,
					"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
					buffer[0], buffer[1], buffer[2], buffer[3],
					buffer[4], buffer[5], buffer[6], buffer[7],
					buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15]);
		}
		/*
		   uchar    EnableFlags;
		   uchar    OneWireSpeed;
		   uchar    StrongPullUpDuration;
		   uchar    ProgPulseDuration;
		   uchar    PullDownSlewRate;
		   uchar    Write1LowTime;
		   uchar    DSOW0RecoveryTime;
		   uchar    Reserved1;
		   uchar    StatusFlags;
		   uchar    CurrentCommCmd1;
		   uchar    CurrentCommCmd2;
		   uchar    CommBufferStatus;  // Buffer for COMM commands
		   uchar    WriteBufferStatus; // Buffer we write to
		   uchar    ReadBufferStatus;  // Buffer we read from
		 */
#endif
	}
	return OWQ_format_output_offset_and_size_z(res, owq);
}
コード例 #4
0
ファイル: ow_ds9490.c プロジェクト: M-o-a-T/owfs
static GOOD_OR_BAD DS9490_HaltPulse(const struct parsedname *pn)
{
	BYTE buffer[ DS9490_getstatus_BUFFER_LENGTH + 1 ];
	struct timeval tv;
	struct timeval tvtarget;
	struct timeval tvlimit = { 0, 300000 } ; // 300 millisec from PDKit /ib/other/libUSB/libusbds2490.c

	if ( timernow( &tv ) < 0) {
		return gbBAD;
	}
	timeradd( &tv, &tvlimit, &tvtarget ) ;

	do {
		int readlen = -1 ;
		
		if ( BAD(USB_Control_Msg(CONTROL_CMD, CTL_HALT_EXE_IDLE, 0, pn)) ) {
			break;
		}
		if ( BAD(USB_Control_Msg(CONTROL_CMD, CTL_RESUME_EXE, 0, pn)) ) {
			break;
		}

		/* Can't wait for STATUSFLAGS_IDLE... just get first availalbe status flag */
		if ( DS9490_getstatus(buffer, &readlen, pn) != BUS_RESET_OK ) {
			break;
		}
		// check the SPU flag
		if (!(buffer[8] & STATUSFLAGS_SPUA)) {
			return gbGOOD;
		}
		if ( timernow( &tv ) < 0) {
			return gbBAD;
		}
	} while ( timercmp( &tv, &tvtarget, >) ) ;
	LEVEL_DATA("DS9490_HaltPulse timeout");
	return gbBAD;
}
コード例 #5
0
ファイル: ow_ds9490.c プロジェクト: M-o-a-T/owfs
// Read up to 7 (DS2490_DIR_GULP_ELEMENTS) at a time, and  place into
// a dirblob. Called from DS9490_next_both every 7 devices to fill.
static enum search_status DS9490_directory(struct device_search *ds, const struct parsedname *pn)
{
	BYTE status_buffer[ DS9490_getstatus_BUFFER_LENGTH + 1 ];
	BYTE EP2_data[SERIAL_NUMBER_SIZE] ; //USB endpoint 3 buffer
	union {
		BYTE b[DS2490_BULK_BUFFER_SIZE] ;
		BYTE sn[DS2490_BULK_BUFFER_SIZE/SERIAL_NUMBER_SIZE][SERIAL_NUMBER_SIZE];
	} EP3 ; //USB endpoint 3 buffer
	SIZE_OR_ERROR ret;
	int bytes_back;
	int devices_found;
	int device_index;
	int dir_gulp_elements = (pn->ds2409_depth==0) ? DS2490_DIR_GULP_ELEMENTS : 1 ;
	int readlen = 0 ;
	
	DirblobClear(&(ds->gulp));

	if ( BAD( BUS_select(pn) ) ) {
		LEVEL_DEBUG("Selection problem before a directory listing") ;
		return search_error ;
	}

	if ( pn->selected_connection->AnyDevices == anydevices_no ) {
		// empty bus detected, no presence pulse detected
		return search_done ;
	}
	
	SetupDiscrepancy(ds, EP2_data);

	// set the search start location
	ret = DS9490_write(EP2_data, SERIAL_NUMBER_SIZE, pn) ;
	if ( ret < SERIAL_NUMBER_SIZE ) {
		LEVEL_DATA("bulk write problem = %d", ret);
		return search_error;
	}
	// Send the search request
	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS, (dir_gulp_elements << 8) | (ds->search), pn) ) ) {
		LEVEL_DATA("control error");
		return search_error;
	}
	// read the search status
	if ( DS9490_getstatus(status_buffer, &readlen, pn)  != BUS_RESET_OK ) {
		return search_error;
	}

	// test the buffer size waiting for us
	bytes_back = status_buffer[13];
	LEVEL_DEBUG("Got %d bytes from USB search", bytes_back);
	if (bytes_back == 0) {
		/* Nothing found on the bus. Have to return something != search_good to avoid
		 * getting stuck in loop in FS_realdir() and FS_alarmdir()
		 * which ends when ret!=search_good */
		LEVEL_DATA("ReadBufferstatus == 0");
		return search_done;
	} else if ( bytes_back % SERIAL_NUMBER_SIZE != 0 ) {
		LEVEL_DATA("ReadBufferstatus size %d not a multiple of %d", bytes_back,SERIAL_NUMBER_SIZE);
		return search_error;
	} else if ( bytes_back > (dir_gulp_elements + 1) * SERIAL_NUMBER_SIZE ) {
		LEVEL_DATA("ReadBufferstatus size %d too large", bytes_back);
		return search_error;
	}
	devices_found = bytes_back / SERIAL_NUMBER_SIZE;
	if (devices_found > dir_gulp_elements) {
		devices_found = dir_gulp_elements;
	}

	// read in the buffer that holds the devices found
	if ((ret = DS9490_read(EP3.b, bytes_back, pn)) <= 0) {
		LEVEL_DATA("bulk read problem ret=%d", ret);
		return search_error;
	}

	// analyze each device found
	for (device_index = 0; device_index < devices_found; ++device_index) {
		/* test for CRC error */
		LEVEL_DEBUG("gulp. Adding element %d:" SNformat, device_index, SNvar(EP3.sn[device_index]));
		if (CRC8(EP3.sn[device_index], SERIAL_NUMBER_SIZE) != 0 || EP3.sn[device_index][0] == 0) {
			LEVEL_DATA("CRC error");
			return search_error;
		}
	}
	// all ok, so add the devices
	for (device_index = 0; device_index < devices_found; ++device_index) {
		DirblobAdd(EP3.sn[device_index], &(ds->gulp));
	}
	ds->LastDiscrepancy = FindDiscrepancy(EP3.sn[devices_found-1], EP3.sn[devices_found]);
	ds->LastDevice = (bytes_back == devices_found * SERIAL_NUMBER_SIZE);	// no more to read

	return search_good;
}
コード例 #6
0
ファイル: ow_ds9490.c プロジェクト: M-o-a-T/owfs
/* return 1=short, 0 good <0 error */
static RESET_TYPE DS9490_reset(const struct parsedname *pn)
{
	int i; 
	BYTE buffer[ DS9490_getstatus_BUFFER_LENGTH + 1 ];
	int USpeed;
	struct connection_in * in = pn->selected_connection ;
	int readlen = 0 ;

	LEVEL_DEBUG("DS9490 RESET. changed %d, flex: %d", in->changed_bus_settings, in->flex) ;	

	if (in->master.usb.lusb_dev == NULL || in->master.usb.lusb_handle == NULL) {
		// From Michael Markstaller:
		LEVEL_DEBUG("Attempting RESET on null bus") ;
		//FIXME! what doees it mean? no action/reconnect is even tried-> shouldn't we just drop this BM and let uscan rediscover it? DS9490 must always have an ID chip..
		// Actually no, the home-brewed DS2490-based masters that people have built have no ID chip
		BUS_ERROR_fix(pn) ;
		return BUS_RESET_ERROR;
	}

	// Do we need to change settings?
	if (in->changed_bus_settings > 0) {
		// Prevent recursive loops on reset
		DS9490_SetSpeed(pn);	// reset paramters
		in->changed_bus_settings = 0 ;
	}

	memset(buffer, 0, 32);

	// Bus timing
	if ( in->overdrive ) {
		USpeed = ONEWIREBUSSPEED_OVERDRIVE ;
	} else if ( in->flex ) {
		USpeed = ONEWIREBUSSPEED_FLEXIBLE ;
	} else {
		USpeed = ONEWIREBUSSPEED_REGULAR ;
	}

	// Send reset
	//FIXME: from Michael Markstaller: changed hard to flexible speed as it gets wrong somewhere, only want flexible
	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, USpeed, pn)) ) {
//	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, ONEWIREBUSSPEED_FLEXIBLE, pn)) ) {
		LEVEL_DATA("Reset command rejected");
		BUS_ERROR_fix(pn) ;
		return BUS_RESET_ERROR;			// fatal error... probably closed usb-handle
	}

	// Extra delay?
	if (in->ds2404_found && (in->overdrive == 0)) {
		// extra delay for alarming DS1994/DS2404 compliance
		UT_delay(5);
	}

	// Read response
	switch( DS9490_getstatus(buffer, &readlen, pn) ) {
		case BUS_RESET_SHORT:
			/* Short detected, but otherwise no bigger problem */
			LEVEL_DEBUG("DS9490_Reset: SHORT");
			return BUS_RESET_SHORT ;
		case BUS_RESET_OK:
			LEVEL_DEBUG("DS9490_Reset: OK");
			break ;
		case BUS_RESET_ERROR:
		default:
			LEVEL_DEBUG("DS9490_Reset: ERROR");
			BUS_ERROR_fix(pn) ;
			return BUS_RESET_ERROR;
	}
	//USBpowered = (buffer[8]&STATUSFLAGS_PMOD) == STATUSFLAGS_PMOD ;
	in->AnyDevices = anydevices_yes ;
	for (i = 16; i < readlen; i++) {
		BYTE val = buffer[i];
		LEVEL_DEBUG("Reset: Status bytes[%d]: %X", i, val);
		if (val != ONEWIREDEVICEDETECT) {
			// check for NRS bit (0x01)
			if (val & COMMCMDERRORRESULT_NRS) {
				// empty bus detected, no presence pulse detected
				in->AnyDevices = anydevices_no;
				LEVEL_DATA("no presense pulse detected");
			}
		}
	}
	return BUS_RESET_OK;
}