Beispiel #1
0
static ZERO_OR_ERROR FS_Mclear(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	int init = 1;

	if ( BAD( Cache_Get_SlaveSpecific(&init, sizeof(init), SlaveSpecificTag(INI), pn)) ) {
		OWQ_Y(owq) = 1;
		if ( FS_r_strobe(owq) != 0 ) {	// set reset pin to strobe mode
			return -EINVAL;
		}
		RETURN_ERROR_IF_BAD( OW_w_pio(0x30, pn) );

		UT_delay(100);
		// init
		RETURN_ERROR_IF_BAD( OW_w_pio(0x38, pn) ) ;
		UT_delay(10);
		// Enable Display, Cursor, and Blinking
		// Entry-mode: auto-increment, no shift
		RETURN_ERROR_IF_BAD( OW_w_pio(0x0F, pn) ) ;
		RETURN_ERROR_IF_BAD( OW_w_pio(0x06, pn) ) ;
		Cache_Add_SlaveSpecific(&init, sizeof(init), SlaveSpecificTag(INI), pn);
	}
	// clear
	RETURN_ERROR_IF_BAD( OW_w_pio(0x01, pn) );
	UT_delay(2);
	return FS_Mhome(owq);
}
Beispiel #2
0
static GOOD_OR_BAD LINK_detect_serial(struct connection_in * in)
{
	struct port_in * pin = in->pown ;
	/* Set up low-level routines */
	LINK_setroutines(in);
	pin->timeout.tv_sec = Globals.timeout_serial ;
	pin->timeout.tv_usec = 0 ;

	/* Open the com port */
	RETURN_BAD_IF_BAD(COM_open(in)) ;
	
	//COM_break( in ) ;
	LEVEL_DEBUG("Slurp in initial bytes");
	LINK_slurp( in ) ;
	UT_delay(100) ; // based on http://morpheus.wcf.net/phpbb2/viewtopic.php?t=89&sid=3ab680415917a0ebb1ef020bdc6903ad
	LINK_slurp( in ) ;
	
	RETURN_GOOD_IF_GOOD( LINK_version(in) ) ;
	LEVEL_DEFAULT("LINK detection error");
	
	serial_powercycle(in) ;
	LEVEL_DEBUG("Slurp in initial bytes");
	LINK_slurp( in ) ;
	UT_delay(100) ; // based on http://morpheus.wcf.net/phpbb2/viewtopic.php?t=89&sid=3ab680415917a0ebb1ef020bdc6903ad
	LINK_slurp( in ) ;
	
	RETURN_GOOD_IF_GOOD( LINK_version(in) ) ;
	LEVEL_DEFAULT("LINK detection error");
	COM_close(in) ;
	return gbBAD;
}
Beispiel #3
0
static void LINK_set_baud(struct connection_in * in)
{
	struct port_in * pin = in->pown ;
	char * speed_code ;

	if ( pin->type == ct_telnet ) {
		// telnet pinned at 115200
		return ;
	}

	COM_BaudRestrict( &(pin->baud), B9600, B19200, B38400, B57600, 0 ) ;

	LEVEL_DEBUG("to %d",COM_BaudRate(pin->baud));
	// Find rate parameter
	switch ( pin->baud ) {
		case B9600:
			COM_break(in) ;
			LINK_flush(in);
			return ;
		case B19200:
			speed_code = "," ;
			break ;
		case B38400:
			speed_code = "`" ;
			break ;
#ifdef B57600
		/* MacOSX support max 38400 in termios.h ? */
		case B57600:
			speed_code = "^" ;
			break ;
#endif
		default:
			LEVEL_DEBUG("Unrecognized baud rate");
			return ;
	}

	LEVEL_DEBUG("LINK change baud string <%s>",speed_code);
	LINK_flush(in);
	if ( BAD( LINK_write(LINK_string(speed_code), 1, in) ) ) {
		LEVEL_DEBUG("LINK change baud error -- will return to 9600");
		pin->baud = B9600 ;
		++in->changed_bus_settings ;
		return ;
	}


	// Send configuration change
	LINK_flush(in);

	// Change OS view of rate
	UT_delay(5);
	COM_change(in) ;
	UT_delay(5);
	LINK_slurp(in);

	return ;
}
Beispiel #4
0
/* Returns 0=good
   bad = -EIO
 */
