NXP PCA9544A device driver: 4-channel I2C-bus multiplexer with interrupt logic

Committer:
ninensei
Date:
Thu Sep 14 00:20:01 2017 +0000
Revision:
1:4d19097c0571
Parent:
0:905d325977dc
Converted to template so that I2C driver derivations can be used (I2C, SoftI2C, etc...); Changed filename to match class name.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ninensei 1:4d19097c0571 1 /* mbed Microcontroller Library
ninensei 1:4d19097c0571 2 * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA
ninensei 1:4d19097c0571 3 *
ninensei 1:4d19097c0571 4 * Licensed under the Apache License, Version 2.0 (the "License");
ninensei 1:4d19097c0571 5 * you may not use this file except in compliance with the License.
ninensei 1:4d19097c0571 6 * You may obtain a copy of the License at
ninensei 1:4d19097c0571 7 *
ninensei 1:4d19097c0571 8 * http://www.apache.org/licenses/LICENSE-2.0
ninensei 1:4d19097c0571 9 *
ninensei 1:4d19097c0571 10 * Unless required by applicable law or agreed to in writing, software
ninensei 1:4d19097c0571 11 * distributed under the License is distributed on an "AS IS" BASIS,
ninensei 1:4d19097c0571 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ninensei 1:4d19097c0571 13 * See the License for the specific language governing permissions and
ninensei 1:4d19097c0571 14 * limitations under the License.
ninensei 1:4d19097c0571 15 */
ninensei 1:4d19097c0571 16
ninensei 1:4d19097c0571 17 /** \addtogroup drivers */
ninensei 1:4d19097c0571 18
ninensei 1:4d19097c0571 19 /** Support for the NXP PCA9544A 4-channel I2C switch.
ninensei 1:4d19097c0571 20 *
ninensei 1:4d19097c0571 21 * Example:
ninensei 1:4d19097c0571 22 * @code
ninensei 1:4d19097c0571 23 *
ninensei 1:4d19097c0571 24 * #include "mbed.h"
ninensei 1:4d19097c0571 25 * #include "PCA9544A.h"
ninensei 1:4d19097c0571 26 *
ninensei 1:4d19097c0571 27 * // PCA9544A strapped for address option 0 (7-bit I2C address 0x70)
ninensei 1:4d19097c0571 28 *
ninensei 1:4d19097c0571 29 * I2C i2c(I2C_SDA, I2C_SCL);
ninensei 1:4d19097c0571 30 * PCA9544A<I2C> pca9544a(&i2c, 0);
ninensei 1:4d19097c0571 31 *
ninensei 1:4d19097c0571 32 * int main() {
ninensei 1:4d19097c0571 33 * bool ok;
ninensei 1:4d19097c0571 34 *
ninensei 1:4d19097c0571 35 * // Enable channel 1
ninensei 1:4d19097c0571 36 * bool ok = _pca9544a->select_channel(1);
ninensei 1:4d19097c0571 37 * if (ok) {
ninensei 1:4d19097c0571 38 * printf("I2C device on channel 1 is now accessible\r\n);
ninensei 1:4d19097c0571 39 * } else {
ninensei 1:4d19097c0571 40 * printf("pca9544a error!\r\n");
ninensei 1:4d19097c0571 41 * }
ninensei 1:4d19097c0571 42 *
ninensei 1:4d19097c0571 43 * // Disconnect all downstream devices from the I2C bus
ninensei 1:4d19097c0571 44 * _pca9544a->reset();
ninensei 1:4d19097c0571 45 * }
ninensei 1:4d19097c0571 46 * @endcode
ninensei 1:4d19097c0571 47 * @ingroup drivers
ninensei 1:4d19097c0571 48 */
ninensei 1:4d19097c0571 49
ninensei 1:4d19097c0571 50 #pragma once
ninensei 0:905d325977dc 51
ninensei 0:905d325977dc 52 #define PCA9544A_BASE_ADDR_7BIT 0x70
ninensei 0:905d325977dc 53 #define MAX_CHANNELS 4
ninensei 0:905d325977dc 54
ninensei 1:4d19097c0571 55 template <class T>
ninensei 0:905d325977dc 56 class PCA9544A
ninensei 0:905d325977dc 57 {
ninensei 0:905d325977dc 58 public:
ninensei 0:905d325977dc 59 /**
ninensei 0:905d325977dc 60 * Constructor
ninensei 0:905d325977dc 61 *
ninensei 0:905d325977dc 62 * @param i2c I2C class servicing the multiplexer
ninensei 0:905d325977dc 63 * @param addr_3bit address of the multiplexer (A0-A2 pin strapping)
ninensei 0:905d325977dc 64 * Valid values are 0-7
ninensei 0:905d325977dc 65 */
ninensei 1:4d19097c0571 66 PCA9544A(T * i2c, uint8_t addr_3bit) : _i2c(i2c) {
ninensei 0:905d325977dc 67 _addr_8bit = ((addr_3bit & 0x7) + PCA9544A_BASE_ADDR_7BIT) << 1;
ninensei 0:905d325977dc 68 }
ninensei 0:905d325977dc 69
ninensei 0:905d325977dc 70 /**
ninensei 0:905d325977dc 71 * Reset the multiplexer. All devices connected to the downstream side of
ninensei 0:905d325977dc 72 * the multiplexer are removed from the I2C bus. Reset is accomplished by
ninensei 0:905d325977dc 73 * deselecting all channels through soft configuration.
ninensei 0:905d325977dc 74 *
ninensei 0:905d325977dc 75 * @returns true if successful
ninensei 0:905d325977dc 76 */
ninensei 0:905d325977dc 77 bool reset(void) {
ninensei 0:905d325977dc 78 const char channel = 0;
ninensei 0:905d325977dc 79 return _i2c->write(_addr_8bit, &channel, 1) == 0;
ninensei 0:905d325977dc 80 }
ninensei 0:905d325977dc 81
ninensei 0:905d325977dc 82 /**
ninensei 0:905d325977dc 83 * Enable access to one of the eight devices on the downstream side of
ninensei 0:905d325977dc 84 * the multiplexer.
ninensei 0:905d325977dc 85 *
ninensei 0:905d325977dc 86 * @param channel channel to activate. Valid values are 0-7.
ninensei 0:905d325977dc 87 *
ninensei 0:905d325977dc 88 * @returns true if successful
ninensei 0:905d325977dc 89 */
ninensei 0:905d325977dc 90 bool select_channel(const uint8_t channel) {
ninensei 0:905d325977dc 91 if (channel < MAX_CHANNELS) {
ninensei 0:905d325977dc 92 char channel_mask = 0x4 | channel;
ninensei 0:905d325977dc 93 return _i2c->write(_addr_8bit, (const char *)&channel_mask, 1) == 0;
ninensei 0:905d325977dc 94 } else {
ninensei 0:905d325977dc 95 return false;
ninensei 0:905d325977dc 96 }
ninensei 0:905d325977dc 97 }
ninensei 0:905d325977dc 98
ninensei 0:905d325977dc 99 protected:
ninensei 1:4d19097c0571 100 int _addr_8bit;
ninensei 1:4d19097c0571 101 T *_i2c;
ninensei 0:905d325977dc 102 };
ninensei 1:4d19097c0571 103