PCAL9714 sample code review

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

PCAL9714 sample code review

Jump to solution
1,163 Views
ahmedd
Contributor II

Hi everyone,

I am trying to write to the register and read it back but it didnt give the same value. I would appreciate if someone would look into my code and correct me. I am using arduino Uno

This is the ino file

#include <Arduino.h>
#include <SPI.h>
#include <stdint.h>
#include "pcal9714.h"

void setup() {
    Serial.begin(9600);
    uint8_t debounce_pins_port0 = 0xFF; // to enable debounce on all pins of port 0
    uint8_t debounce_pins_port1 = 0xFF; // to enable debounce on all pins of port 1
    uint16_t debounce_counter_value = 10;        // debounce time of 10 microseconds
    
    pcal9714_configure_debounce(debounce_pins_port0, debounce_pins_port1, debounce_counter_value);

    // Set all pins you want to monitor as inputs with internal pull-up
    for (uint8_t pin = 0; pin < 8; pin++) {
      pcal9714_set_mode(pin, INPUT_PULLUP);

    }

    // Write a test value to a register
    uint8_t testValue = 0xAA; // Example test value (170 in decimal)
    pcal9714_write(PCAL_CONF_PORT0, testValue);

    // Read the value back
    uint8_t readBackValue = pcal9714_read(PCAL_CONF_PORT0);

    // Print the read back value to the serial monitor
    Serial.print("Wrote: 0x");
    Serial.print(testValue, HEX);
    Serial.print(", Read back: 0x");
    Serial.println(readBackValue, HEX);


        // Set GPIOEXP_LIMIT_SWITCH_HOME_Y_V10 as an output
    pcal9714_set_mode(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10, OUTPUT); // Set the pin as output

    // Set the pin high
    pcal9714_set_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10, HIGH); // Drive the pin high

    // Add a short delay to observe the pin voltage with a multimeter
    delay(1000); // Wait for 1 second

    // Set the pin low
    pcal9714_set_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10, LOW); // Drive the pin low

    // Add another short delay to observe the pin voltage with a multimeter
    delay(1000); // Wait for 1 second


    Serial.println("Direct pin test setup complete.");

}

void loop() {
    // Read the state of a pin (for example, P0_2) and print it to the serial monitor
  int limitSwitchValue = pcal9714_read_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10);
  
  // Print the state to the serial monitor
  Serial.print("Limit Switch State: ");
  Serial.println(limitSwitchValue);

  // Add a delay to prevent flooding the serial monitor
  delay(500);

  static bool pinState = LOW;
  pcal9714_set_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10, pinState);
  pinState = !pinState; // Toggle the state
  delay(1000); // 1 second delay

       
}

 

cpp file

#include <Arduino.h>
#include "pcal9714.h"
#include <SPI.h>


/**
********************************************************************************
* @file pcal9714.cpp
* @author ahmed
* @date 2024-04-22
* @brief Implementation of the pcal9714 driver.
********************************************************************************
*/

/// @brief Configure the pcal9714 device.
void pcal9714_init(void)
{

pinMode(PCAL9714_SPI_CS_PIN, OUTPUT);
digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device
SPI.begin(); // Initialize SPI communication

}

/// @brief Set the value of a pin on the pcal9714 device.
///  channel Channel number.
///  value 1 for high, 0 for low.
void pcal9714_set_pin(uint8_t channel, uint8_t value)
{
uint8_t port = channel / 8; // Determine port (0 or 1)
uint8_t pin = channel % 8; // Determine pin within the port

uint8_t portValue = pcal9714_read_port(port); // Read current port value

if (value) {
portValue |= (1 << pin); // Set the pin to HIGH
} else {
portValue &= ~(1 << pin); // Set the pin to LOW
}

pcal9714_write(PCAL_OUT_PORT0 + port, portValue); // Write to the output port

}

/// @brief Read the value of a pin on the pcal9714 device.
///  channel Channel number.
/// @return The value of the pin.
uint8_t pcal9714_read_pin(uint8_t channel)
{
uint8_t port = channel / 8;
uint8_t pin = channel % 8;

uint8_t portValue = pcal9714_read_port(port);
return (portValue >> pin) & 0x01;
}

/// @brief Set the mode of a pin on the pcal9714 device.
///  channel Channel number.
///  value 1 for high impedence input, 0 for output.
void pcal9714_set_mode(uint8_t channel, uint8_t mode) {
uint8_t port = channel / 8;
uint8_t pin = channel % 8;

// Setting the overall port configuration for push-pull if we're setting the pin as an output
if (mode == OUTPUT) {
uint8_t out_conf = pcal9714_read(PCAL_OUT_CONF_REG);
out_conf |= 0x03; // Set the ports to push-pull mode
pcal9714_write(PCAL_OUT_CONF_REG, out_conf);

// Set the individual pin configuration for pull-up if required
uint8_t out_conf_reg = (port == 0) ? PCAL_OUT_CONF_REG0 : PCAL_OUT_CONF_REG1;
uint8_t out_conf_value = pcal9714_read(out_conf_reg);
out_conf_value |= (1 << pin); // Enable pull-up for the pin
pcal9714_write(out_conf_reg, out_conf_value);
}

// Then set the pin direction (input/output)
uint8_t config_reg = (port == 0) ? PCAL_CONF_PORT0 : PCAL_CONF_PORT1;
uint8_t current_config = pcal9714_read(config_reg);

if (mode == OUTPUT) {
current_config &= ~(1 << pin); // Clear the bit to set it as output
} else {
current_config |= (1 << pin); // Set the bit to set it as input
}

pcal9714_write(config_reg, current_config);
}


void pcal9714_configure_debounce(uint8_t debounce_pins_port0, uint8_t debounce_pins_port1, uint8_t debounce_counter_value) {
// Initialize SPI communication
pcal9714_init();

// Set up the switch debounce enable registers for port 0 and port 1
pcal9714_write(PCAL_DEBOUNCE_EN_REG0, debounce_pins_port0);
pcal9714_write(PCAL_DEBOUNCE_EN_REG1, debounce_pins_port1);

// Write the debounce counter value to the debounce count register
pcal9714_write(PCAL_DEBOUNCE_COUNT, debounce_counter_value);
}


/// @brief Write a value to a register on the pcal9714 device.
///  addr Address of the register.
///  value Value to write.
void pcal9714_write(uint8_t addr, uint8_t value)
{
digitalWrite(PCAL9714_SPI_CS_PIN, LOW); // Select the device
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

SPI.transfer(addr); // Send the address
SPI.transfer(value); // Send the value

SPI.endTransaction();
digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device

}

/// @brief Read a value from a port on the pcal9714 device.
///  port port addr
/// @return value of the port
uint8_t pcal9714_read_port(uint8_t port)
{
uint8_t regAddr = (port == 0) ? PCAL_INP_PORT0 : PCAL_INP_PORT1;
return pcal9714_read(regAddr);
}

/// @brief Read a value from a register on the pcal9714 device.
///  addr Address of the register.
/// @return Value read from the register.
uint8_t pcal9714_read(uint8_t addr)
{
uint8_t read_value = 0;

digitalWrite(PCAL9714_SPI_CS_PIN, LOW); // Select the device
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

SPI.transfer(addr | 0x80); // Send the address ORed with the read command
read_value = SPI.transfer(0xFF); // Send dummy data to read the value

SPI.endTransaction();
digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device

return read_value;


}

 

 

the header file

#ifndef _PCAL9714_H_
#define _PCAL9714_H_

#include <stdint.h>
#include <stdbool.h>


/**
********************************************************************************
* @file pcal9714.h
* @author ahmed
* @date 2024-04-22
* @brief Header file for the pcal9714 driver.
********************************************************************************
*/


typedef enum gpio_expander_channels_v10_t {
GPIOEXP_NONE0_V10,
GPIOEXP_NONE1_V10,
GPIOEXP_LIMIT_SWITCH_HOME_Y_V10,
GPIOEXP_SEL_WG_CD_V10,
GPIOEXP_SEL_FIBER_V10,
GPIOEXP_SEL_WG_AB_V10,
GPIOEXP_NONE2_V10,
GPIOEXP_NONE3_V10,
GPIOEXP_LIMIT_SWITCH_HOME_X_V10,
GPIOEXP_LIMIT_SWITCH_END_X_V10,
GPIOEXP_LIMIT_SWITCH_END_Y_V10,
GPIOEXP_CCB_DETECT_V10,
GPIOEXP_CC_DETECT_V10,
GPIOEXP_MOTOR_ENABLE_V10,
NUMBER_OF_GPIOEXP_PINS_V10
}gpio_expander_channels_v10_t;