GOOD_OR_BAD BUS_PowerBit(BYTE data, BYTE * resp, UINT delay, const struct parsedname *pn)
{
	GOOD_OR_BAD ret;
	struct connection_in * in = pn->selected_connection ;

	/* Special handling for some adapters that can handle independent channels
	 * but others, like the DS2482-800 aren't completely independent
	 * */
	 
	/* Very tricky -- we will release the port but not the channel 
	 * so other threads can use the port's other channels
	 * but we have to be careful of deadlocks
	 * by fully releasing before relocking.
	 * We are locking and releasing out of sequence
	 * */

	/* At the end, we need to relock because that's what the surrounding code expects 
	 * -- that this routine is called with locked port and channel 
	 * and leaves with same
	 * */

	if ( in->iroutines.PowerBit !=NO_POWERBIT_ROUTINE ) {
		// use available bit level routine
		ret = (in->iroutines.PowerBit) (data, resp, delay, pn);
	} else { // send a bit and delay (use normal pull-up for power)
		if (in->iroutines.flags & ADAP_FLAG_unlock_during_delay) {
			ret = BUS_sendback_bits(&data, resp, 1, pn);
			/* Can unlock port (but not channel) */
			PORTUNLOCKIN(in);
			// other channels are accessible, but this channel is still locked
			// delay
			UT_delay(delay);
			CHANNELUNLOCKIN(in); // have to release channel, too
			// now need to relock for further work in transaction
			BUSLOCKIN(in);
			// Wait for other thread to complete
		} else {
			// send the packet but keep port locked
			// No real "power" in the default case
			ret = BUS_sendback_bits(&data, resp, 1, pn);
			// delay
			UT_delay(delay);
		}
	}
	if ( BAD(ret) ) {
		STAT_ADD1_BUS(e_bus_pullup_errors, in);
		return gbBAD ;
	}
	return gbGOOD ;
}
Beispiel #5
0
static ZERO_OR_ERROR FS_Mhome(struct one_wire_query *owq)
{
	// home
	RETURN_ERROR_IF_BAD( OW_w_pio(0x02, PN(owq)) );
	UT_delay(2);
	return 0;
}
Beispiel #6
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 ;
}
Beispiel #7
0
// do the configuration stuff
static GOOD_OR_BAD DS2480_big_configuration(struct connection_in * in)
{
    BYTE single_bit = CMD_COMM | BITPOL_ONE |  DS2480b_speed_byte(in) ;
    BYTE single_bit_response ;

    // Now set desired baud and polarity
    // BUS_reset will do the actual changes
    in->changed_bus_settings = 1 ; // Force a mode change
    // Send a reset again
    DS2480_reset_in(in) ;

    // delay to let line settle
    UT_delay(4);

    // default W1LT = 10us (write-1 low time)
    RETURN_BAD_IF_BAD(DS2480_configuration_write(PARMSEL_WRITE1LOW, PARMSET_Write10us, in)) ;

    // default DSO/WORT = 8us (data sample offset / write 0 recovery time )
    RETURN_BAD_IF_BAD(DS2480_configuration_write(PARMSEL_SAMPLEOFFSET, PARMSET_SampOff8us, in)) ;

    // Strong pullup duration = infinite
    RETURN_BAD_IF_BAD(DS2480_configuration_write(PARMSEL_5VPULSE, PARMSET_infinite, in)) ;

    // Program pulse duration = 512usec
    RETURN_BAD_IF_BAD(DS2480_configuration_write(PARMSEL_12VPULSE, PARMSET_512us, in)) ;

    // Send a single bit
    // The datasheet wants this
    RETURN_BAD_IF_BAD(DS2480_sendback_cmd(&single_bit, &single_bit_response, 1, in)) ;

    /* Apparently need to reset again to get the version number properly */
    return gbRESET( DS2480_reset_in(in)  ) ;
}
Beispiel #8
0
// RESET called with bus locked
RESET_TYPE BUS_reset(const struct parsedname *pn)
{
	struct connection_in * in = pn->selected_connection ;
	STAT_ADD1_BUS(e_bus_resets, in);

	switch ( (in->iroutines.reset) (pn) ) {
	case BUS_RESET_OK:
		in->reconnect_state = reconnect_ok;	// Flag as good!
		if (in->ds2404_found && ((in->iroutines.flags&ADAP_FLAG_no2404delay)==0) ) {
			// extra delay for alarming DS1994/DS2404 complience
			UT_delay(5);
		}

		return BUS_RESET_OK ;
	case BUS_RESET_SHORT:
		/* Shorted 1-wire bus or minor error shouldn't cause a reconnect */
		in->AnyDevices = anydevices_unknown;
		LEVEL_CONNECT("1-wire bus short circuit.");
		STAT_ADD1_BUS(e_bus_short_errors, in);
		return BUS_RESET_SHORT;
	case BUS_RESET_ERROR:
		if ( in->ds2404_found ) {
			// extra reset for DS1994/DS2404 might be needed
			if ( (in->iroutines.reset) (pn) == BUS_RESET_OK ) {
				return BUS_RESET_OK ;
			}
		}
	default:
		in->reconnect_state++;	// Flag for eventual reconnection
		LEVEL_DEBUG("Reset error. Reconnection %d/%d",in->reconnect_state,reconnect_error); 
		STAT_ADD1_BUS(e_bus_reset_errors, in);
		return BUS_RESET_ERROR ;
	}
}
Beispiel #9
0
static GOOD_OR_BAD LINK_detect_net(struct connection_in * in)
{
	struct port_in * pin = in->pown ;
	/* Set up low-level routines */
	LINKE_setroutines(in);
	pin->timeout.tv_sec = 0 ;
	pin->timeout.tv_usec = 300000 ;

	/* Open the tcp port */
	RETURN_BAD_IF_BAD( COM_open(in) ) ;
	
	LEVEL_DEBUG("Slurp in initial bytes");
//	LINK_slurp( in ) ;
	UT_delay(1000) ; // based on http://morpheus.wcf.net/phpbb2/viewtopic.php?t=89&sid=3ab680415917a0ebb1ef020bdc6903ad
	LINK_slurp( in ) ;
//	LINK_flush(in);

	pin->dev.telnet.telnet_negotiated = needs_negotiation ;
	RETURN_GOOD_IF_GOOD( LINK_version(in) ) ;

	// second try -- send a break and line settings
	LEVEL_DEBUG("Second try -- send BREAK");
	COM_flush(in) ;
	COM_break(in);
	telnet_change(in);
//	LINK_slurp( in ) ;
	RETURN_GOOD_IF_GOOD( LINK_version(in) ) ;

	LEVEL_DEFAULT("LINK detection error");
	COM_close(in) ;
	return gbBAD;
}
Beispiel #10
0
/* send A/D conversion command */
static GOOD_OR_BAD OW_convert( int simul_good, int delay, struct parsedname *pn)
{
	BYTE convert[] = { _1W_CONVERT, 0x0F, 0x00, 0xFF, 0xFF, };
	struct transaction_log tpower[] = {
		TRXN_START,
		TRXN_WR_CRC16(convert, 3, 0),
		TRXN_END,
	};
	struct transaction_log tdead[] = {
		TRXN_START,
		TRXN_WRITE3(convert),
		TRXN_READ1(&convert[3]),
		TRXN_POWER( &convert[4], delay ) ,
		TRXN_CRC16(convert, 5),
		TRXN_END,
	};

	/* See if a conversion was globally triggered */
	if ( GOOD(OW_get_power(pn) ) ) {
		if ( simul_good ) { 
			return FS_Test_Simultaneous( simul_volt, delay, pn) ;
		} 
		// Start conversion
		// 6 msec for 16bytex4channel (5.2)
		RETURN_BAD_IF_BAD(BUS_transaction(tpower, pn));
		UT_delay(delay);			/* don't need to hold line for conversion! */
	} else {
		// Start conversion
		// 6 msec for 16bytex4channel (5.2)
		RETURN_BAD_IF_BAD(BUS_transaction(tdead, pn)) ;
	}
	return gbGOOD;
}
Beispiel #11
0
/* USB is a special case, in gets reenumerated, so we look for similar DS2401 chip */
GOOD_OR_BAD TestConnection(const struct parsedname *pn)
{
	GOOD_OR_BAD ret = 0;
	struct connection_in *in ;

	if ( pn == NO_PARSEDNAME ) {
		return gbGOOD ;
	}

	in = pn->selected_connection ;
	if ( in == NO_CONNECTION ) {
		return gbGOOD ;
	}
	
	// Test without a lock -- efficient
	if ( in->reconnect_state < reconnect_error ) {
		return gbGOOD;
	}
	
	// Lock the bus
	BUSLOCK(pn);
	// Test again
	if (in->reconnect_state >= reconnect_error) {
		// Add Statistics
		STAT_ADD1_BUS(e_bus_reconnects, in);

		// Close the bus (should leave enough reconnection information available)
		BUS_close(in);	// already locked

		// Call reconnection
		in->AnyDevices = anydevices_unknown ;
		if ( in->iroutines.reconnect != NO_RECONNECT_ROUTINE ) {
			// reconnect method exists
			ret = (in->iroutines.reconnect) (pn) ;	// call bus-specific reconnect
		} else {
			ret = BUS_detect(in->pown) ;	// call initial opener
		}
		if ( BAD( ret ) ) {
			in->reconnect_state = reconnect_ok + 1 ;
			// delay to slow thrashing
			UT_delay(200);
		} else {
			in->reconnect_state = reconnect_ok;
		}
	}
	BUSUNLOCK(pn);

	if ( BAD( ret ) ) {
		LEVEL_DEFAULT("Failed to reconnect %s bus master!", in->adapter_name);
	} else {
		LEVEL_DEFAULT("%s bus master reconnected", in->adapter_name);
	}

	return ret;
}
Beispiel #12
0
// do the com port and configuration stuff
static GOOD_OR_BAD DS2480_big_reset_serial(struct connection_in * in)
{
    BYTE reset_byte = (BYTE) ( CMD_COMM | FUNCTSEL_RESET | SPEEDSEL_STD );

    // Open the com port in 9600 Baud.
    RETURN_BAD_IF_BAD(COM_open(in)) ;

    // send a break to reset the DS2480
    COM_break(in);

    // It's in command mode now
    in->master.serial.mode = ds2480b_command_mode ;

    // send the timing byte (A reset command at 9600 baud)
    DS2480_write( &reset_byte, 1, in ) ;

    // delay to let line settle
    UT_delay(4);
    // flush the buffers
    DS2480_flush(in);
    // ignore response
    DS2480_slurp( in ) ;
    // Now set desired baud and polarity
    // BUS_reset will do the actual changes
    in->changed_bus_settings = 1 ; // Force a mode change
    // Send a reset again
    LEVEL_DEBUG("Send the initial reset to the bus master.");
    DS2480_reset_in(in) ;

    // delay to let line settle
    UT_delay(400);
    // flush the buffers
    DS2480_flush(in);
    // ignore response
    DS2480_slurp( in ) ;

    // Now set desired baud and polarity
    return DS2480_big_configuration(in) ;
}
Beispiel #13
0
// Send 8 bits of communication to the 1-Wire Net and read the
// 8 bits back from the 1-Wire Net.
// The parameter 'byte' least significant 8 bits are used.  After the
// 8 bits are sent change the level of the 1-Wire net.
// Delay delay msec and return to normal
static GOOD_OR_BAD DS9490_PowerByte(BYTE byte, BYTE * resp, UINT delay, const struct parsedname *pn)
{
	LEVEL_DATA("DS9490_PowerByte start");

	/* This is more likely to be the correct way to handle powerbytes */
	if ( BAD( USB_Control_Msg(COMM_CMD, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte & 0xFF, pn)) ) {
		DS9490_HaltPulse(pn);
		return gbBAD ;
	} else if ( DS9490_read(resp, 1, pn) < 0) {
		/* Read back the result (may be the same as "byte") */
		DS9490_HaltPulse(pn);
		return gbBAD ;
	}
	/* Delay with strong pullup */
	LEVEL_DEBUG("DS9490_PowerByte DELAY:%d", delay);
	UT_delay(delay);
	DS9490_HaltPulse(pn);
	return gbGOOD ;
}
Beispiel #14
0
static GOOD_OR_BAD DS2482_PowerByte(const BYTE byte, BYTE * resp, const UINT delay, const struct parsedname *pn)
{
    struct connection_in * in = pn->selected_connection ;

    /* Make sure we're using the correct channel */
    RETURN_BAD_IF_BAD(DS2482_channel_select(in)) ;

    /* Set the power (bit is automatically cleared by reset) */
    TrafficOut("power write", &byte, 1, in ) ;
    RETURN_BAD_IF_BAD(SetConfiguration(  in->master.i2c.configreg | DS2482_REG_CFG_SPU, in)) ;

    /* send and get byte (and trigger strong pull-up */
    RETURN_BAD_IF_BAD(DS2482_send_and_get( in->pown->file_descriptor, byte, resp)) ;
    TrafficOut("power response", resp, 1, in ) ;

    UT_delay(delay);

    return gbGOOD;
}
Beispiel #15
0
static GOOD_OR_BAD OW_Hinit(struct parsedname * pn)
{
	int init = 1;
	// clear, display on, mode
	BYTE start[] = { NIBBLE_ONE(LCD_COMMAND_ATTENTION), };
	BYTE next[] = {
		NIBBLE_ONE(LCD_COMMAND_ATTENTION),
		NIBBLE_ONE(LCD_COMMAND_ATTENTION),
		NIBBLE_ONE(LCD_COMMAND_4_BIT),
		NIBBLE_CTRL(LCD_COMMAND_4_BIT_2_LINES),
	};
	BYTE data[6];

	// already done?
	RETURN_GOOD_IF_GOOD( Cache_Get_SlaveSpecific(&init, sizeof(init), SlaveSpecificTag(INI), pn) )
	
	if ( BAD( OW_w_control(0x04, pn) )	// strobe
		|| BAD( OW_r_reg(data, pn) ) ) {
		LEVEL_DEBUG("Trouble sending strobe to Hobbyboard LCD") ;
		return gbBAD;
	}
	if ( data[5] != 0x84 )	{
		LEVEL_DEBUG("LCD is not powered"); // not powered
		return gbBAD ;
	}
	if ( BAD( OW_c_latch(pn) ) ) {
		LEVEL_DEBUG("Trouble clearing latches") ;
		return gbBAD ;
	}// clear PIOs
	if ( BAD( OW_w_pios(start, 1, pn) ) ) {
		LEVEL_DEBUG("Error sending initial attention");	
		return gbBAD;
	}
	UT_delay(5);
	if ( BAD( OW_w_pios(next, 5, pn) ) ) {
		LEVEL_DEBUG("Error sending setup commands");	
		return gbBAD;
	}
	Cache_Add_SlaveSpecific(&init, sizeof(init), SlaveSpecificTag(INI), pn);
	return gbGOOD ;
}
Beispiel #16
0
static GOOD_OR_BAD LINK_PowerByte(const BYTE data, BYTE * resp, const UINT delay, const struct parsedname *pn)
{
	struct connection_in * in = pn->selected_connection ;
	ASCII buf[3] = "pxx";
	BYTE respond[2+in->CRLF_size] ;
	
	num2string(&buf[1], data);
	
	RETURN_BAD_IF_BAD(LINK_write(LINK_string(buf), 3, in) ) ;
	
	// delay
	UT_delay(delay);
	
	// flush the buffers
	RETURN_BAD_IF_BAD(LINK_write(LINK_string("\r"), 1, in) ) ;
	
	RETURN_BAD_IF_BAD( LINK_readback_data( LINK_string(respond), 2, in) ) ;
	
	resp[0] = string2num((const ASCII *) respond);
	return gbGOOD ;
}
Beispiel #17
0
//  _sendback_bits
//  Send data and return response block
//  return 0=good
static GOOD_OR_BAD LINK_PowerBit(const BYTE data, BYTE * resp, const UINT delay, const struct parsedname *pn)
{
	struct connection_in * in = pn->selected_connection ;
	BYTE buf[2+1+1+in->CRLF_size] ;
	
	buf[0] = '~';			//put in power bit mode
	buf[1] = data ? '1' : '0' ;
	
	// send to LINK (wait for final CR)
	RETURN_BAD_IF_BAD(LINK_write(buf, 2, in) ) ;

	// delay
	UT_delay(delay);
	
	// // take out of power bit mode
	RETURN_BAD_IF_BAD(LINK_write(LINK_string("\r"), 1, in) ) ;
		
	// read back
	RETURN_BAD_IF_BAD( LINK_readback_data(buf, 1, in) ) ;
	
	// place data (converted back to hex) in resp
	resp[0] = (buf[0]=='0') ? 0x00 : 0xFF ;
	return gbGOOD;
}
Beispiel #18
0
static GOOD_OR_BAD BUS_transaction_single(const struct transaction_log *t, const struct parsedname *pn)
{
	GOOD_OR_BAD ret = gbGOOD;
	switch (t->type) {
	case trxn_select:			// select a 1-wire device (by unique ID)
		ret = BUS_select(pn);
		LEVEL_DEBUG("select = %d", ret);
		break;
	case trxn_compare:			// match two strings -- no actual 1-wire
		if ((t->in == NULL) || (t->out == NULL)
			|| (memcmp(t->in, t->out, t->size) != 0)) {
			ret = gbBAD;
		}
		LEVEL_DEBUG("compare = %d", ret);
		break;
	case trxn_bitcompare:			// match two strings -- no actual 1-wire
		if ((t->in == NULL) || (t->out == NULL)
			|| BAD( BUS_compare_bits( t->in, t->out, t->size)) ) {
			ret = gbBAD;
		}
		LEVEL_DEBUG("compare = %d", ret);
		break;
	case trxn_match:			// send data and compare response
		assert(t->in == NULL);	// else use trxn_compare
		if (t->size == 0) {		/* ignore for both cases */
			break;
		} else {
			ret = BUS_send_data(t->out, t->size, pn);
			LEVEL_DEBUG("send = %d", ret);
		}
		break;
	case trxn_bitmatch:			// send data and compare response
		assert(t->in == NULL);	// else use trxn_compare
		if (t->size == 0) {		/* ignore for both cases */
			break;
		} else {
			ret = BUS_send_bits(t->out, t->size, pn);
			LEVEL_DEBUG("send bits = %d", ret);
		}
		break;
	case trxn_read:
		assert(t->out == NULL);	// pure read
		if (t->size == 0) {		/* ignore for all cases */
			break;
		} else if (t->out == NULL) {
			ret = BUS_readin_data(t->in, t->size, pn);
			LEVEL_DEBUG("readin = %d", ret);
		}
		break;
	case trxn_bitread:
		assert(t->out == NULL);	// pure read
		if (t->size == 0) {		/* ignore for all cases */
			break;
		} else if (t->out == NULL) {
			ret = BUS_readin_bits(t->in, t->size, pn);
			LEVEL_DEBUG("readin bits = %d", ret);
		}
		break;
	case trxn_modify:			// write data and read response. No match needed
		ret = BUS_sendback_data(t->out, t->in, t->size, pn);
		LEVEL_DEBUG("modify = %d", ret);
		break;
	case trxn_bitmodify:			// write data and read response. No match needed
		ret = BUS_sendback_bits(t->out, t->in, t->size, pn);
		LEVEL_DEBUG("bit modify = %d", ret);
		break;
	case trxn_blind:			// write data ignore response
		{
			BYTE *dummy = owmalloc(t->size);
			if (dummy != NULL) {
				ret = BUS_sendback_data(t->out, dummy, t->size, pn);
				owfree(dummy);
			} else {
				ret = gbBAD;
			}
		}
		LEVEL_DEBUG("blind = %d", ret);
		break;
	case trxn_power:
		ret = BUS_PowerByte(t->out[0], t->in, t->size, pn);
		LEVEL_DEBUG("power (%d usec) = %d", t->size, ret);
		break;
	case trxn_bitpower:
		ret = BUS_PowerBit(t->out[0], t->in, t->size, pn);
		LEVEL_DEBUG("power bit (%d usec) = %d", t->size, ret);
		break;
	case trxn_program:
		ret = BUS_ProgramPulse(pn);
		LEVEL_DEBUG("program pulse = %d", ret);
		break;
	case trxn_crc8:
		ret = CRC8(t->out, t->size);
		LEVEL_DEBUG("CRC8 = %d", ret);
		break;
	case trxn_crc8seeded:
		ret = CRC8seeded(t->out, t->size, ((UINT *) (t->in))[0]);
		LEVEL_DEBUG("seeded CRC8 = %d", ret);
		break;
	case trxn_crc16:
		ret = CRC16(t->out, t->size);
		LEVEL_DEBUG("CRC16 = %d", ret);
		break;
	case trxn_crc16seeded:
		ret = CRC16seeded(t->out, t->size, ((UINT *) (t->in))[0]);
		LEVEL_DEBUG("seeded CRC16 = %d", ret);
		break;
	case trxn_delay:
		if (t->size > 0) {
			UT_delay(t->size);
		}
		LEVEL_DEBUG("Delay %d", t->size);
		break;
	case trxn_udelay:
		if (t->size > 0) {
			UT_delay_us(t->size);
		}
		LEVEL_DEBUG("Micro Delay %d", t->size);
		break;
	case trxn_reset:
		ret = BUS_reset(pn)==BUS_RESET_OK ? gbGOOD : gbBAD;
		LEVEL_DEBUG("reset = %d", ret);
		break;
	case trxn_end:
		LEVEL_DEBUG("end = %d", ret);
		return gbOTHER;			// special "end" flag
	case trxn_verify:
		{
			struct parsedname pn2;
			memcpy(&pn2, pn, sizeof(struct parsedname));	//shallow copy
			pn2.selected_device = NO_DEVICE;
			if ( BAD( BUS_select(&pn2) )) {
				ret = gbBAD ;
			} else if ( BAD(BUS_verify(t->size, pn) )) {
				ret = gbBAD ;
			} else {
				ret = gbGOOD;
			}
			LEVEL_DEBUG("verify = %d", ret);
		}
		break;
	case trxn_nop:
		ret = gbGOOD;
		break;
	}
	return ret;
}
Beispiel #19
0
/* 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;
}
Beispiel #20
0
static GOOD_OR_BAD Bundle_unpack(struct transaction_bundle *tb)
{
	int packet_index;
	const struct transaction_log *tl;
	BYTE *data = MemblobData(&(tb->mb));
	GOOD_OR_BAD ret = gbGOOD;

	LEVEL_DEBUG("unpacking");

	for (packet_index = 0, tl = tb->start; packet_index < tb->packets; ++packet_index, ++tl) {
		switch (tl->type) {
		case trxn_compare:		// match two strings -- no actual 1-wire
			LEVEL_DEBUG("unpacking #%d COMPARE", packet_index);
			if ((tl->in == NULL) || (tl->out == NULL)
				|| (memcmp(tl->in, tl->out, tl->size) != 0)) {
				ret = gbBAD;
			}
			break;
		case trxn_bitcompare:			// match two strings -- no actual 1-wire
			if ((tl->in == NULL) || (tl->out == NULL)
				|| BAD( BUS_compare_bits( tl->in, tl->out, tl->size)) ) {
				ret = gbBAD;
			}
			break ;
		case trxn_match:		// send data and compare response
			LEVEL_DEBUG("unpacking #%d MATCH", packet_index);
			if (memcmp(tl->out, data, tl->size) != 0) {
				ret = gbBAD;
			}
			data += tl->size;
			break;
		case trxn_read:
		case trxn_modify:		// write data and read response. No match needed
			LEVEL_DEBUG("unpacking #%d READ MODIFY", packet_index);
			memmove(tl->in, data, tl->size);
			data += tl->size;
			break;
		case trxn_blind:
			LEVEL_DEBUG("unpacking #%d BLIND", packet_index);
			data += tl->size;
			break;
		case trxn_power:
		case trxn_program:
			LEVEL_DEBUG("unpacking #%d POWER PROGRAM", packet_index);
			memmove(tl->in, data, 1);
			data += 1;
			UT_delay(tl->size);
			break;
		case trxn_crc8:
			LEVEL_DEBUG("unpacking #%d CRC8", packet_index);
			if (CRC8(tl->out, tl->size) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_crc8seeded:
			LEVEL_DEBUG("unpacking #%d CRC8 SEEDED", packet_index);
			if (CRC8seeded(tl->out, tl->size, ((UINT *) (tl->in))[0]) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_crc16:
			LEVEL_DEBUG("unpacking #%d CRC16", packet_index);
			if (CRC16(tl->out, tl->size) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_crc16seeded:
			LEVEL_DEBUG("unpacking #%d CRC16 SEEDED", packet_index);
			if (CRC16seeded(tl->out, tl->size, ((UINT *) (tl->in))[0]) != 0) {
				ret = gbBAD;
			}
			break;
		case trxn_delay:
			LEVEL_DEBUG("unpacking #%d DELAY", packet_index);
			UT_delay(tl->size);
			break;
		case trxn_udelay:
			LEVEL_DEBUG("unpacking #%d UDELAY", packet_index);
			UT_delay_us(tl->size);
			break;
		case trxn_reset:
		case trxn_end:
		case trxn_verify:
			// should never get here
			LEVEL_DEBUG("unpacking #%d RESET END VERIFY", packet_index);
			ret = gbBAD;
			break;
		case trxn_nop:
		case trxn_select:
			LEVEL_DEBUG("unpacking #%d NOP or SELECT", packet_index);
			break;
		case trxn_bitmatch:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitmatch");
			break ;
		case trxn_bitmodify:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitmodify");
			break ;
		case trxn_bitread:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitread");
			break ;
		case trxn_bitpower:
			LEVEL_DEBUG("Unsupported transaction request trxn_bitpower");
			break ;
		}
		if ( BAD(ret) ) {
			break;
		}
	}

	// clear the bundle
	MemblobClear(&tb->mb);
	tb->packets = 0;
	tb->select_first = 0;

	return ret;
}