/* Strong PullUp *0:pullupnotactive,elsedurationinmilliseconds
*/ int spu_sleep; /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup *shouldbeactiveornotforwrites.
*/
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 *theinputbuffer,thedevicefailsthebulktransferand *clearstheinputbuffer.Itcouldreadthemaximumsizeof *thedatabuffer,butthendoyoureturnthefirst,last,or *somesetofthemiddlesizebytes?Aslongastherestof *thecodeiscorrecttherewillbesizebyteswaiting.A *calltods_wait_statuswillwaituntilthedeviceisidle *andanydatatobereceivedwouldhavebeenavailable.
*/
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); #if0 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. *Theextendedstatusincludesnewdevicedetection(maybesomeone *candosomethingwithit).
*/ 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 *wouldhavealreadytoldtheuserthatandwecan'tdoanything *aboutitinsoftwareanyway.
*/ if (count >= 100 || err < 0) return -1; else return0;
}
staticint ds_reset(struct ds_device *dev)
{ int err;
/* Other potentionally interesting flags for reset. * *COMM_NTF:Returnresultregisterfeedback.Thiscouldbeusedto *detectsomeconditionssuchasshort,alarmingpresence,or *detectifanewdevicewasdetected. * *COMM_SEwhichallowsSPEED_NORMAL,SPEED_FLEXIBLE,SPEED_OVERDRIVE: *Selectthedatatransferrate.
*/
err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL); if (err) return err;
return0;
}
#if0 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 *thesameasthehardwarewaslastprogrammedto,thereisalso *nothingmoretodo.Comparewiththerecalculatedvaluems *ratherthandelordelaywhichcanhaveadifferentvalue.
*/ if (delay == 0 || ms == dev->spu_sleep) return err;
/* Set COMM_ICP to write without a readback. Note, this will *produceonetimeslot,adownfollowedbyanupwithCOMM_D *onlydetermingthetiming.
*/
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 *bethatdevice(ifitisstillonthebusmostlikely). * *Ifthenumberofdevicesfoundislessthanorequaltothe *search_limit,thatnumberofIDswillbereturned.Ifthereare *more,search_limitIDswillbereturnedfollowedbyanon-zero *discrepencyvalue.
*/ 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 *discovering8devices(1bulktransferand1/2FIFOsize)atatime.
*/ constunsignedlong jtime = msecs_to_jiffies(1000*8/75); /* FIFO 128 bytes, bulk packet size 64, read a multiple of the *packetsize.
*/ const size_t bufsize = 2 * 64;
u64 *buf, *found_ids;
buf = kmalloc(bufsize, GFP_KERNEL); if (!buf) return;
/* Reset the device as it can be in a bad state. *Thisisnecessarybecauseablockwritewillwaitfordata *tobeplacedintheoutputbufferandblockanylater *commandswhichwillkeepaccumulatingandthedevicewill *notbeidle.Anothercaseisremovingtheds2490module *whileabussearchisinprogress,somehowafewcommands *getthrough,buttheinputtransfersfailleavingdatain *theinputbuffer.Thiswillcausethenextreadtofail *seethenoteinds_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 *samplethelinelevel.Forwrite_bitthatmeansitisexpectedto *setittothatvalueandleaveitthere.ds2490onlysupportsan *individualtimeslotatthelowestlevel.Therequirementfrom *pullingthebusstatedowntoreadingthestateis15us,something *thatisn'trealisticontheUSBbusanyway. 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;
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.