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