/* Strong PullUp * 0: pullup not active, else duration in milliseconds
*/ int spu_sleep; /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup * should be active or not for writes.
*/
u16 spu_bit;
for (i = 16; i < count; ++i) { if (buf[i] == RR_DETECT) {
dev_dbg(dev, "New device detect.\n"); continue;
}
dev_dbg(dev, "Result Register Value: 0x%02x", buf[i]); if (buf[i] & RR_NRS)
dev_dbg(dev, "NRS: Reset no presence or ...\n"); if (buf[i] & RR_SH)
dev_dbg(dev, "SH: short on reset or set path\n"); if (buf[i] & RR_APP)
dev_dbg(dev, "APP: alarming presence on reset\n"); if (buf[i] & RR_VPP)
dev_dbg(dev, "VPP: 12V expected not seen\n"); if (buf[i] & RR_CMP)
dev_dbg(dev, "CMP: compare error\n"); if (buf[i] & RR_CRC)
dev_dbg(dev, "CRC: CRC error detected\n"); if (buf[i] & RR_RDP)
dev_dbg(dev, "RDP: redirected page\n"); if (buf[i] & RR_EOS)
dev_dbg(dev, "EOS: end of search error\n");
}
}
staticint ds_recv_data(struct ds_device *dev, unsignedchar *buf, int size)
{ int count, err;
/* Careful on size. If size is less than what is available in * the input buffer, the device fails the bulk transfer and * clears the input buffer. It could read the maximum size of * the data buffer, but then do you return the first, last, or * some set of the middle size bytes? As long as the rest of * the code is correct there will be size bytes waiting. A * call to ds_wait_status will wait until the device is idle * and any data to be received would have been available.
*/
count = 0;
err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
buf, size, &count, 1000); if (err < 0) { int recv_len;
do {
st->status = 0;
err = ds_recv_status(dev, st); #if 0 if (err >= 0) { int i;
printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); for (i = 0; i < err; ++i)
printk("%02x ", dev->st_buf[i]);
printk("\n");
} #endif
} while (!(st->status & ST_IDLE) && !(err < 0) && ++count < 100);
if (err >= 16 && st->status & ST_EPOF) {
dev_info(&dev->udev->dev, "Resetting device after ST_EPOF.\n");
ds_reset_device(dev); /* Always dump the device status. */
count = 101;
}
/* Dump the status for errors or if there is extended return data. * The extended status includes new device detection (maybe someone * can do something with it).
*/ if (err > 16 || count >= 100 || err < 0)
ds_dump_status(dev, dev->st_buf, err);
/* Extended data isn't an error. Well, a short is, but the dump * would have already told the user that and we can't do anything * about it in software anyway.
*/ if (count >= 100 || err < 0) return -1; else return 0;
}
staticint ds_reset(struct ds_device *dev)
{ int err;
/* Other potentionally interesting flags for reset. * * COMM_NTF: Return result register feedback. This could be used to * detect some conditions such as short, alarming presence, or * detect if a new device was detected. * * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE: * Select the data transfer rate.
*/
err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL); if (err) return err;
return 0;
}
#if 0 staticint ds_set_speed(struct ds_device *dev, int speed)
{ int err;
if (speed != SPEED_OVERDRIVE)
speed = SPEED_FLEXIBLE;
speed &= 0xff;
err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); if (err) return err;
return err;
} #endif/* 0 */
staticint ds_set_pullup(struct ds_device *dev, int delay)
{ int err = 0;
u8 del = 1 + (u8)(delay >> 4); /* Just storing delay would not get the trunication and roundup. */ int ms = del<<4;
/* Enable spu_bit if a delay is set. */
dev->spu_bit = delay ? COMM_SPU : 0; /* If delay is zero, it has already been disabled, if the time is * the same as the hardware was last programmed to, there is also * nothing more to do. Compare with the recalculated value ms * rather than del or delay which can have a different value.
*/ if (delay == 0 || ms == dev->spu_sleep) return err;
/* Set COMM_ICP to write without a readback. Note, this will * produce one time slot, a down followed by an up with COMM_D * only determing the timing.
*/
err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP |
(bit ? COMM_D : 0), 0); if (err) return err;
staticint ds_read_block(struct ds_device *dev, u8 *buf, int len)
{ int err, to_read, rem = len;
if (len > 64 * 1024) return -E2BIG;
do {
to_read = rem <= FIFO_SIZE ? rem : FIFO_SIZE;
err = read_block_chunk(dev, &buf[len - rem], to_read); if (err < 0) return err;
rem -= to_read;
} while (rem);
return err;
}
staticint ds_write_block(struct ds_device *dev, u8 *buf, int len)
{ int err; struct ds_status st;
staticvoid ds9490r_search(void *data, struct w1_master *master,
u8 search_type, w1_slave_found_callback callback)
{ /* When starting with an existing id, the first id returned will * be that device (if it is still on the bus most likely). * * If the number of devices found is less than or equal to the * search_limit, that number of IDs will be returned. If there are * more, search_limit IDs will be returned followed by a non-zero * discrepency value.
*/ struct ds_device *dev = data; int err;
u16 value, index; struct ds_status st; int search_limit; int found = 0; int i;
/* DS18b20 spec, 13.16 ms per device, 75 per second, sleep for * discovering 8 devices (1 bulk transfer and 1/2 FIFO size) at a time.
*/ constunsignedlong jtime = msecs_to_jiffies(1000*8/75); /* FIFO 128 bytes, bulk packet size 64, read a multiple of the * packet size.
*/ const size_t bufsize = 2 * 64;
u64 *buf, *found_ids;
buf = kmalloc(bufsize, GFP_KERNEL); if (!buf) return;
/* * We are holding the bus mutex during the scan, but adding devices via the * callback needs the bus to be unlocked. So we queue up found ids here.
*/
found_ids = kmalloc_array(master->max_slave_count, sizeof(u64), GFP_KERNEL); if (!found_ids) {
kfree(buf); return;
}
mutex_lock(&master->bus_mutex);
/* address to start searching at */ if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0) goto search_out;
master->search_id = 0;
value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F |
COMM_RTS;
search_limit = master->max_slave_count; if (search_limit > 255)
search_limit = 0;
index = search_type | (search_limit << 8); if (ds_send_control(dev, value, index) < 0) goto search_out;
if (st.data_in_buffer_status) { /* * Bulk in can receive partial ids, but when it does * they fail crc and will be discarded anyway. * That has only been seen when status in buffer * is 0 and bulk is read anyway, so don't read * bulk without first checking if status says there * is data to read.
*/
err = ds_recv_data(dev, (u8 *)buf, bufsize); if (err < 0) break; for (i = 0; i < err/8; ++i) {
found_ids[found++] = buf[i]; /* * can't know if there will be a discrepancy * value after until the next id
*/ if (found == search_limit) {
master->search_id = buf[i]; break;
}
}
}
if (test_bit(W1_ABORT_SEARCH, &master->flags)) break;
} while (!(st.status & (ST_IDLE | ST_HALT)));
/* only continue the search if some weren't found */ if (found <= search_limit) {
master->search_id = 0;
} elseif (!test_bit(W1_WARN_MAX_COUNT, &master->flags)) { /* * Only max_slave_count will be scanned in a search, * but it will start where it left off next search * until all ids are identified and then it will start * over. A continued search will report the previous * last id as the first id (provided it is still on the * bus).
*/
dev_info(&dev->udev->dev, "%s: max_slave_count %d reached, " "will continue next search.\n", __func__,
master->max_slave_count);
set_bit(W1_WARN_MAX_COUNT, &master->flags);
}
for (i = 0; i < found; i++) /* run callback for all queued up IDs */
callback(master, found_ids[i]);
kfree(found_ids);
}
#if 0 /* * FIXME: if this disabled code is ever used in the future all ds_send_data() * calls must be changed to use a DMAable buffer.
*/ staticint ds_match_access(struct ds_device *dev, u64 init)
{ int err; struct ds_status st;
err = ds_send_data(dev, (unsignedchar *)&init, sizeof(init)); if (err) return err;
/* Reset the device as it can be in a bad state. * This is necessary because a block write will wait for data * to be placed in the output buffer and block any later * commands which will keep accumulating and the device will * not be idle. Another case is removing the ds2490 module * while a bus search is in progress, somehow a few commands * get through, but the input transfers fail leaving data in * the input buffer. This will cause the next read to fail * see the note in ds_recv_data.
*/
ds_reset_device(dev);
dev->master.data = dev;
dev->master.touch_bit = &ds9490r_touch_bit; /* read_bit and write_bit in w1_bus_master are expected to set and * sample the line level. For write_bit that means it is expected to * set it to that value and leave it there. ds2490 only supports an * individual time slot at the lowest level. The requirement from * pulling the bus state down to reading the state is 15us, something * that isn't realistic on the USB bus anyway. dev->master.read_bit = &ds9490r_read_bit; dev->master.write_bit = &ds9490r_write_bit;
*/
dev->master.read_byte = &ds9490r_read_byte;
dev->master.write_byte = &ds9490r_write_byte;
dev->master.read_block = &ds9490r_read_block;
dev->master.write_block = &ds9490r_write_block;
dev->master.reset_bus = &ds9490r_reset;
dev->master.set_pullup = &ds9490r_set_pullup;
dev->master.search = &ds9490r_search;
err = usb_reset_configuration(dev->udev); if (err) {
dev_err(&dev->udev->dev, "Failed to reset configuration: err=%d.\n", err); goto err_out_clear;
}
/* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */
alt = 3;
err = usb_set_interface(dev->udev,
intf->cur_altsetting->desc.bInterfaceNumber, alt); if (err) {
dev_err(&dev->udev->dev, "Failed to set alternative setting %d " "for %d interface: err=%d.\n", alt,
intf->cur_altsetting->desc.bInterfaceNumber, err); goto err_out_clear;
}
iface_desc = intf->cur_altsetting; if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
dev_err(&dev->udev->dev, "Num endpoints=%d. It is not DS9490R.\n",
iface_desc->desc.bNumEndpoints);
err = -EINVAL; goto err_out_clear;
}
/* * This loop doesn'd show control 0 endpoint, * so we will fill only 1-3 endpoints entry.
*/ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.