#define PCAL_INP_PORT0 0x00
#define PCAL_INP_PORT1 0x01
#define PCAL_OUT_PORT0 0x02
#define PCAL_OUT_PORT1 0x03
#define PCAL_POL_INV_PORT0 0x04
#define PCAL_POL_INV_PORT1 0x05
#define PCAL_CONF_PORT0 0x06
#define PCAL_CONF_PORT1 0x07
#define PCAL_OUT_STR_PORT0A 0x40
#define PCAL_OUT_STR_PORT0B 0x41
#define PCAL_OUT_STR_PORT1A 0x42
#define PCAL_OUT_STR_PORT1B 0x43
#define PCAL_INP_LATCH_REG0 0x44
#define PCAL_INP_LATCH_REG1 0x45
#define PCAL_PULL_EN_PORT0 0x46
#define PCAL_PULL_EN_PORT1 0x47
#define PCAL_PULL_SEL_PORT0 0x48
#define PCAL_PULL_SEL_PORT1 0x49
#define PCAL_INT_MASK_PORT0 0x4A
#define PCAL_INT_MASK_PORT1 0x4B
#define PCAL_INT_STAT_PORT0 0x4C
#define PCAL_INT_STAT_PORT1 0x4D
#define PCAL_OUT_CONF_REG 0x4F
#define PCAL_INT_EDGE_REG0A 0x50
#define PCAL_INT_EDGE_REG0B 0x51
#define PCAL_INT_EDGE_REG1A 0x52
#define PCAL_INT_EDGE_REG1B 0x53
#define PCAL_INT_CLR_REG0 0x54
#define PCAL_INT_CLR_REG1 0x55
#define PCAL_INP_PORT_READ_WO_INT_CLR0 0x56
#define PCAL_INP_PORT_READ_WO_INT_CLR1 0x57
#define PCAL_OUT_CONF_REG0 0x58
#define PCAL_OUT_CONF_REG1 0x59
#define PCAL_DEBOUNCE_EN_REG0 0x5A
#define PCAL_DEBOUNCE_EN_REG1 0x5B
#define PCAL_DEBOUNCE_COUNT 0x5C


// Define the SPI CS pin
#define PCAL9714_SPI_CS_PIN 9 // CS pin for the PCAL9714 is connected to Arduino pin 9


void pcal9714_init(void);
void pcal9714_set_pin(uint8_t channel, uint8_t value);
uint8_t pcal9714_read_pin(uint8_t channel);
void pcal9714_set_mode(uint8_t channel, uint8_t value);
void pcal9714_write(uint8_t addr, uint8_t value);
uint8_t pcal9714_read_port(uint8_t port);
uint8_t pcal9714_read(uint8_t addr);
void pcal9714_configure_debounce(uint8_t debounce_pins_port0, uint8_t debounce_pins_port1, uint8_t debounce_counter_value);




#endif /* _PCAL9714_H_ */

 

 

Please guide me through how to read/write or test the limit switches on the PCAL9714

Best,

Ahmed

0 Kudos
Reply
1 Solution
1,125 Views
ahmedd
Contributor II

Hi David,

sorry for the late response, but I had solved it, here is the corrected code for anyone who needs it

cpp file

#include <Arduino.h>
#include "pcal9714.h"
#include <SPI.h>


/**
 ********************************************************************************
 * @file    pcal9714.cpp
 * @author  ahmed
 * @date    2024-04-22
 * @brief   Implementation of the pcal9714 driver.
 ********************************************************************************
 */

/// @brief Configure the pcal9714 device.
void pcal9714_init(void)
{
    
    pinMode(PCAL9714_SPI_CS_PIN, OUTPUT);
    digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device
    SPI.begin();  // Initialize SPI communication

}

/// @brief Set the value of a pin on the pcal9714 device.
/// @Param channel Channel number.
/// @Param value 1 for high, 0 for low.
void pcal9714_set_pin(uint8_t channel, uint8_t value)
{
    uint8_t port = channel / 8;  // Determine port (0 or 1)
    uint8_t pin = channel % 8;   // Determine pin within the port

    uint8_t portValue = pcal9714_read_port(port); // Read current port value

    if (value) {
        portValue |= (1 << pin); // Set the pin to HIGH
    } else {
        portValue &= ~(1 << pin); // Set the pin to LOW
    }

    pcal9714_write(PCAL_OUT_PORT0 + port, portValue); // Write to the output port

}

/// @brief Read the value of a pin on the pcal9714 device.
/// @Param channel Channel number.
/// @return The value of the pin.
uint8_t pcal9714_read_pin(uint8_t channel)
{
    uint8_t port = channel / 8;
    uint8_t pin = channel % 8;

    uint8_t portValue = pcal9714_read_port(port);
    return (portValue >> pin) & 0x01; 
}

/// @brief Set the mode of a pin on the pcal9714 device.
/// @Param channel Channel number.
/// @Param value 1 for high impedence input, 0 for output.
void pcal9714_set_mode(uint8_t channel, uint8_t mode) {
    uint8_t port = channel / 8;
    uint8_t pin = channel % 8;

    // Setting the overall port configuration for push-pull if we're setting the pin as an output
    if (mode == OUTPUT) {
        uint8_t out_conf = pcal9714_read(PCAL_OUT_CONF_REG);
        out_conf |= 0x03; // Set the ports to push-pull mode
        pcal9714_write(PCAL_OUT_CONF_REG, out_conf);

        // Set the individual pin configuration for pull-up if required
        uint8_t out_conf_reg = (port == 0) ? PCAL_OUT_CONF_REG0 : PCAL_OUT_CONF_REG1;
        uint8_t out_conf_value = pcal9714_read(out_conf_reg);
        out_conf_value |= (1 << pin); // Enable pull-up for the pin
        pcal9714_write(out_conf_reg, out_conf_value);
    }

    // Then set the pin direction (input/output)
    uint8_t config_reg = (port == 0) ? PCAL_CONF_PORT0 : PCAL_CONF_PORT1;
    uint8_t current_config = pcal9714_read(config_reg);

    if (mode == OUTPUT) {
        current_config &= ~(1 << pin); // Clear the bit to set it as output
    } else {
        current_config |= (1 << pin); // Set the bit to set it as input
    }

    pcal9714_write(config_reg, current_config);
}

/// @brief Configure the debounce on the pcal9714 device.
/// @Param  debounce_pins_port0 This parameter specifies which pins on port 0 of the PCAL9714 device should have debounce enabled. Each bit in this parameter represents a pin on port 0, where a value of 1 enables debounce for that pin, and a value of 0 disables debounce.
/// @Param debounce_pins_port1 Similar to debounce_pins_port0, this parameter specifies debounce settings for pins on port 1 of the device.
/// @Param debounce_counter_value This parameter determines the debounce counter value, which influences the debounce delay. A higher counter value results in a longer debounce delay.

void pcal9714_configure_debounce(uint8_t debounce_pins_port0, uint8_t debounce_pins_port1, uint8_t debounce_counter_value) {
    // Initialize SPI communication
    pcal9714_init();

    // Set up the switch debounce enable registers for port 0 and port 1
    pcal9714_write(PCAL_DEBOUNCE_EN_REG0, debounce_pins_port0);
    
    pcal9714_write(PCAL_DEBOUNCE_EN_REG1, debounce_pins_port1);

    // Write the debounce counter value to the debounce count register
    pcal9714_write(PCAL_DEBOUNCE_COUNT, debounce_counter_value);
}


/// @brief Write a value to a register on the pcal9714 device.
/// @Param addr Address of the register.
/// @Param value Value to write.
void pcal9714_write(uint8_t addr, uint8_t value) {
  // Build the frame according to datasheet. First byte is slave address with R/W bit set to 0 for write.
  uint8_t slaveAddressByte = 0x40; // Adjust as needed.
  uint8_t dataFrame[3] = {slaveAddressByte, addr, value};

  digitalWrite(PCAL9714_SPI_CS_PIN, LOW); // Select the device
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  for (int i = 0; i < 3; i++) {
    SPI.transfer(dataFrame[i]); // Transfer each byte
  }

  SPI.endTransaction();
  digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device
}

/// @brief Read a value from a port on the pcal9714 device.
/// @Param port port addr
/// @return value of the port
uint8_t pcal9714_read_port(uint8_t port)
{
    uint8_t regAddr = (port == 0) ? PCAL_INP_PORT0 : PCAL_INP_PORT1; 
    return pcal9714_read(regAddr);
}

/// @brief Read a value from a register on the pcal9714 device.
/// @Param addr Address of the register.
/// @return Value read from the register.

uint8_t pcal9714_read(uint8_t addr) {
  // Build the frame according to datasheet. First byte is slave address with R/W bit set to 1 for read.
  uint8_t slaveAddressByte = (0x41); // OR with 0x01 to indicate read operation
  uint8_t dataOut[3] = {slaveAddressByte, addr, 0x00}; // Third byte doesn't matter, it's dummy for clocking out the data
  uint8_t dataIn[3] = {0, 0, 0};

  digitalWrite(PCAL9714_SPI_CS_PIN, LOW); // Select the device
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  for (int i = 0; i < 3; i++) {
    dataIn[i] = SPI.transfer(dataOut[i]); // Transfer each byte
    //Serial.println(dataIn[i], HEX);
  }

  SPI.endTransaction();
  digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device

  return dataIn[2]; // The data read from the device will be in the third byte
}


header file

#ifndef _PCAL9714_H_
#define _PCAL9714_H_

#include <stdint.h>
#include <stdbool.h>


/**
 ********************************************************************************
 * @file    pcal9714.h
 * @author  ahmed
 * @date    2024-04-22
 * @brief   Header file for the pcal9714 driver.
 ********************************************************************************
 */


typedef enum gpio_expander_channels_v10_t {
    GPIOEXP_NONE0_V10,//input P0_0
    GPIOEXP_NONE1_V10,//input P0_2
    GPIOEXP_LIMIT_SWITCH_HOME_Y_V10,
    GPIOEXP_SEL_WG_CD_V10,
    GPIOEXP_SEL_FIBER_V10,
    GPIOEXP_SEL_WG_AB_V10,
    GPIOEXP_NONE2_V10,
    GPIOEXP_NONE3_V10,
    GPIOEXP_LIMIT_SWITCH_HOME_X_V10,
    GPIOEXP_LIMIT_SWITCH_END_X_V10,
    GPIOEXP_LIMIT_SWITCH_END_Y_V10,
    GPIOEXP_CCB_DETECT_V10,
    GPIOEXP_CC_DETECT_V10,
    GPIOEXP_MOTOR_ENABLE_V10,
    NUMBER_OF_GPIOEXP_PINS_V10
}gpio_expander_channels_v10_t;

