1 /*
2 OWFS -- One-Wire filesystem
3 OWHTTPD -- One-Wire Web Server
4 Written 2003 Paul H Alfille
5 email: paul.alfille@gmail.com
6 Released under the GPL
7 See the header file: ow.h for full attribution
8 1wire/iButton system from Dallas Semiconductor
9 */
10
11 #include <config.h>
12 #include "owfs_config.h"
13 #include "ow.h"
14 #include "ow_counters.h"
15 #include "ow_connection.h"
16 #include "ow_codes.h"
17
18 // Send 8 bits of communication to the 1-Wire Net
19 // Delay delay msec and return to normal
20 //
BUS_PowerByte(BYTE data,BYTE * resp,UINT delay,const struct parsedname * pn)21 GOOD_OR_BAD BUS_PowerByte(BYTE data, BYTE * resp, UINT delay, const struct parsedname *pn)
22 {
23 GOOD_OR_BAD ret;
24 struct connection_in * in = pn->selected_connection ;
25
26 /* Special handling for some adapters that can handle independent channels
27 * but others, like the DS2482-800 aren't completely independent
28 * */
29
30 /* Very tricky -- we will release the port but not the channel
31 * so other threads can use the port's other channels
32 * but we have to be careful of deadlocks
33 * by fully releasing before relocking.
34 * We are locking and releasing out of sequence
35 * */
36
37 /* At the end, we need to relock because that's what the surrounding code expects
38 * -- that this routine is called with locked port and channel
39 * and leaves with same
40 * */
41
42 if ( in->iroutines.PowerByte != NO_POWERBYTE_ROUTINE ) {
43 // use available byte level routine
44 ret = (in->iroutines.PowerByte) (data, resp, delay, pn);
45 } else if ( in->iroutines.PowerBit != NO_POWERBIT_ROUTINE && in->iroutines.sendback_bits != NO_SENDBACKBITS_ROUTINE ) {
46 // use available bit level routine
47 BYTE sending[8];
48 BYTE receive[8] ;
49 int i ;
50 for ( i = 0 ; i < 8 ; ++i ) { // load up bits
51 sending[i] = UT_getbit(&data,i) ? 0xFF : 0x00 ;
52 }
53 ret = BUS_sendback_bits( sending, receive, 7, pn ) ; // send first 7 bits
54 if ( GOOD(ret) ) {
55 ret = BUS_PowerBit( sending[7], &receive[7], delay, pn ) ; // last bit with power and delay
56 }
57 for ( i = 0 ; i < 8 ; ++i ) {
58 UT_setbit( resp, i, receive[i] ) ;
59 }
60 } else { // send with no true power applied
61 if (in->iroutines.flags & ADAP_FLAG_unlock_during_delay) {
62 /* Can unlock port (but not channel) */
63 ret = BUS_sendback_data(&data, resp, 1, pn);
64 PORTUNLOCKIN(in);
65 // other channels are accessible, but this channel is still locked
66 // delay
67 UT_delay(delay);
68 CHANNELUNLOCKIN(in); // have to release channel, too
69 // now need to relock for further work in transaction
70 BUSLOCKIN(in);
71 } else {
72 // send with no true power applied
73 ret = BUS_sendback_data(&data, resp, 1, pn);
74 // delay
75 UT_delay(delay);
76 }
77 }
78 if ( BAD(ret) ) {
79 STAT_ADD1_BUS(e_bus_pullup_errors, in);
80 return gbBAD ;
81 }
82 return gbGOOD ;
83 }
84