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