#define PCAL_INP_PORT0 0x00
#define PCAL_INP_PORT1 0x01
#define PCAL_OUT_PORT0 0x02
#define PCAL_OUT_PORT1 0x03
#define PCAL_POL_INV_PORT0 0x04
#define PCAL_POL_INV_PORT1 0x05
#define PCAL_CONF_PORT0 0x06
#define PCAL_CONF_PORT1 0x07
#define PCAL_OUT_STR_PORT0A 0x40
#define PCAL_OUT_STR_PORT0B 0x41
#define PCAL_OUT_STR_PORT1A 0x42
#define PCAL_OUT_STR_PORT1B 0x43
#define PCAL_INP_LATCH_REG0 0x44
#define PCAL_INP_LATCH_REG1 0x45
#define PCAL_PULL_EN_PORT0 0x46
#define PCAL_PULL_EN_PORT1 0x47
#define PCAL_PULL_SEL_PORT0 0x48
#define PCAL_PULL_SEL_PORT1 0x49
#define PCAL_INT_MASK_PORT0 0x4A
#define PCAL_INT_MASK_PORT1 0x4B
#define PCAL_INT_STAT_PORT0 0x4C
#define PCAL_INT_STAT_PORT1 0x4D
#define PCAL_OUT_CONF_REG 0x4F
#define PCAL_INT_EDGE_REG0A 0x50
#define PCAL_INT_EDGE_REG0B 0x51
#define PCAL_INT_EDGE_REG1A 0x52
#define PCAL_INT_EDGE_REG1B 0x53
#define PCAL_INT_CLR_REG0 0x54
#define PCAL_INT_CLR_REG1 0x55
#define PCAL_INP_PORT_READ_WO_INT_CLR0 0x56
#define PCAL_INP_PORT_READ_WO_INT_CLR1 0x57
#define PCAL_OUT_CONF_REG0 0x58
#define PCAL_OUT_CONF_REG1 0x59
#define PCAL_DEBOUNCE_EN_REG0 0x5A
#define PCAL_DEBOUNCE_EN_REG1 0x5B
#define PCAL_DEBOUNCE_COUNT 0x5C


// Define the SPI CS pin
#define PCAL9714_SPI_CS_PIN   9  // CS pin for the PCAL9714 is connected to Arduino pin 9

// Slave address based on your specific hardware setup
#define PCAL9714_SLAVE_ADDRESS 0x20 // Example slave address



void pcal9714_init(void);
void pcal9714_set_pin(uint8_t channel, uint8_t value);
uint8_t pcal9714_read_pin(uint8_t channel);
void pcal9714_set_mode(uint8_t channel, uint8_t value);
void pcal9714_write(uint8_t addr, uint8_t value);
uint8_t pcal9714_read_port(uint8_t port);
uint8_t pcal9714_read(uint8_t addr);
void pcal9714_configure_debounce(uint8_t debounce_pins_port0, uint8_t debounce_pins_port1, uint8_t debounce_counter_value);




#endif /* _PCAL9714_H_ */







View solution in original post

0 Kudos
Reply
2 Replies
1,126 Views
ahmedd
Contributor II

Hi David,

sorry for the late response, but I had solved it, here is the corrected code for anyone who needs it

cpp file

#include <Arduino.h>
#include "pcal9714.h"
#include <SPI.h>


/**
 ********************************************************************************
 * @file    pcal9714.cpp
 * @author  ahmed
 * @date    2024-04-22
 * @brief   Implementation of the pcal9714 driver.
 ********************************************************************************
 */

/// @brief Configure the pcal9714 device.
void pcal9714_init(void)
{
    
    pinMode(PCAL9714_SPI_CS_PIN, OUTPUT);
    digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device
    SPI.begin();  // Initialize SPI communication

}

/// @brief Set the value of a pin on the pcal9714 device.
/// @Param channel Channel number.
/// @Param value 1 for high, 0 for low.
void pcal9714_set_pin(uint8_t channel, uint8_t value)
{
    uint8_t port = channel / 8;  // Determine port (0 or 1)
    uint8_t pin = channel % 8;   // Determine pin within the port

    uint8_t portValue = pcal9714_read_port(port); // Read current port value

    if (value) {
        portValue |= (1 << pin); // Set the pin to HIGH
    } else {
        portValue &= ~(1 << pin); // Set the pin to LOW
    }

    pcal9714_write(PCAL_OUT_PORT0 + port, portValue); // Write to the output port

}

/// @brief Read the value of a pin on the pcal9714 device.
/// @Param channel Channel number.
/// @return The value of the pin.
uint8_t pcal9714_read_pin(uint8_t channel)
{
    uint8_t port = channel / 8;
    uint8_t pin = channel % 8;

    uint8_t portValue = pcal9714_read_port(port);
    return (portValue >> pin) & 0x01; 
}

/// @brief Set the mode of a pin on the pcal9714 device.
/// @Param channel Channel number.
/// @Param value 1 for high impedence input, 0 for output.
void pcal9714_set_mode(uint8_t channel, uint8_t mode) {
    uint8_t port = channel / 8;
    uint8_t pin = channel % 8;

    // Setting the overall port configuration for push-pull if we're setting the pin as an output
    if (mode == OUTPUT) {
        uint8_t out_conf = pcal9714_read(PCAL_OUT_CONF_REG);
        out_conf |= 0x03; // Set the ports to push-pull mode
        pcal9714_write(PCAL_OUT_CONF_REG, out_conf);

        // Set the individual pin configuration for pull-up if required
        uint8_t out_conf_reg = (port == 0) ? PCAL_OUT_CONF_REG0 : PCAL_OUT_CONF_REG1;
        uint8_t out_conf_value = pcal9714_read(out_conf_reg);
        out_conf_value |= (1 << pin); // Enable pull-up for the pin
        pcal9714_write(out_conf_reg, out_conf_value);
    }

    // Then set the pin direction (input/output)
    uint8_t config_reg = (port == 0) ? PCAL_CONF_PORT0 : PCAL_CONF_PORT1;
    uint8_t current_config = pcal9714_read(config_reg);

    if (mode == OUTPUT) {
        current_config &= ~(1 << pin); // Clear the bit to set it as output
    } else {
        current_config |= (1 << pin); // Set the bit to set it as input
    }

    pcal9714_write(config_reg, current_config);
}

/// @brief Configure the debounce on the pcal9714 device.
/// @Param  debounce_pins_port0 This parameter specifies which pins on port 0 of the PCAL9714 device should have debounce enabled. Each bit in this parameter represents a pin on port 0, where a value of 1 enables debounce for that pin, and a value of 0 disables debounce.
/// @Param debounce_pins_port1 Similar to debounce_pins_port0, this parameter specifies debounce settings for pins on port 1 of the device.
/// @Param debounce_counter_value This parameter determines the debounce counter value, which influences the debounce delay. A higher counter value results in a longer debounce delay.

void pcal9714_configure_debounce(uint8_t debounce_pins_port0, uint8_t debounce_pins_port1, uint8_t debounce_counter_value) {
    // Initialize SPI communication
    pcal9714_init();

    // Set up the switch debounce enable registers for port 0 and port 1
    pcal9714_write(PCAL_DEBOUNCE_EN_REG0, debounce_pins_port0);
    
    pcal9714_write(PCAL_DEBOUNCE_EN_REG1, debounce_pins_port1);

    // Write the debounce counter value to the debounce count register
    pcal9714_write(PCAL_DEBOUNCE_COUNT, debounce_counter_value);
}


/// @brief Write a value to a register on the pcal9714 device.
/// @Param addr Address of the register.
/// @Param value Value to write.
void pcal9714_write(uint8_t addr, uint8_t value) {
  // Build the frame according to datasheet. First byte is slave address with R/W bit set to 0 for write.
  uint8_t slaveAddressByte = 0x40; // Adjust as needed.
  uint8_t dataFrame[3] = {slaveAddressByte, addr, value};

  digitalWrite(PCAL9714_SPI_CS_PIN, LOW); // Select the device
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  for (int i = 0; i < 3; i++) {
    SPI.transfer(dataFrame[i]); // Transfer each byte
  }

  SPI.endTransaction();
  digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device
}

/// @brief Read a value from a port on the pcal9714 device.
/// @Param port port addr
/// @return value of the port
uint8_t pcal9714_read_port(uint8_t port)
{
    uint8_t regAddr = (port == 0) ? PCAL_INP_PORT0 : PCAL_INP_PORT1; 
    return pcal9714_read(regAddr);
}

/// @brief Read a value from a register on the pcal9714 device.
/// @Param addr Address of the register.
/// @return Value read from the register.

uint8_t pcal9714_read(uint8_t addr) {
  // Build the frame according to datasheet. First byte is slave address with R/W bit set to 1 for read.
  uint8_t slaveAddressByte = (0x41); // OR with 0x01 to indicate read operation
  uint8_t dataOut[3] = {slaveAddressByte, addr, 0x00}; // Third byte doesn't matter, it's dummy for clocking out the data
  uint8_t dataIn[3] = {0, 0, 0};

  digitalWrite(PCAL9714_SPI_CS_PIN, LOW); // Select the device
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  for (int i = 0; i < 3; i++) {
    dataIn[i] = SPI.transfer(dataOut[i]); // Transfer each byte
    //Serial.println(dataIn[i], HEX);
  }

  SPI.endTransaction();
  digitalWrite(PCAL9714_SPI_CS_PIN, HIGH); // Deselect the device

  return dataIn[2]; // The data read from the device will be in the third byte
}


header file

#ifndef _PCAL9714_H_
#define _PCAL9714_H_

