Skip to content

PCA9506 Module

Samuel Martel edited this page Sep 16, 2020 · 2 revisions

Content

Initialization

To instantiate a Pca9505Module in your application, you must first configure an I2C peripheral in the CubeMX software, then instantiate a I2cModule. The constructor of this module takes a reference to a PCA9505::Config structure that contains all the options used by the PCA9505.

void MyApplication::InitializeModules()
{
  // Instantiate the I2C module used by the PCA.
  I2cModule* i2c = new I2cModule(&hi2c1, "i2c1);
  AddModule(i2c);

  // Configuration structure for the PCA, leave it all to default.
  PCA9505::Config pcaConfig;
  // The PCA is on I2C1.
  pcaConfig.i2c = i2c;

  // Set Interrupt pin, Output from PCA.
  pcaConfig.interrupt.port = IO_EXT1_INT_GPIO_Port;
  pcaConfig.interrupt.pin = IO_EXT1_INT_Pin;

  // Set Output Enable pin, Input of PCA.
  pcaConfig.outputEnable.port = IO_EXT1_OE_GPIO_Port;
  pcaConfig.outputEnable.pin = IO_EXT1_OE_Pin;

  // Set Reset pin, Input of PCA.
  pcaConfig.reset.port = IO_EXT1_RESET_GPIO_Port;
  pcaConfig.reset.pin = IO_EXT1_RESET_Pin;

  // Instantiate PCA9505 module.
  AddModule(new Pca9505Module(pcaConfig, "ioext1");
}

To simplify access to this new instance, you can create a macro that will get that instance in the application:

#define IOEXT1_MODULE    static_cast<Pca9505Module*>(MyApplication::GetModule("ioext1"))

This macro allows you to use the module like this:

IOEXT1_MODULE->WritePin(PCA9505::Ports::p0, PCA9505::Pins::p3, true);

Configuration

The PCA9505 I/O extender offers great versatility when it comes to configuration. Each of the 40 available GPIOs can be configured individually. This is initially done during the instantiation of a Pca9505Module, but can also be done dynamically accomplished at run-time using the ConfigurePin and ConfigurePort methods.

PCA9505::Config

This structure is used by the constructor of the Pca9505Module class. It contains the following members:

I2cModule* i2c

A pointer to the I2cModule that should be used to communicate with the PCA9505.

uint8_t address

The address of the PCA9505 chip on the I2C bus. This address is set by the values of the three address pins on the PCA9505, with a constant base address of 0x40.

Pin outputEnable

A Pin object that contains the GPIO port and the pin number of the pin used for the Output Enable signal of the PCA9505. This pin should be configured as an output. This signal on the PCA9505 is active LOW.

Pin interrupt

A Pin object that contains the GPIO port and the pin number of the pin used for the Interrupt signal of the PCA9505. This pin should be configured as an input. This pin can be linked to an external interrupt, if desired.

Pin reset

A Pin object that contains the GPIO port and the pin number of the pin used for the Reset signal of the PCA9505. This pin should be configured as an output. This signal on the PCA9505 is active LOW.

std::vector<PCA9505::PinConfig> pinConfig

A std::vector of PCA9505::PinConfig that contains overrides for the default pin configuration. If all the pins are used in the default configuration, you can leave this vector empty. Otherwise, simply add all the pin configurations needed for your particular case.

// We want pin 3 of port 2 to be an output in a HIGH state
// and pin 6 of port 4 to be an input with inversed polarity and with interrupts enabled.
PCA9505::Config config;
config.pinConfig.emplace_back({PCA9505::Pins::p3, PCA9505::Ports::p2, PCA9505::Polarity::Normal, PCA9505::Direction::Output, true});
config.pinConfig.emplace_back({PCA9505::Pins::p6, PCA9505::Ports::p4, PCA9505::Polarity::Inverted, PCA9505::Direction::Input, false});

// Config pins, i2c, etc.

AddModule(new Pca9505Module(config, "ioext1"));

PCA9505::PinConfig

The PinConfig structure is used to configure individual pins on the PCA9505. It contains the following members:

PCA9505::Pins pin

The number of the pin we're configuring. Can be:

  • p0: Pin 0
  • p1: Pin 1
  • p2: Pin 2
  • p3: Pin 3
  • p4: Pin 4
  • p5: Pin 5
  • p6: Pin 6
  • p7: Pin 7

PCA9505::Ports port

The port of the pin we're configuring. Can be:

  • p0: Port 0
  • p1: Port 1
  • p2: Port 2
  • p3: Port 3
  • p4: Port 4

PCA9505::Polarity polarity

The polarity of the pin. This is only used when the pin is configured as an input. Can be:

  • Normal: 0
  • Inverted: 1
Polarity Value on Pin Value in Register
Normal 0 0
1 1
Inverted 0 1
1 0

PCA9505::Direction direction

The direction, or function of the pin. Can be:

  • Output: 0
  • Input: 1

PCA9505::Interrupt interrupt

If activated and if configured as an input, a change of state (from LOW to HIGH or from HIGH to LOW) on the pin will result in the interrupt pin being set in the active state. Can be:

  • Enable: 0
  • Disable: 1

bool state

If configured as an output, this member indicates the state that the pin will take (HIGH or LOW)

  • true: Pin is HIGH (1)
  • false: Pin is LOW (0)

Update Pin Configuration

To update the configuration of a single pin after the initialization of the Pca9505Module, use the ConfigurePin method. As a parameter, this function takes a reference to a PCA9505::PinConfig.

// Reconfigure pin 3 of port 2 as an input with inversed polarity and no interrupt.
IOEXT1_MODULE->ConfigurePin({ PCA9505::Pins::p3, 
                              PCA9505::Ports::p2, 
                              PCA9505::Polarity::Inverted, 
                              PCA9505::Direction::Input, 
                              PCA9505::Interrupt::Disable, 
                              false });

Update Port Configuration

You can also update the configuration of an entire port at once using the ConfigurePort method. This method takes as parameter a PCA9505::Ports and 4 uint8_t. Each bits of a uint8_t corresponds to a pin on the port, pin 0 being the LSB and pin 7 being the MSB.

// Configure port 1 to have:
// - Pin 0: Input,  Inverted, No interrupts, LOW
// - Pin 1: Output, Normal,   No interrupts, HIGH
// - Pin 2: Input,  Normal,   No interrupts, LOW
// - Pin 3: Output, Normal,   No interrupts, LOW
// - Pin 4: Input,  Inverted, Interrupts,    LOW
// - Pin 5: Input,  Normal,   Interrupts,    LOW
// - Pin 6: Output, Normal,   No interrupts, HIGH
// - Pin 7: Output, Normal,   No interrupts, LOW
IOEXT1_MODULE->ConfigurePort(PCA9505::Ports::p1, 0x35, 0x11, 0x01, 0x42);

Usage

Enable Output

Method: EnableOutput

Parameters: None

Returns: None

Description: Enable the output pins on the PCA9505.

Example:

IOEXT1_MODULE->EnableOutput();

Disable Output

Method: DisableOutput

Parameters: None

Returns: None

Description: Set the output pins on the PCA9505 in a high impedance state.

Example:

IOEXT1_MODULE->DisableOutput();

Reset

Method: Reset

Parameters: None

Returns: None

Description: Send a reset pulse to the PCA9505.

Example:

IOEXT1_MODULE->Reset();

Hold Reset

Method: HoldReset

Parameters: None

Returns: None

Description: Hold the PCA9505 in its reset state.

Example:

IOEXT1_MODULE->HoldReset();

Release Reset

Method: ReleaseReset

Parameters: None

Returns: None

Description: Release the reset signal of the PCA9505.

Example:

IOEXT1_MODULE->ReleaseReset();

Read Pin

Method: ReadPin

Parameters:

  • PCA9505::Ports port: The port to read
  • PCA9505::Pins pin: The pin to read

Returns: True if the pin is active, false

Description: Release the reset signal of the PCA9505.

Note: This only returns the cached value and doesn't actually read the PCA9505.

Example:

if(IOEXT1_MODULE->ReadPin(PCA9505::Ports::p0, PCA9505::Pins::p5) == true)
{
  DoStuff();
}

Read Port

Method: ReadPort

Parameters:

  • PCA9505::Ports port: The port to read

Returns: PCA9505::PortState the state of the port.

Description: Queries the PCA9505 for the state of the desired port. This method also refreshes the cached values for each ports.

Example:

PCA9505::PortState port = IOEXT1_MODULE->ReadPort(PCA9505::Ports::p3);

if(port.pin2 == true)
{
  DoStuff();
}

Write Pin

Method: WritePin

Parameters:

  • PCA9505::Ports port: The port to write to
  • PCA9505::Pins pin: The pin to set
  • bool state: The state that the pin should take

Returns: None

Description: Set the state of a pin on the PCA9505.

Example:

// Set pin 0 of port 1 to HIGH.
IOEXT1_MODULE->WritePin(PCA9505::Ports::p1, PCA9505::Pins::p0, true);

Write Port

Method: WritePort

Parameters:

  • PCA9505::Ports port: The port to write to
  • uint8_t state: The desired state of each pin on the port

Returns: None

Description: Set the state of an entire port on the PCA9505.

Example:

// Set all pins of port 4 to LOW.
IOEXT1_MODULE->WritePort(PCA9505::Ports::p4, 0x00);