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); }
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; }
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 ; }
/* 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 ; }
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; }
//-------------------------------------------------------------------------- // 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 ; }
// 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) ) ; }
// 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 ; } }
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; }
/* 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; }
/* 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; }
// 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) ; }
// 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 ; }
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; }
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 ; }
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 ; }
// _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; }
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; }
/* 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; }
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; }