#include <stdint.h>
#include <stdbool.h>


/**
 ********************************************************************************
 * @file    pcal9714.h
 * @author  ahmed
 * @date    2024-04-22
 * @brief   Header file for the pcal9714 driver.
 ********************************************************************************
 */


typedef enum gpio_expander_channels_v10_t {
    GPIOEXP_NONE0_V10,//input P0_0
    GPIOEXP_NONE1_V10,//input P0_2
    GPIOEXP_LIMIT_SWITCH_HOME_Y_V10,
    GPIOEXP_SEL_WG_CD_V10,
    GPIOEXP_SEL_FIBER_V10,
    GPIOEXP_SEL_WG_AB_V10,
    GPIOEXP_NONE2_V10,
    GPIOEXP_NONE3_V10,
    GPIOEXP_LIMIT_SWITCH_HOME_X_V10,
    GPIOEXP_LIMIT_SWITCH_END_X_V10,
    GPIOEXP_LIMIT_SWITCH_END_Y_V10,
    GPIOEXP_CCB_DETECT_V10,
    GPIOEXP_CC_DETECT_V10,
    GPIOEXP_MOTOR_ENABLE_V10,
    NUMBER_OF_GPIOEXP_PINS_V10
}gpio_expander_channels_v10_t;

#define PCAL_INP_PORT0 0x00
#define PCAL_INP_PORT1 0x01
#define PCAL_OUT_PORT0 0x02
#define PCAL_OUT_PORT1 0x03
#define PCAL_POL_INV_PORT0 0x04
#define PCAL_POL_INV_PORT1 0x05
#define PCAL_CONF_PORT0 0x06
#define PCAL_CONF_PORT1 0x07
#define PCAL_OUT_STR_PORT0A 0x40
#define PCAL_OUT_STR_PORT0B 0x41
#define PCAL_OUT_STR_PORT1A 0x42
#define PCAL_OUT_STR_PORT1B 0x43
#define PCAL_INP_LATCH_REG0 0x44
#define PCAL_INP_LATCH_REG1 0x45
#define PCAL_PULL_EN_PORT0 0x46
#define PCAL_PULL_EN_PORT1 0x47
#define PCAL_PULL_SEL_PORT0 0x48
#define PCAL_PULL_SEL_PORT1 0x49
#define PCAL_INT_MASK_PORT0 0x4A
#define PCAL_INT_MASK_PORT1 0x4B
#define PCAL_INT_STAT_PORT0 0x4C
#define PCAL_INT_STAT_PORT1 0x4D
#define PCAL_OUT_CONF_REG 0x4F
#define PCAL_INT_EDGE_REG0A 0x50
#define PCAL_INT_EDGE_REG0B 0x51
#define PCAL_INT_EDGE_REG1A 0x52
#define PCAL_INT_EDGE_REG1B 0x53
#define PCAL_INT_CLR_REG0 0x54
#define PCAL_INT_CLR_REG1 0x55
#define PCAL_INP_PORT_READ_WO_INT_CLR0 0x56
#define PCAL_INP_PORT_READ_WO_INT_CLR1 0x57
#define PCAL_OUT_CONF_REG0 0x58
#define PCAL_OUT_CONF_REG1 0x59
#define PCAL_DEBOUNCE_EN_REG0 0x5A
#define PCAL_DEBOUNCE_EN_REG1 0x5B
#define PCAL_DEBOUNCE_COUNT 0x5C


// Define the SPI CS pin
#define PCAL9714_SPI_CS_PIN   9  // CS pin for the PCAL9714 is connected to Arduino pin 9

// Slave address based on your specific hardware setup
#define PCAL9714_SLAVE_ADDRESS 0x20 // Example slave address



void pcal9714_init(void);
void pcal9714_set_pin(uint8_t channel, uint8_t value);
uint8_t pcal9714_read_pin(uint8_t channel);
void pcal9714_set_mode(uint8_t channel, uint8_t value);
void pcal9714_write(uint8_t addr, uint8_t value);
uint8_t pcal9714_read_port(uint8_t port);
uint8_t pcal9714_read(uint8_t addr);
void pcal9714_configure_debounce(uint8_t debounce_pins_port0, uint8_t debounce_pins_port1, uint8_t debounce_counter_value);




#endif /* _PCAL9714_H_ */







0 Kudos
Reply
1,136 Views
diazmarin09
NXP TechSupport
NXP TechSupport

Hello ahmedd,

As mentioned in another post, I would like to focus on your pcal9714_write and pcal9714_read functions.

The bus master must send the target slave address followed by a read or write operation. The slave address of the PCAL9714 is shown below:

diazmarin09_1-1714503244036.png

 

Are you considering such an address before trying to write or read an internal register?

Following the first byte of the slave address, the bus master sends a command byte, which is write-only and stored in the pointer register in the PCAL9714. Finally, the data.

In total, 24 bits of data are transferred before deserting CS.

diazmarin09_0-1714503238811.png

 

Could you please share an oscilloscope of your data transfer?

Regards,

David

