Tuesday, September 9, 2014

Updated PCA9546 library

As mentioned in a previous post, I have updated the PCA9546 library in order to fix the problem of one of the methods of the class being implemented as private when it needs to be public.  I also implemented a constructor that allows initialization of the class without selecting any channel as active.  Lastly, I implemented a change to the selectChannel method to allow deselecting all channels.

As promised, I am posting the entirety of the update here for your convenience.

File: PCA9546.h

#ifndef PCA9546_H
#define PCA9546_h

#ifndef P
#define PBUFSIZE (66)
extern char buf[PBUFSIZE];

#define  P(x) strcpy_P(buf, PSTR(x))
#endif

typedef enum 
{
  PCA9546_ERROR = 0,
  PCA9546_SUCCESS
} PCA9546_Status;

#define PCA9546_NOCHANNEL (0) // No channel selected
#define PCA9546_CHANNEL_1 (1) // Bit 1
#define PCA9546_CHANNEL_2 (2) // Bit 2
#define PCA9546_CHANNEL_3 (4) // Bit 3
#define PCA9546_CHANNEL_4 (8) // Bit 4

class PCA9546
{
public:
  PCA9546(uint8_t i2c_address);
  PCA9546(uint8_t i2c_address, uint8_t channel);
  bool selectChannel(uint8_t channel);
  
  PCA9546_Status status;
  uint8_t channel;

private:
  uint8_t i2c_address;
  uint8_t i2c_read();
  void i2c_write(uint8_t data);
};


#endif

File: PCA9546.cpp

/*
 * PCA9546 Library for Arduino
 *
 * MIT License
 *
 * Copyright Jeff Whitlatch - ko7m - 2014
 */

#include <Arduino.h>
#include <Wire.h>
#include "PCA9546.h"
#include "debug.h"


#define DEBUG(x ...)  // Default to NO debug    
//#define DEBUG(x ...) debugUnique(x)    // UnComment for Debug

// Initialize the PCA9546 and disable all channels
PCA9546::PCA9546(uint8_t PCA9546_address)
  i2c_address = PCA9546_address;

  Wire.begin();
  selectChannel(PCA9546_NOCHANNEL);
}

// Initialize the PCA9546 and enable the channel(s) indicated
PCA9546::PCA9546(uint8_t PCA9546_address, uint8_t channel)
  i2c_address = PCA9546_address;

  Wire.begin();
  selectChannel(channel);
}

// Send a channel selection word to the PCA9546
bool PCA9546::selectChannel(uint8_t channel)
{
  // Sanity check value passed.  Only least significant 4 bits valid
  if (channel <= 0xf)
  {
    i2c_write(channel);
    debug(P("Successfully selected PCA9546 channel"));
    status = PCA9546_SUCCESS;
  }
  else
  {
    debug(P("PCA9546 channel selection failed"));
    status = PCA9546_ERROR;
  }
  return (PCA9546_SUCCESS == status);
}

// Write a byte to I2C device.  There is only a single register.  If multiple bytes written, last one wins.
void PCA9546::i2c_write(uint8_t data)
{
  Wire.beginTransmission(i2c_address);
  Wire.write(data);
  Wire.endTransmission();
}

// Read the one byte register from the I2C device
uint8_t PCA9546::i2c_read()
{
  uint8_t rdata = 0xFF;
  Wire.beginTransmission(i2c_address);
  Wire.requestFrom(i2c_address, (uint8_t)1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
}

No comments:

Post a Comment