Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
laeI2CMux.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // File: laeI2CMux.h
6 //
7 /*! \file
8  *
9  * $LastChangedDate: 2016-01-21 16:50:25 -0700 (Thu, 21 Jan 2016) $
10  * $Rev: 4268 $
11  *
12  * \brief Laelaps PCA9548A I2C multiplexer switch interface.
13  *
14  * The multiplexer allows access to multiple \h_i2c devices including those
15  * that have the same fixed address.
16  *
17  * \author Robin Knight (robin.knight@roadnarrows.com)
18  *
19  * \par Copyright
20  * \h_copy 2015-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Unless otherwise stated explicitly, all materials contained are copyrighted
28  * and may not be used without RoadNarrows LLC's written consent,
29  * except as provided in these terms and conditions or in the copyright
30  * notice (documents and software) or other proprietary notice provided with
31  * the relevant materials.
32  *
33  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
34  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
35  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
36  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
37  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
38  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
41  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
42  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
43  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
44  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
45  *
46  * @EulaEnd@
47  */
48 ////////////////////////////////////////////////////////////////////////////////
49 
50 #ifndef _LAE_I2C_MUX_H
51 #define _LAE_I2C_MUX_H
52 
53 #include <pthread.h>
54 
55 #include "rnr/rnrconfig.h"
56 #include "rnr/log.h"
57 
58 #include "Laelaps/laelaps.h"
59 #include "Laelaps/laeI2C.h"
60 
61 /*!
62  * \brief The \h_laelaps namespace encapsulates all \h_laelaps related
63  * constructs.
64  */
65 #ifndef SWIG
66 namespace laelaps
67 {
68 #endif // SWIG
69 
70  //----------------------------------------------------------------------------
71  // Constants
72  //----------------------------------------------------------------------------
73 
74  //
75  // Addresses
76  //
77  const i2c_addr_t LaeI2CMuxAddrMin = 0x70; ///< \h_i2c minimum 7-bit address
78  const i2c_addr_t LaeI2CMuxAddrMax = 0x77; ///< \h_i2c maximum 7-bit address
79  const i2c_addr_t LaeI2CMuxAddrDft = 0x70; ///< \h_i2c default 7-bit address
80 
81  //
82  // I2C slave channel numbers.
83  //
84  const int LaeI2CMuxChanMin = 0; ///< min channel number
85  const int LaeI2CMuxChanMax = 7; ///< min channel number
86  const int LaeI2CMuxChanNone = 0x100; ///< no channel selected
87 
88  //
89  // Control register.
90  //
91  const byte_t LaeI2CMuxCtlRegMask = 0xff; /// control register mask
92 
93  //----------------------------------------------------------------------------
94  // LaeI2CMux Class
95  //----------------------------------------------------------------------------
96 
97  /*!
98  * TI PCA9548A \h_i2c mulitplexer switch class.
99  */
100  class LaeI2CMux
101  {
102  public:
103  /*!
104  * \brief Initialization constructor.
105  *
106  * \param i2cbus Bound open \h_i2c bus instance.
107  * \param addr I2C Mux address.
108  */
109  LaeI2CMux(LaeI2C &i2cBus, uint_t addr=LaeI2CMuxAddrDft);
110 
111  /*!
112  * \brief Destructor.
113  */
114  virtual ~LaeI2CMux();
115 
116  /*!
117  * \brief Read from a multiplexed \h_i2c slave endpoint device.
118  *
119  * Reads data from a device at the given address on the bound \h_i2c bus.
120  *
121  * \param chan Multiplexed channel number.
122  * \param addr Endpoint \h_i2c device's 7/10-bit address.
123  * \param [out] buf Pointer to the buffer that will receive the data bytes.
124  * \param len Number of bytes to read.
125  *
126  * \return
127  * On success, returns \h_ge 0 number of bytes read.\n
128  * Else returns \h_lt 0 error code.
129  */
130  virtual int read(int chan, uint_t addr, byte_t buf[], size_t len);
131 
132  /*!
133  * \brief Write from an \h_i2c endpoint device.
134  *
135  * Write data to a device at the given address on the bound \h_i2c bus.
136  *
137  * \param chan Multiplexed channel number.
138  * \param addr Endpoint \h_i2c device's 7/10-bit address.
139  * \param [int] buf Pointer to the buffer that will be written.
140  * \param len Number of bytes to write.
141  *
142  * \return
143  * On success, returns \h_ge 0 number of bytes read.\n
144  * Else returns \h_lt 0 error code.
145  */
146  virtual int write(int chan, uint_t addr, byte_t buf[], size_t len);
147 
148  /*!
149  * \brief Perform a write/read transaction to/from an \h_i2c slave endpoint
150  * device.
151  *
152  * \param chan Multiplexed channel number.
153  * \param addr Endpoint \h_i2c device's 7/10-bit address.
154  * \param [in] wbuf Pointer to the buffer that contains the data
155  * to be written.
156  * \param wlen Number of bytes to write.
157  * \param [out] rbuf Pointer to the buffer that will receive the data.
158  * \param rlen Number of bytes to read.
159  * \param usec Delay between write and read operations (usecs).
160  *
161  * \copydoc doc_return_std
162  */
163  virtual int transact(int chan, uint_t addr,
164  const byte_t wbuf[], size_t wlen,
165  byte_t rbuf[], size_t rlen,
166  long usec=0);
167 
168  /*!
169  * \brief Read the current \h_i2c multiplexer enable state.
170  *
171  * \param [out] chanBits Bit map of enable/disable channels.
172  *
173  * \copydoc doc_return_std
174  */
175  virtual int readChannelStates(byte_t &chanBits);
176 
177  /*!
178  * \brief Reset \h_i2c devices on multiplexer bus.
179  *
180  * \copydoc doc_return_std
181  */
182  virtual int reset()
183  {
184  // TODO
185  return -LAE_ECODE_INTERNAL;
186  }
187 
188  /*!
189  * \brief Check if a channel is enabled in the channel bit map.
190  *
191  * \param chan Multiplexed channel number.
192  * \param chanBits Bit map of enable/disable channels.
193  *
194  * \return True or false.
195  */
196  bool isChanEnabled(int chan, byte_t chanBits)
197  {
198  return (LaeI2CMuxCtlRegMask & ((byte_t)(1 << chan) & chanBits)) != 0;
199  }
200 
201  /*!
202  * \brief Get associated \h_i2c device name.
203  *
204  * \return Returns device name string. Empty if no device.
205  */
206  std::string getDevName()
207  {
208  return m_i2cBus.getDevName();
209  }
210 
211  /*!
212  * \brief Check if bound I2C device is open.
213  *
214  * \return Returns true or false.
215  */
216  bool isOpen()
217  {
218  return m_i2cBus.isOpen();
219  }
220 
221  protected:
222  LaeI2C &m_i2cBus; ///< boulnd \h_i2c bus instance
223  uint_t m_addrMux; ///< \h_i2c multiplexer address
224  int m_chan; ///< current active channel
225 
226  // mutual exclusion
227  pthread_mutex_t m_mutex; ///< mutex
228 
229  /*!
230  * \brief Lock the shared resource.
231  *
232  * The lock()/unlock() primitives provide for safe multi-threading.
233  *
234  * \par Context:
235  * Any.
236  */
237  void lock()
238  {
239  pthread_mutex_lock(&m_mutex);
240  }
241 
242  /*!
243  * \brief Unlock the shared resource.
244  *
245  * \par Context:
246  * Any.
247  */
248  void unlock()
249  {
250  pthread_mutex_unlock(&m_mutex);
251  }
252 
253  /*!
254  * \brief Set channel.
255  *
256  * This function does not call the lock/unlock mutex.
257  *
258  * \param chan Multiplexed channel number.
259  *
260  * \copydoc doc_return_std
261  */
262  int setChannel(int chan);
263 
264  }; // class LaeI2CMux
265 
266 #ifndef SWIG
267 } // namespace laelaps
268 #endif // SWIG
269 
270 
271 #endif // _LAE_I2C_MUX_H
int setChannel(int chan)
Set channel.
Definition: laeI2CMux.cxx:185
std::string getDevName()
Get associated I2C device name.
Definition: laeI2C.h:193
const i2c_addr_t LaeI2CMuxAddrDft
I2C default 7-bit address.
Definition: laeI2CMux.h:79
control register mask
Definition: laeI2CMux.h:100
std::string getDevName()
Get associated I2C device name.
Definition: laeI2CMux.h:206
LaeI2CMux(LaeI2C &i2cBus, uint_t addr=LaeI2CMuxAddrDft)
Initialization constructor.
Definition: laeI2CMux.cxx:63
uint_t m_addrMux
I2C multiplexer address.
Definition: laeI2CMux.h:223
const int LaeI2CMuxChanNone
no channel selected
Definition: laeI2CMux.h:86
bool isOpen()
Check if bound I2C device is open.
Definition: laeI2CMux.h:216
Laelaps I2C class interface.
LaeI2C & m_i2cBus
boulnd I2C bus instance
Definition: laeI2CMux.h:222
virtual ~LaeI2CMux()
Destructor.
Definition: laeI2CMux.cxx:71
virtual int reset()
Reset I2C devices on multiplexer bus.
Definition: laeI2CMux.h:182
virtual int write(int chan, uint_t addr, byte_t buf[], size_t len)
Write from an I2C endpoint device.
Definition: laeI2CMux.cxx:106
pthread_mutex_t m_mutex
mutex
Definition: laeI2CMux.h:227
const i2c_addr_t LaeI2CMuxAddrMax
I2C maximum 7-bit address.
Definition: laeI2CMux.h:78
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
const int LaeI2CMuxChanMax
min channel number
Definition: laeI2CMux.h:85
bool isOpen()
Check if device is open.
Definition: laeI2C.h:203
bool isChanEnabled(int chan, byte_t chanBits)
Check if a channel is enabled in the channel bit map.
Definition: laeI2CMux.h:196
virtual int read(int chan, uint_t addr, byte_t buf[], size_t len)
Read from a multiplexed I2C slave endpoint device.
Definition: laeI2CMux.cxx:76
int m_chan
current active channel
Definition: laeI2CMux.h:224
const i2c_addr_t LaeI2CMuxAddrMin
I2C minimum 7-bit address.
Definition: laeI2CMux.h:77
const int LaeI2CMuxChanMin
min channel number
Definition: laeI2CMux.h:84
void lock()
Lock the shared resource.
Definition: laeI2CMux.h:237
static const int LAE_ECODE_INTERNAL
internal error (bug)
Definition: laelaps.h:75
void unlock()
Unlock the shared resource.
Definition: laeI2CMux.h:248
virtual int transact(int chan, uint_t addr, const byte_t wbuf[], size_t wlen, byte_t rbuf[], size_t rlen, long usec=0)
Perform a write/read transaction to/from an I2C slave endpoint device.
Definition: laeI2CMux.cxx:136
virtual int readChannelStates(byte_t &chanBits)
Read the current I2C multiplexer enable state.
Definition: laeI2CMux.cxx:163
Top-level package include file.