Statistics
| Branch: | Tag: | Revision:

amiro-os / components / bus / i2c / mux / pca9544.tpp @ 58fe0e0b

History | View | Annotate | Download (2.469 KB)

1 58fe0e0b Thomas Schöpping
#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 */