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

PCA9544a.h

Committer:
ninensei
Date:
2017-09-14
Revision:
2:31aceaca418e
Parent:
pca9544a.h@ 1:4d19097c0571

File content as of revision 2:31aceaca418e:

/* mbed Microcontroller Library
 * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** \addtogroup drivers */

/** Support for the NXP PCA9544A 4-channel I2C switch.
 *
 * Example:
 * @code
 *
 * #include "mbed.h"
 * #include "PCA9544A.h"
 *
 * // PCA9544A strapped for address option 0 (7-bit I2C address 0x70)
 *
 * I2C            i2c(I2C_SDA, I2C_SCL);
 * PCA9544A<I2C>  pca9544a(&i2c, 0);
 *
 * int main() {
 *     bool                ok;
 *
 *     // Enable channel 1
 *     bool ok = _pca9544a->select_channel(1);
 *     if (ok) {
 *         printf("I2C device on channel 1 is now accessible\r\n);
 *     } else {
 *         printf("pca9544a error!\r\n");
 *     }
 *
 *     // Disconnect all downstream devices from the I2C bus
 *     _pca9544a->reset();
 * }
 * @endcode
 * @ingroup drivers
 */

#pragma once

#define PCA9544A_BASE_ADDR_7BIT     0x70
#define MAX_CHANNELS                4

template <class T>
class PCA9544A
{
public:
    /**
    * Constructor
    *
    * @param i2c I2C class servicing the multiplexer
    * @param addr_3bit address of the multiplexer (A0-A2 pin strapping)
    *          Valid values are 0-7
    */
    PCA9544A(T * i2c, uint8_t addr_3bit) : _i2c(i2c) {
        _addr_8bit = ((addr_3bit & 0x7) + PCA9544A_BASE_ADDR_7BIT) << 1;
    }

    /**
    * Reset the multiplexer.  All devices connected to the downstream side of
    * the multiplexer are removed from the I2C bus.  Reset is accomplished by
    * deselecting all channels through soft configuration.
    *
    * @returns true if successful
    */
    bool reset(void) {
        const char channel = 0;
        return _i2c->write(_addr_8bit, &channel, 1) == 0;
    }

    /**
    * Enable access to one of the eight devices on the downstream side of
    * the multiplexer.
    *
    * @param channel channel to activate.  Valid values are 0-7.
    *
    * @returns true if successful
    */
    bool select_channel(const uint8_t channel) {
        if (channel < MAX_CHANNELS) {
            char channel_mask = 0x4 | channel;
            return _i2c->write(_addr_8bit, (const char *)&channel_mask, 1) == 0;
        } else {
            return false;
        }
    }

protected:
    int     _addr_8bit;
    T      *_i2c;
};