Statistics
| Branch: | Tag: | Revision:

amiro-os / components / bus / i2c / mux / pca9544.tpp @ 6acaea07

History | View | Annotate | Download (2.469 KB)

1
#include <chdebug.h>
2

    
3
namespace amiro {
4

    
5
template <bool ignore_deselect>
6
PCA9544<ignore_deselect>::
7
PCA9544(I2CDriver *driver, const uint8_t master_id) :
8
	I2CMultiplexer(driver),
9
	master_id(master_id),
10
	selected(-1) {
11

    
12
	chDbgCheck(master_id <= 0x07u, "PCA9544 ctor master_id");
13
	this->tx_params.addr = (PCA9544::SLA | this->master_id);
14
	this->rx_params.addr = (PCA9544::SLA | this->master_id);
15

    
16
}
17

    
18
template <bool ignore_deselect>
19
msg_t
20
PCA9544<ignore_deselect>::
21
select(const uint8_t bus_id) {
22

    
23
	chDbgCheck(bus_id <= 0x03u, "PCA9544 select bus_id");
24

    
25
	uint8_t tmp = PCA9544::BUS_ON | bus_id;
26

    
27
	if (bus_id == this->selected)
28
		return RDY_OK;
29

    
30
	this->selected = bus_id;
31

    
32
	this->tx_params.txbuf = &tmp;
33
	this->tx_params.txbytes = 1;
34
	this->tx_params.rxbytes = 0;
35
	return this->masterTransmit(&this->tx_params); // TODO select timeout
36

    
37
}
38

    
39
template <>
40
inline msg_t
41
PCA9544<true>::
42
deselect() {
43

    
44
	return RDY_OK;
45

    
46
}
47

    
48
template <>
49
inline msg_t
50
PCA9544<false>::
51
deselect() {
52

    
53
	uint8_t tmp = PCA9544::BUS_OFF;
54

    
55
	this->selected = -1;
56
	this->tx_params.txbuf = &tmp;
57
	this->tx_params.txbytes = 1;
58
	this->tx_params.rxbytes = 0;
59
	return this->masterTransmit(&this->tx_params); // TODO select timeout
60

    
61
}
62

    
63
template <bool ignore_deselect>
64
uint8_t
65
PCA9544<ignore_deselect>::
66
getInterruptSource() {
67

    
68
	uint8_t tmp;
69
	this->rx_params.rxbuf = &tmp;
70
	this->rx_params.rxbytes = 1;
71
	this->masterReceive(&this->rx_params); // TODO select timeout
72
	return tmp;
73

    
74
}
75

    
76
template <bool ignore_deselect>
77
uint8_t
78
PCA9544<ignore_deselect>::
79
getCheck(void) {
80

    
81
	const int8_t rxBufferMask = 0x07; /** We are only intrested in the first three bits*/
82
	int8_t txBuffer, resTx, resRx;
83
	uint8_t rxBuffer[2];
84

    
85
	// Copy the data, because some virtual driver can write into it
86
	I2CTxParams tx_params = this->tx_params;
87
	I2CRxParams rx_params = this->rx_params;
88

    
89
	tx_params.txbuf = (uint8_t*) &txBuffer;
90
	tx_params.txbytes = 1;
91
	tx_params.rxbytes = 0;
92
	rx_params.rxbuf = rxBuffer;
93
	rx_params.rxbytes = 2; /** This is a bug workaround: 1 byte is impossible to read*/
94

    
95
	for (txBuffer = rxBufferMask; txBuffer >= 0x00; txBuffer--) {
96
		this->acquireBus();
97
		resTx = this->masterTransmit(&tx_params);
98
		resRx = this->masterReceive(&rx_params);
99
		this->releaseBus();
100
		// Failed to transmit
101
		if (resTx != RDY_OK || resRx != RDY_OK) {
102
			break;
103
		}
104
		// Check data written to MUX register
105
		if (txBuffer != (rxBuffer[0] & rxBufferMask)) {
106
			break;
107
		}
108
	}
109

    
110
	// Data analysis
111
	if (txBuffer != -1) {
112
		return PCA9544::CHECK_FAIL;
113
	} else {
114
		return PCA9544::CHECK_OK;
115
	}
116
}
117

    
118
} /* amiro */