0 Kudos
Reply
%3CLINGO-SUB%20id%3D%22lingo-sub-1855568%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3EPCAL9714%20sample%20code%20review%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1855568%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%20everyone%2C%3C%2FP%3E%3CP%3EI%20am%20trying%20to%20write%20to%20the%20register%20and%20read%20it%20back%20but%20it%20didnt%20give%20the%20same%20value.%20I%20would%20appreciate%20if%20someone%20would%20look%20into%20my%20code%20and%20correct%20me.%20I%20am%20using%20arduino%20Uno%3CBR%20%2F%3E%3CBR%20%2F%3EThis%20is%20the%20ino%20file%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23include%20%3CARDUINO.H%3E%0A%23include%20%3CSPI.H%3E%0A%23include%20%3CSTDINT.H%3E%0A%23include%20%22pcal9714.h%22%0A%0Avoid%20setup()%20%7B%0A%20%20%20%20Serial.begin(9600)%3B%0A%20%20%20%20uint8_t%20debounce_pins_port0%20%3D%200xFF%3B%20%2F%2F%20to%20enable%20debounce%20on%20all%20pins%20of%20port%200%0A%20%20%20%20uint8_t%20debounce_pins_port1%20%3D%200xFF%3B%20%2F%2F%20to%20enable%20debounce%20on%20all%20pins%20of%20port%201%0A%20%20%20%20uint16_t%20debounce_counter_value%20%3D%2010%3B%20%20%20%20%20%20%20%20%2F%2F%20debounce%20time%20of%2010%20microseconds%0A%20%20%20%20%0A%20%20%20%20pcal9714_configure_debounce(debounce_pins_port0%2C%20debounce_pins_port1%2C%20debounce_counter_value)%3B%0A%0A%20%20%20%20%2F%2F%20Set%20all%20pins%20you%20want%20to%20monitor%20as%20inputs%20with%20internal%20pull-up%0A%20%20%20%20for%20(uint8_t%20pin%20%3D%200%3B%20pin%20%26lt%3B%208%3B%20pin%2B%2B)%20%7B%0A%20%20%20%20%20%20pcal9714_set_mode(pin%2C%20INPUT_PULLUP)%3B%0A%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Write%20a%20test%20value%20to%20a%20register%0A%20%20%20%20uint8_t%20testValue%20%3D%200xAA%3B%20%2F%2F%20Example%20test%20value%20(170%20in%20decimal)%0A%20%20%20%20pcal9714_write(PCAL_CONF_PORT0%2C%20testValue)%3B%0A%0A%20%20%20%20%2F%2F%20Read%20the%20value%20back%0A%20%20%20%20uint8_t%20readBackValue%20%3D%20pcal9714_read(PCAL_CONF_PORT0)%3B%0A%0A%20%20%20%20%2F%2F%20Print%20the%20read%20back%20value%20to%20the%20serial%20monitor%0A%20%20%20%20Serial.print(%22Wrote%3A%200x%22)%3B%0A%20%20%20%20Serial.print(testValue%2C%20HEX)%3B%0A%20%20%20%20Serial.print(%22%2C%20Read%20back%3A%200x%22)%3B%0A%20%20%20%20Serial.println(readBackValue%2C%20HEX)%3B%0A%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Set%20GPIOEXP_LIMIT_SWITCH_HOME_Y_V10%20as%20an%20output%0A%20%20%20%20pcal9714_set_mode(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10%2C%20OUTPUT)%3B%20%2F%2F%20Set%20the%20pin%20as%20output%0A%0A%20%20%20%20%2F%2F%20Set%20the%20pin%20high%0A%20%20%20%20pcal9714_set_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10%2C%20HIGH)%3B%20%2F%2F%20Drive%20the%20pin%20high%0A%0A%20%20%20%20%2F%2F%20Add%20a%20short%20delay%20to%20observe%20the%20pin%20voltage%20with%20a%20multimeter%0A%20%20%20%20delay(1000)%3B%20%2F%2F%20Wait%20for%201%20second%0A%0A%20%20%20%20%2F%2F%20Set%20the%20pin%20low%0A%20%20%20%20pcal9714_set_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10%2C%20LOW)%3B%20%2F%2F%20Drive%20the%20pin%20low%0A%0A%20%20%20%20%2F%2F%20Add%20another%20short%20delay%20to%20observe%20the%20pin%20voltage%20with%20a%20multimeter%0A%20%20%20%20delay(1000)%3B%20%2F%2F%20Wait%20for%201%20second%0A%0A%0A%20%20%20%20Serial.println(%22Direct%20pin%20test%20setup%20complete.%22)%3B%0A%0A%7D%0A%0Avoid%20loop()%20%7B%0A%20%20%20%20%2F%2F%20Read%20the%20state%20of%20a%20pin%20(for%20example%2C%20P0_2)%20and%20print%20it%20to%20the%20serial%20monitor%0A%20%20int%20limitSwitchValue%20%3D%20pcal9714_read_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10)%3B%0A%20%20%0A%20%20%2F%2F%20Print%20the%20state%20to%20the%20serial%20monitor%0A%20%20Serial.print(%22Limit%20Switch%20State%3A%20%22)%3B%0A%20%20Serial.println(limitSwitchValue)%3B%0A%0A%20%20%2F%2F%20Add%20a%20delay%20to%20prevent%20flooding%20the%20serial%20monitor%0A%20%20delay(500)%3B%0A%0A%20%20static%20bool%20pinState%20%3D%20LOW%3B%0A%20%20pcal9714_set_pin(GPIOEXP_LIMIT_SWITCH_HOME_Y_V10%2C%20pinState)%3B%0A%20%20pinState%20%3D%20!pinState%3B%20%2F%2F%20Toggle%20the%20state%0A%20%20delay(1000)%3B%20%2F%2F%201%20second%20delay%0A%0A%20%20%20%20%20%20%20%0A%7D%3C%2FSTDINT.H%3E%3C%2FSPI.H%3E%3C%2FARDUINO.H%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CBR%20%2F%3E%3CP%3Ecpp%20file%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23include%20%3CARDUINO.H%3E%0A%23include%20%22pcal9714.h%22%0A%23include%20%3CSPI.H%3E%0A%0A%0A%2F**%0A********************************************************************************%0A*%20%40file%20pcal9714.cpp%0A*%20%40author%20ahmed%0A*%20%40date%202024-04-22%0A*%20%40brief%20Implementation%20of%20the%20pcal9714%20driver.%0A********************************************************************************%0A*%2F%0A%0A%2F%2F%2F%20%40brief%20Configure%20the%20pcal9714%20device.%0Avoid%20pcal9714_init(void)%0A%7B%0A%0ApinMode(PCAL9714_SPI_CS_PIN%2C%20OUTPUT)%3B%0AdigitalWrite(PCAL9714_SPI_CS_PIN%2C%20HIGH)%3B%20%2F%2F%20Deselect%20the%20device%0ASPI.begin()%3B%20%2F%2F%20Initialize%20SPI%20communication%0A%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Set%20the%20value%20of%20a%20pin%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%20channel%20Channel%20number.%0A%2F%2F%2F%20%20value%201%20for%20high%2C%200%20for%20low.%0Avoid%20pcal9714_set_pin(uint8_t%20channel%2C%20uint8_t%20value)%0A%7B%0Auint8_t%20port%20%3D%20channel%20%2F%208%3B%20%2F%2F%20Determine%20port%20(0%20or%201)%0Auint8_t%20pin%20%3D%20channel%20%25%208%3B%20%2F%2F%20Determine%20pin%20within%20the%20port%0A%0Auint8_t%20portValue%20%3D%20pcal9714_read_port(port)%3B%20%2F%2F%20Read%20current%20port%20value%0A%0Aif%20(value)%20%7B%0AportValue%20%7C%3D%20(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Set%20the%20pin%20to%20HIGH%0A%7D%20else%20%7B%0AportValue%20%26amp%3B%3D%20~(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Set%20the%20pin%20to%20LOW%0A%7D%0A%0Apcal9714_write(PCAL_OUT_PORT0%20%2B%20port%2C%20portValue)%3B%20%2F%2F%20Write%20to%20the%20output%20port%0A%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Read%20the%20value%20of%20a%20pin%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%20channel%20Channel%20number.%0A%2F%2F%2F%20%40return%20The%20value%20of%20the%20pin.%0Auint8_t%20pcal9714_read_pin(uint8_t%20channel)%0A%7B%0Auint8_t%20port%20%3D%20channel%20%2F%208%3B%0Auint8_t%20pin%20%3D%20channel%20%25%208%3B%0A%0Auint8_t%20portValue%20%3D%20pcal9714_read_port(port)%3B%0Areturn%20(portValue%20%26gt%3B%26gt%3B%20pin)%20%26amp%3B%200x01%3B%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Set%20the%20mode%20of%20a%20pin%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%20channel%20Channel%20number.%0A%2F%2F%2F%20%20value%201%20for%20high%20impedence%20input%2C%200%20for%20output.%0Avoid%20pcal9714_set_mode(uint8_t%20channel%2C%20uint8_t%20mode)%20%7B%0Auint8_t%20port%20%3D%20channel%20%2F%208%3B%0Auint8_t%20pin%20%3D%20channel%20%25%208%3B%0A%0A%2F%2F%20Setting%20the%20overall%20port%20configuration%20for%20push-pull%20if%20we're%20setting%20the%20pin%20as%20an%20output%0Aif%20(mode%20%3D%3D%20OUTPUT)%20%7B%0Auint8_t%20out_conf%20%3D%20pcal9714_read(PCAL_OUT_CONF_REG)%3B%0Aout_conf%20%7C%3D%200x03%3B%20%2F%2F%20Set%20the%20ports%20to%20push-pull%20mode%0Apcal9714_write(PCAL_OUT_CONF_REG%2C%20out_conf)%3B%0A%0A%2F%2F%20Set%20the%20individual%20pin%20configuration%20for%20pull-up%20if%20required%0Auint8_t%20out_conf_reg%20%3D%20(port%20%3D%3D%200)%20%3F%20PCAL_OUT_CONF_REG0%20%3A%20PCAL_OUT_CONF_REG1%3B%0Auint8_t%20out_conf_value%20%3D%20pcal9714_read(out_conf_reg)%3B%0Aout_conf_value%20%7C%3D%20(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Enable%20pull-up%20for%20the%20pin%0Apcal9714_write(out_conf_reg%2C%20out_conf_value)%3B%0A%7D%0A%0A%2F%2F%20Then%20set%20the%20pin%20direction%20(input%2Foutput)%0Auint8_t%20config_reg%20%3D%20(port%20%3D%3D%200)%20%3F%20PCAL_CONF_PORT0%20%3A%20PCAL_CONF_PORT1%3B%0Auint8_t%20current_config%20%3D%20pcal9714_read(config_reg)%3B%0A%0Aif%20(mode%20%3D%3D%20OUTPUT)%20%7B%0Acurrent_config%20%26amp%3B%3D%20~(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Clear%20the%20bit%20to%20set%20it%20as%20output%0A%7D%20else%20%7B%0Acurrent_config%20%7C%3D%20(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Set%20the%20bit%20to%20set%20it%20as%20input%0A%7D%0A%0Apcal9714_write(config_reg%2C%20current_config)%3B%0A%7D%0A%0A%0Avoid%20pcal9714_configure_debounce(uint8_t%20debounce_pins_port0%2C%20uint8_t%20debounce_pins_port1%2C%20uint8_t%20debounce_counter_value)%20%7B%0A%2F%2F%20Initialize%20SPI%20communication%0Apcal9714_init()%3B%0A%0A%2F%2F%20Set%20up%20the%20switch%20debounce%20enable%20registers%20for%20port%200%20and%20port%201%0Apcal9714_write(PCAL_DEBOUNCE_EN_REG0%2C%20debounce_pins_port0)%3B%0Apcal9714_write(PCAL_DEBOUNCE_EN_REG1%2C%20debounce_pins_port1)%3B%0A%0A%2F%2F%20Write%20the%20debounce%20counter%20value%20to%20the%20debounce%20count%20register%0Apcal9714_write(PCAL_DEBOUNCE_COUNT%2C%20debounce_counter_value)%3B%0A%7D%0A%0A%0A%2F%2F%2F%20%40brief%20Write%20a%20value%20to%20a%20register%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%20addr%20Address%20of%20the%20register.%0A%2F%2F%2F%20%20value%20Value%20to%20write.%0Avoid%20pcal9714_write(uint8_t%20addr%2C%20uint8_t%20value)%0A%7B%0AdigitalWrite(PCAL9714_SPI_CS_PIN%2C%20LOW)%3B%20%2F%2F%20Select%20the%20device%0ASPI.beginTransaction(SPISettings(1000000%2C%20MSBFIRST%2C%20SPI_MODE0))%3B%0A%0ASPI.transfer(addr)%3B%20%2F%2F%20Send%20the%20address%0ASPI.transfer(value)%3B%20%2F%2F%20Send%20the%20value%0A%0ASPI.endTransaction()%3B%0AdigitalWrite(PCAL9714_SPI_CS_PIN%2C%20HIGH)%3B%20%2F%2F%20Deselect%20the%20device%0A%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Read%20a%20value%20from%20a%20port%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%20port%20port%20addr%0A%2F%2F%2F%20%40return%20value%20of%20the%20port%0Auint8_t%20pcal9714_read_port(uint8_t%20port)%0A%7B%0Auint8_t%20regAddr%20%3D%20(port%20%3D%3D%200)%20%3F%20PCAL_INP_PORT0%20%3A%20PCAL_INP_PORT1%3B%0Areturn%20pcal9714_read(regAddr)%3B%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Read%20a%20value%20from%20a%20register%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%20addr%20Address%20of%20the%20register.%0A%2F%2F%2F%20%40return%20Value%20read%20from%20the%20register.%0Auint8_t%20pcal9714_read(uint8_t%20addr)%0A%7B%0Auint8_t%20read_value%20%3D%200%3B%0A%0AdigitalWrite(PCAL9714_SPI_CS_PIN%2C%20LOW)%3B%20%2F%2F%20Select%20the%20device%0ASPI.beginTransaction(SPISettings(1000000%2C%20MSBFIRST%2C%20SPI_MODE0))%3B%0A%0ASPI.transfer(addr%20%7C%200x80)%3B%20%2F%2F%20Send%20the%20address%20ORed%20with%20the%20read%20command%0Aread_value%20%3D%20SPI.transfer(0xFF)%3B%20%2F%2F%20Send%20dummy%20data%20to%20read%20the%20value%0A%0ASPI.endTransaction()%3B%0AdigitalWrite(PCAL9714_SPI_CS_PIN%2C%20HIGH)%3B%20%2F%2F%20Deselect%20the%20device%0A%0Areturn%20read_value%3B%0A%0A%0A%7D%3C%2FSPI.H%3E%3C%2FARDUINO.H%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3CP%3Ethe%20header%20file%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23ifndef%20_PCAL9714_H_%0A%23define%20_PCAL9714_H_%0A%0A%23include%20%3CSTDINT.H%3E%0A%23include%20%3CSTDBOOL.H%3E%0A%0A%0A%2F**%0A********************************************************************************%0A*%20%40file%20pcal9714.h%0A*%20%40author%20ahmed%0A*%20%40date%202024-04-22%0A*%20%40brief%20Header%20file%20for%20the%20pcal9714%20driver.%0A********************************************************************************%0A*%2F%0A%0A%0Atypedef%20enum%20gpio_expander_channels_v10_t%20%7B%0AGPIOEXP_NONE0_V10%2C%0AGPIOEXP_NONE1_V10%2C%0AGPIOEXP_LIMIT_SWITCH_HOME_Y_V10%2C%0AGPIOEXP_SEL_WG_CD_V10%2C%0AGPIOEXP_SEL_FIBER_V10%2C%0AGPIOEXP_SEL_WG_AB_V10%2C%0AGPIOEXP_NONE2_V10%2C%0AGPIOEXP_NONE3_V10%2C%0AGPIOEXP_LIMIT_SWITCH_HOME_X_V10%2C%0AGPIOEXP_LIMIT_SWITCH_END_X_V10%2C%0AGPIOEXP_LIMIT_SWITCH_END_Y_V10%2C%0AGPIOEXP_CCB_DETECT_V10%2C%0AGPIOEXP_CC_DETECT_V10%2C%0AGPIOEXP_MOTOR_ENABLE_V10%2C%0ANUMBER_OF_GPIOEXP_PINS_V10%0A%7Dgpio_expander_channels_v10_t%3B%0A%0A%23define%20PCAL_INP_PORT0%200x00%0A%23define%20PCAL_INP_PORT1%200x01%0A%23define%20PCAL_OUT_PORT0%200x02%0A%23define%20PCAL_OUT_PORT1%200x03%0A%23define%20PCAL_POL_INV_PORT0%200x04%0A%23define%20PCAL_POL_INV_PORT1%200x05%0A%23define%20PCAL_CONF_PORT0%200x06%0A%23define%20PCAL_CONF_PORT1%200x07%0A%23define%20PCAL_OUT_STR_PORT0A%200x40%0A%23define%20PCAL_OUT_STR_PORT0B%200x41%0A%23define%20PCAL_OUT_STR_PORT1A%200x42%0A%23define%20PCAL_OUT_STR_PORT1B%200x43%0A%23define%20PCAL_INP_LATCH_REG0%200x44%0A%23define%20PCAL_INP_LATCH_REG1%200x45%0A%23define%20PCAL_PULL_EN_PORT0%200x46%0A%23define%20PCAL_PULL_EN_PORT1%200x47%0A%23define%20PCAL_PULL_SEL_PORT0%200x48%0A%23define%20PCAL_PULL_SEL_PORT1%200x49%0A%23define%20PCAL_INT_MASK_PORT0%200x4A%0A%23define%20PCAL_INT_MASK_PORT1%200x4B%0A%23define%20PCAL_INT_STAT_PORT0%200x4C%0A%23define%20PCAL_INT_STAT_PORT1%200x4D%0A%23define%20PCAL_OUT_CONF_REG%200x4F%0A%23define%20PCAL_INT_EDGE_REG0A%200x50%0A%23define%20PCAL_INT_EDGE_REG0B%200x51%0A%23define%20PCAL_INT_EDGE_REG1A%200x52%0A%23define%20PCAL_INT_EDGE_REG1B%200x53%0A%23define%20PCAL_INT_CLR_REG0%200x54%0A%23define%20PCAL_INT_CLR_REG1%200x55%0A%23define%20PCAL_INP_PORT_READ_WO_INT_CLR0%200x56%0A%23define%20PCAL_INP_PORT_READ_WO_INT_CLR1%200x57%0A%23define%20PCAL_OUT_CONF_REG0%200x58%0A%23define%20PCAL_OUT_CONF_REG1%200x59%0A%23define%20PCAL_DEBOUNCE_EN_REG0%200x5A%0A%23define%20PCAL_DEBOUNCE_EN_REG1%200x5B%0A%23define%20PCAL_DEBOUNCE_COUNT%200x5C%0A%0A%0A%2F%2F%20Define%20the%20SPI%20CS%20pin%0A%23define%20PCAL9714_SPI_CS_PIN%209%20%2F%2F%20CS%20pin%20for%20the%20PCAL9714%20is%20connected%20to%20Arduino%20pin%209%0A%0A%0Avoid%20pcal9714_init(void)%3B%0Avoid%20pcal9714_set_pin(uint8_t%20channel%2C%20uint8_t%20value)%3B%0Auint8_t%20pcal9714_read_pin(uint8_t%20channel)%3B%0Avoid%20pcal9714_set_mode(uint8_t%20channel%2C%20uint8_t%20value)%3B%0Avoid%20pcal9714_write(uint8_t%20addr%2C%20uint8_t%20value)%3B%0Auint8_t%20pcal9714_read_port(uint8_t%20port)%3B%0Auint8_t%20pcal9714_read(uint8_t%20addr)%3B%0Avoid%20pcal9714_configure_debounce(uint8_t%20debounce_pins_port0%2C%20uint8_t%20debounce_pins_port1%2C%20uint8_t%20debounce_counter_value)%3B%0A%0A%0A%0A%0A%23endif%20%2F*%20_PCAL9714_H_%20*%2F%3C%2FSTDBOOL.H%3E%3C%2FSTDINT.H%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3CP%3EPlease%20guide%20me%20through%20how%20to%20read%2Fwrite%20or%20test%20the%20limit%20switches%20on%20the%20PCAL9714%3CBR%20%2F%3E%3CBR%20%2F%3EBest%2C%3C%2FP%3E%3CP%3EAhmed%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1859773%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3ERe%3A%20PCAL9714%20sample%20code%20review%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1859773%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%20David%2C%3CBR%20%2F%3E%3CBR%20%2F%3Esorry%20for%20the%20late%20response%2C%20but%20I%20had%20solved%20it%2C%20here%20is%20the%20corrected%20code%20for%20anyone%20who%20needs%20it%3CBR%20%2F%3E%3CBR%20%2F%3Ecpp%20file%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23include%20%3CARDUINO.H%3E%0A%23include%20%22pcal9714.h%22%0A%23include%20%3CSPI.H%3E%0A%0A%0A%2F**%0A%20********************************************************************************%0A%20*%20%40file%20%20%20%20pcal9714.cpp%0A%20*%20%40author%20%20ahmed%0A%20*%20%40date%20%20%20%202024-04-22%0A%20*%20%40brief%20%20%20Implementation%20of%20the%20pcal9714%20driver.%0A%20********************************************************************************%0A%20*%2F%0A%0A%2F%2F%2F%20%40brief%20Configure%20the%20pcal9714%20device.%0Avoid%20pcal9714_init(void)%0A%7B%0A%20%20%20%20%0A%20%20%20%20pinMode(PCAL9714_SPI_CS_PIN%2C%20OUTPUT)%3B%0A%20%20%20%20digitalWrite(PCAL9714_SPI_CS_PIN%2C%20HIGH)%3B%20%2F%2F%20Deselect%20the%20device%0A%20%20%20%20SPI.begin()%3B%20%20%2F%2F%20Initialize%20SPI%20communication%0A%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Set%20the%20value%20of%20a%20pin%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20channel%20Channel%20number.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20value%201%20for%20high%2C%200%20for%20low.%0Avoid%20pcal9714_set_pin(uint8_t%20channel%2C%20uint8_t%20value)%0A%7B%0A%20%20%20%20uint8_t%20port%20%3D%20channel%20%2F%208%3B%20%20%2F%2F%20Determine%20port%20(0%20or%201)%0A%20%20%20%20uint8_t%20pin%20%3D%20channel%20%25%208%3B%20%20%20%2F%2F%20Determine%20pin%20within%20the%20port%0A%0A%20%20%20%20uint8_t%20portValue%20%3D%20pcal9714_read_port(port)%3B%20%2F%2F%20Read%20current%20port%20value%0A%0A%20%20%20%20if%20(value)%20%7B%0A%20%20%20%20%20%20%20%20portValue%20%7C%3D%20(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Set%20the%20pin%20to%20HIGH%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20portValue%20%26amp%3B%3D%20~(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Set%20the%20pin%20to%20LOW%0A%20%20%20%20%7D%0A%0A%20%20%20%20pcal9714_write(PCAL_OUT_PORT0%20%2B%20port%2C%20portValue)%3B%20%2F%2F%20Write%20to%20the%20output%20port%0A%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Read%20the%20value%20of%20a%20pin%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20channel%20Channel%20number.%0A%2F%2F%2F%20%40return%20The%20value%20of%20the%20pin.%0Auint8_t%20pcal9714_read_pin(uint8_t%20channel)%0A%7B%0A%20%20%20%20uint8_t%20port%20%3D%20channel%20%2F%208%3B%0A%20%20%20%20uint8_t%20pin%20%3D%20channel%20%25%208%3B%0A%0A%20%20%20%20uint8_t%20portValue%20%3D%20pcal9714_read_port(port)%3B%0A%20%20%20%20return%20(portValue%20%26gt%3B%26gt%3B%20pin)%20%26amp%3B%200x01%3B%20%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Set%20the%20mode%20of%20a%20pin%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20channel%20Channel%20number.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20value%201%20for%20high%20impedence%20input%2C%200%20for%20output.%0Avoid%20pcal9714_set_mode(uint8_t%20channel%2C%20uint8_t%20mode)%20%7B%0A%20%20%20%20uint8_t%20port%20%3D%20channel%20%2F%208%3B%0A%20%20%20%20uint8_t%20pin%20%3D%20channel%20%25%208%3B%0A%0A%20%20%20%20%2F%2F%20Setting%20the%20overall%20port%20configuration%20for%20push-pull%20if%20we're%20setting%20the%20pin%20as%20an%20output%0A%20%20%20%20if%20(mode%20%3D%3D%20OUTPUT)%20%7B%0A%20%20%20%20%20%20%20%20uint8_t%20out_conf%20%3D%20pcal9714_read(PCAL_OUT_CONF_REG)%3B%0A%20%20%20%20%20%20%20%20out_conf%20%7C%3D%200x03%3B%20%2F%2F%20Set%20the%20ports%20to%20push-pull%20mode%0A%20%20%20%20%20%20%20%20pcal9714_write(PCAL_OUT_CONF_REG%2C%20out_conf)%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Set%20the%20individual%20pin%20configuration%20for%20pull-up%20if%20required%0A%20%20%20%20%20%20%20%20uint8_t%20out_conf_reg%20%3D%20(port%20%3D%3D%200)%20%3F%20PCAL_OUT_CONF_REG0%20%3A%20PCAL_OUT_CONF_REG1%3B%0A%20%20%20%20%20%20%20%20uint8_t%20out_conf_value%20%3D%20pcal9714_read(out_conf_reg)%3B%0A%20%20%20%20%20%20%20%20out_conf_value%20%7C%3D%20(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Enable%20pull-up%20for%20the%20pin%0A%20%20%20%20%20%20%20%20pcal9714_write(out_conf_reg%2C%20out_conf_value)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Then%20set%20the%20pin%20direction%20(input%2Foutput)%0A%20%20%20%20uint8_t%20config_reg%20%3D%20(port%20%3D%3D%200)%20%3F%20PCAL_CONF_PORT0%20%3A%20PCAL_CONF_PORT1%3B%0A%20%20%20%20uint8_t%20current_config%20%3D%20pcal9714_read(config_reg)%3B%0A%0A%20%20%20%20if%20(mode%20%3D%3D%20OUTPUT)%20%7B%0A%20%20%20%20%20%20%20%20current_config%20%26amp%3B%3D%20~(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Clear%20the%20bit%20to%20set%20it%20as%20output%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20current_config%20%7C%3D%20(1%20%26lt%3B%26lt%3B%20pin)%3B%20%2F%2F%20Set%20the%20bit%20to%20set%20it%20as%20input%0A%20%20%20%20%7D%0A%0A%20%20%20%20pcal9714_write(config_reg%2C%20current_config)%3B%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Configure%20the%20debounce%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20%20debounce_pins_port0%20This%20parameter%20specifies%20which%20pins%20on%20port%200%20of%20the%20PCAL9714%20device%20should%20have%20debounce%20enabled.%20Each%20bit%20in%20this%20parameter%20represents%20a%20pin%20on%20port%200%2C%20where%20a%20value%20of%201%20enables%20debounce%20for%20that%20pin%2C%20and%20a%20value%20of%200%20disables%20debounce.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20debounce_pins_port1%20Similar%20to%20debounce_pins_port0%2C%20this%20parameter%20specifies%20debounce%20settings%20for%20pins%20on%20port%201%20of%20the%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20debounce_counter_value%20This%20parameter%20determines%20the%20debounce%20counter%20value%2C%20which%20influences%20the%20debounce%20delay.%20A%20higher%20counter%20value%20results%20in%20a%20longer%20debounce%20delay.%0A%0Avoid%20pcal9714_configure_debounce(uint8_t%20debounce_pins_port0%2C%20uint8_t%20debounce_pins_port1%2C%20uint8_t%20debounce_counter_value)%20%7B%0A%20%20%20%20%2F%2F%20Initialize%20SPI%20communication%0A%20%20%20%20pcal9714_init()%3B%0A%0A%20%20%20%20%2F%2F%20Set%20up%20the%20switch%20debounce%20enable%20registers%20for%20port%200%20and%20port%201%0A%20%20%20%20pcal9714_write(PCAL_DEBOUNCE_EN_REG0%2C%20debounce_pins_port0)%3B%0A%20%20%20%20%0A%20%20%20%20pcal9714_write(PCAL_DEBOUNCE_EN_REG1%2C%20debounce_pins_port1)%3B%0A%0A%20%20%20%20%2F%2F%20Write%20the%20debounce%20counter%20value%20to%20the%20debounce%20count%20register%0A%20%20%20%20pcal9714_write(PCAL_DEBOUNCE_COUNT%2C%20debounce_counter_value)%3B%0A%7D%0A%0A%0A%2F%2F%2F%20%40brief%20Write%20a%20value%20to%20a%20register%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20addr%20Address%20of%20the%20register.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20value%20Value%20to%20write.%0Avoid%20pcal9714_write(uint8_t%20addr%2C%20uint8_t%20value)%20%7B%0A%20%20%2F%2F%20Build%20the%20frame%20according%20to%20datasheet.%20First%20byte%20is%20slave%20address%20with%20R%2FW%20bit%20set%20to%200%20for%20write.%0A%20%20uint8_t%20slaveAddressByte%20%3D%200x40%3B%20%2F%2F%20Adjust%20as%20needed.%0A%20%20uint8_t%20dataFrame%5B3%5D%20%3D%20%7BslaveAddressByte%2C%20addr%2C%20value%7D%3B%0A%0A%20%20digitalWrite(PCAL9714_SPI_CS_PIN%2C%20LOW)%3B%20%2F%2F%20Select%20the%20device%0A%20%20SPI.beginTransaction(SPISettings(1000000%2C%20MSBFIRST%2C%20SPI_MODE0))%3B%0A%0A%20%20for%20(int%20i%20%3D%200%3B%20i%20%26lt%3B%203%3B%20i%2B%2B)%20%7B%0A%20%20%20%20SPI.transfer(dataFrame%5Bi%5D)%3B%20%2F%2F%20Transfer%20each%20byte%0A%20%20%7D%0A%0A%20%20SPI.endTransaction()%3B%0A%20%20digitalWrite(PCAL9714_SPI_CS_PIN%2C%20HIGH)%3B%20%2F%2F%20Deselect%20the%20device%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Read%20a%20value%20from%20a%20port%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20port%20port%20addr%0A%2F%2F%2F%20%40return%20value%20of%20the%20port%0Auint8_t%20pcal9714_read_port(uint8_t%20port)%0A%7B%0A%20%20%20%20uint8_t%20regAddr%20%3D%20(port%20%3D%3D%200)%20%3F%20PCAL_INP_PORT0%20%3A%20PCAL_INP_PORT1%3B%20%0A%20%20%20%20return%20pcal9714_read(regAddr)%3B%0A%7D%0A%0A%2F%2F%2F%20%40brief%20Read%20a%20value%20from%20a%20register%20on%20the%20pcal9714%20device.%0A%2F%2F%2F%20%3CA%20href%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F197964%22%20target%3D%22_blank%22%3E%40Param%3C%2FA%3E%20addr%20Address%20of%20the%20register.%0A%2F%2F%2F%20%40return%20Value%20read%20from%20the%20register.%0A%0Auint8_t%20pcal9714_read(uint8_t%20addr)%20%7B%0A%20%20%2F%2F%20Build%20the%20frame%20according%20to%20datasheet.%20First%20byte%20is%20slave%20address%20with%20R%2FW%20bit%20set%20to%201%20for%20read.%0A%20%20uint8_t%20slaveAddressByte%20%3D%20(0x41)%3B%20%2F%2F%20OR%20with%200x01%20to%20indicate%20read%20operation%0A%20%20uint8_t%20dataOut%5B3%5D%20%3D%20%7BslaveAddressByte%2C%20addr%2C%200x00%7D%3B%20%2F%2F%20Third%20byte%20doesn't%20matter%2C%20it's%20dummy%20for%20clocking%20out%20the%20data%0A%20%20uint8_t%20dataIn%5B3%5D%20%3D%20%7B0%2C%200%2C%200%7D%3B%0A%0A%20%20digitalWrite(PCAL9714_SPI_CS_PIN%2C%20LOW)%3B%20%2F%2F%20Select%20the%20device%0A%20%20SPI.beginTransaction(SPISettings(1000000%2C%20MSBFIRST%2C%20SPI_MODE0))%3B%0A%0A%20%20for%20(int%20i%20%3D%200%3B%20i%20%26lt%3B%203%3B%20i%2B%2B)%20%7B%0A%20%20%20%20dataIn%5Bi%5D%20%3D%20SPI.transfer(dataOut%5Bi%5D)%3B%20%2F%2F%20Transfer%20each%20byte%0A%20%20%20%20%2F%2FSerial.println(dataIn%5Bi%5D%2C%20HEX)%3B%0A%20%20%7D%0A%0A%20%20SPI.endTransaction()%3B%0A%20%20digitalWrite(PCAL9714_SPI_CS_PIN%2C%20HIGH)%3B%20%2F%2F%20Deselect%20the%20device%0A%0A%20%20return%20dataIn%5B2%5D%3B%20%2F%2F%20The%20data%20read%20from%20the%20device%20will%20be%20in%20the%20third%20byte%0A%7D%3C%2FSPI.H%3E%3C%2FARDUINO.H%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%3CBR%20%2F%3Eheader%20file%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3E%23ifndef%20_PCAL9714_H_%0A%23define%20_PCAL9714_H_%0A%0A%23include%20%3CSTDINT.H%3E%0A%23include%20%3CSTDBOOL.H%3E%0A%0A%0A%2F**%0A%20********************************************************************************%0A%20*%20%40file%20%20%20%20pcal9714.h%0A%20*%20%40author%20%20ahmed%0A%20*%20%40date%20%20%20%202024-04-22%0A%20*%20%40brief%20%20%20Header%20file%20for%20the%20pcal9714%20driver.%0A%20********************************************************************************%0A%20*%2F%0A%0A%0Atypedef%20enum%20gpio_expander_channels_v10_t%20%7B%0A%20%20%20%20GPIOEXP_NONE0_V10%2C%2F%2Finput%20P0_0%0A%20%20%20%20GPIOEXP_NONE1_V10%2C%2F%2Finput%20P0_2%0A%20%20%20%20GPIOEXP_LIMIT_SWITCH_HOME_Y_V10%2C%0A%20%20%20%20GPIOEXP_SEL_WG_CD_V10%2C%0A%20%20%20%20GPIOEXP_SEL_FIBER_V10%2C%0A%20%20%20%20GPIOEXP_SEL_WG_AB_V10%2C%0A%20%20%20%20GPIOEXP_NONE2_V10%2C%0A%20%20%20%20GPIOEXP_NONE3_V10%2C%0A%20%20%20%20GPIOEXP_LIMIT_SWITCH_HOME_X_V10%2C%0A%20%20%20%20GPIOEXP_LIMIT_SWITCH_END_X_V10%2C%0A%20%20%20%20GPIOEXP_LIMIT_SWITCH_END_Y_V10%2C%0A%20%20%20%20GPIOEXP_CCB_DETECT_V10%2C%0A%20%20%20%20GPIOEXP_CC_DETECT_V10%2C%0A%20%20%20%20GPIOEXP_MOTOR_ENABLE_V10%2C%0A%20%20%20%20NUMBER_OF_GPIOEXP_PINS_V10%0A%7Dgpio_expander_channels_v10_t%3B%0A%0A%23define%20PCAL_INP_PORT0%200x00%0A%23define%20PCAL_INP_PORT1%200x01%0A%23define%20PCAL_OUT_PORT0%200x02%0A%23define%20PCAL_OUT_PORT1%200x03%0A%23define%20PCAL_POL_INV_PORT0%200x04%0A%23define%20PCAL_POL_INV_PORT1%200x05%0A%23define%20PCAL_CONF_PORT0%200x06%0A%23define%20PCAL_CONF_PORT1%200x07%0A%23define%20PCAL_OUT_STR_PORT0A%200x40%0A%23define%20PCAL_OUT_STR_PORT0B%200x41%0A%23define%20PCAL_OUT_STR_PORT1A%200x42%0A%23define%20PCAL_OUT_STR_PORT1B%200x43%0A%23define%20PCAL_INP_LATCH_REG0%200x44%0A%23define%20PCAL_INP_LATCH_REG1%200x45%0A%23define%20PCAL_PULL_EN_PORT0%200x46%0A%23define%20PCAL_PULL_EN_PORT1%200x47%0A%23define%20PCAL_PULL_SEL_PORT0%200x48%0A%23define%20PCAL_PULL_SEL_PORT1%200x49%0A%23define%20PCAL_INT_MASK_PORT0%200x4A%0A%23define%20PCAL_INT_MASK_PORT1%200x4B%0A%23define%20PCAL_INT_STAT_PORT0%200x4C%0A%23define%20PCAL_INT_STAT_PORT1%200x4D%0A%23define%20PCAL_OUT_CONF_REG%200x4F%0A%23define%20PCAL_INT_EDGE_REG0A%200x50%0A%23define%20PCAL_INT_EDGE_REG0B%200x51%0A%23define%20PCAL_INT_EDGE_REG1A%200x52%0A%23define%20PCAL_INT_EDGE_REG1B%200x53%0A%23define%20PCAL_INT_CLR_REG0%200x54%0A%23define%20PCAL_INT_CLR_REG1%200x55%0A%23define%20PCAL_INP_PORT_READ_WO_INT_CLR0%200x56%0A%23define%20PCAL_INP_PORT_READ_WO_INT_CLR1%200x57%0A%23define%20PCAL_OUT_CONF_REG0%200x58%0A%23define%20PCAL_OUT_CONF_REG1%200x59%0A%23define%20PCAL_DEBOUNCE_EN_REG0%200x5A%0A%23define%20PCAL_DEBOUNCE_EN_REG1%200x5B%0A%23define%20PCAL_DEBOUNCE_COUNT%200x5C%0A%0A%0A%2F%2F%20Define%20the%20SPI%20CS%20pin%0A%23define%20PCAL9714_SPI_CS_PIN%20%20%209%20%20%2F%2F%20CS%20pin%20for%20the%20PCAL9714%20is%20connected%20to%20Arduino%20pin%209%0A%0A%2F%2F%20Slave%20address%20based%20on%20your%20specific%20hardware%20setup%0A%23define%20PCAL9714_SLAVE_ADDRESS%200x20%20%2F%2F%20Example%20slave%20address%0A%0A%0A%0Avoid%20pcal9714_init(void)%3B%0Avoid%20pcal9714_set_pin(uint8_t%20channel%2C%20uint8_t%20value)%3B%0Auint8_t%20pcal9714_read_pin(uint8_t%20channel)%3B%0Avoid%20pcal9714_set_mode(uint8_t%20channel%2C%20uint8_t%20value)%3B%0Avoid%20pcal9714_write(uint8_t%20addr%2C%20uint8_t%20value)%3B%0Auint8_t%20pcal9714_read_port(uint8_t%20port)%3B%0Auint8_t%20pcal9714_read(uint8_t%20addr)%3B%0Avoid%20pcal9714_configure_debounce(uint8_t%20debounce_pins_port0%2C%20uint8_t%20debounce_pins_port1%2C%20uint8_t%20debounce_counter_value)%3B%0A%0A%0A%0A%0A%23endif%20%2F*%20_PCAL9714_H_%20*%2F%3C%2FSTDBOOL.H%3E%3C%2FSTDINT.H%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1857767%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3ERe%3A%20PCAL9714%20sample%20code%20review%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1857767%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHello%20%3CSPAN%3Eahmedd%3C%2FSPAN%3E%2C%3C%2FP%3E%0A%3CP%3EAs%20mentioned%20in%20another%20post%2C%26nbsp%3BI%20would%20like%20to%20focus%20on%20your%20%3CEM%3Epcal9714_write%3C%2FEM%3E%20and%20%3CEM%3Epcal9714_read%3C%2FEM%3E%20functions.%3C%2FP%3E%0A%3CP%3EThe%20bus%20master%20must%20send%20the%20target%20slave%20address%20followed%20by%20a%20read%20or%20write%20operation.%20The%20slave%20address%20of%20the%20PCAL9714%20is%20shown%20below%3A%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22diazmarin09_1-1714503244036.png%22%20style%3D%22width%3A%20249px%3B%22%3E%3Cspan%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22diazmarin09_1-1714503244036.png%22%20style%3D%22width%3A%20249px%3B%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F276733i368FD7B350397486%2Fimage-dimensions%2F249x97%3Fv%3Dv2%22%20width%3D%22249%22%20height%3D%2297%22%20role%3D%22button%22%20title%3D%22diazmarin09_1-1714503244036.png%22%20alt%3D%22diazmarin09_1-1714503244036.png%22%20%2F%3E%3C%2Fspan%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3EAre%20you%20considering%20such%20an%20address%20before%20trying%20to%20write%20or%20read%20an%20internal%20register%3F%3C%2FP%3E%0A%3CP%3EFollowing%20the%20first%20byte%20of%20the%20slave%20address%2C%20the%20bus%20master%20sends%20a%20command%20byte%2C%20which%20is%20write-only%20and%20stored%20in%20the%20pointer%20register%20in%20the%20PCAL9714.%20Finally%2C%20the%20data.%3C%2FP%3E%0A%3CP%3EIn%20total%2C%2024%20bits%20of%20data%20are%20transferred%20before%20deserting%20CS.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22diazmarin09_0-1714503238811.png%22%20style%3D%22width%3A%20503px%3B%22%3E%3Cspan%20class%3D%22lia-inline-image-display-wrapper%22%20image-alt%3D%22diazmarin09_0-1714503238811.png%22%20style%3D%22width%3A%20503px%3B%22%3E%3Cimg%20src%3D%22https%3A%2F%2Fcommunity.nxp.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F276732i6243FF1958D5F3F9%2Fimage-dimensions%2F503x127%3Fv%3Dv2%22%20width%3D%22503%22%20height%3D%22127%22%20role%3D%22button%22%20title%3D%22diazmarin09_0-1714503238811.png%22%20alt%3D%22diazmarin09_0-1714503238811.png%22%20%2F%3E%3C%2Fspan%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3ECould%20you%20please%20share%20an%20oscilloscope%20of%20your%20data%20transfer%3F%3C%2FP%3E%0A%3CP%3ERegards%2C%3C%2FP%3E%0A%3CP%3EDavid%3C%2FP%3E%3C%2FLINGO-BODY%3E