amiro-os / components / bus / i2c / mux / pca9544.tpp @ e0c5d17a
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 */ |