Skip to content

Commit

Permalink
Merge pull request #621 from oisalb/mcp23x17_software_cs
Browse files Browse the repository at this point in the history
Allow using software controlled Chip Select (CS) for MCP23S17.
  • Loading branch information
UncleRus authored Mar 19, 2024
2 parents acedb7a + 2d525ec commit c6da185
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
33 changes: 28 additions & 5 deletions components/mcp23x17/mcp23x17.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,17 @@ static esp_err_t write_reg_bit_8(mcp23x17_t *dev, uint8_t reg, bool val, uint8_t

#else

static esp_err_t spi_transmit(mcp23x17_t *dev, spi_transaction_t *t)
{
esp_err_t err;
if (dev->use_software_cs)
gpio_set_level(dev->cs_pin, 0);
err = spi_device_transmit(dev->spi_dev, t);
if (dev->use_software_cs)
gpio_set_level(dev->cs_pin, 1);
return err;
}

static esp_err_t read_reg_16(mcp23x17_t *dev, uint8_t reg, uint16_t *val)
{
CHECK_ARG(dev && val);
Expand All @@ -162,7 +173,7 @@ static esp_err_t read_reg_16(mcp23x17_t *dev, uint8_t reg, uint16_t *val)
t.tx_buffer = tx;
t.length = 32; // 32 bits

CHECK(spi_device_transmit(dev->spi_dev, &t));
CHECK(spi_transmit(dev, &t));

*val = (rx[3] << 8) | rx[2];

Expand All @@ -180,7 +191,7 @@ static esp_err_t write_reg_16(mcp23x17_t *dev, uint8_t reg, uint16_t val)
t.tx_buffer = tx;
t.length = 32; // 32 bits

CHECK(spi_device_transmit(dev->spi_dev, &t));
CHECK(spi_transmit(dev, &t));

return ESP_OK;
}
Expand Down Expand Up @@ -208,7 +219,7 @@ static esp_err_t read_reg_8(mcp23x17_t *dev, uint8_t reg, uint8_t *val)
t.tx_buffer = tx;
t.length = 24; // 24 bits

CHECK(spi_device_transmit(dev->spi_dev, &t));
CHECK(spi_transmit(dev, &t));

*val = rx[2];

Expand All @@ -226,7 +237,7 @@ static esp_err_t write_reg_8(mcp23x17_t *dev, uint8_t reg, uint8_t val)
t.tx_buffer = tx;
t.length = 24; // 24 bits

CHECK(spi_device_transmit(dev->spi_dev, &t));
CHECK(spi_transmit(dev, &t));

return ESP_OK;
}
Expand Down Expand Up @@ -310,9 +321,21 @@ esp_err_t mcp23x17_init_desc_spi(mcp23x17_t *dev, spi_host_device_t host, uint32
}

dev->addr = addr;
dev->cs_pin = cs_pin;

memset(&dev->spi_cfg, 0, sizeof(dev->spi_cfg));
dev->spi_cfg.spics_io_num = cs_pin;
if (dev->use_software_cs)
{
// Configure software Chip Select (CS) and pull the pin high.
dev->spi_cfg.spics_io_num = -1;
CHECK(gpio_set_direction(dev->cs_pin, GPIO_MODE_OUTPUT));
CHECK(gpio_set_level(dev->cs_pin, 1));
}
else
{
// Configure hardware CS.
dev->spi_cfg.spics_io_num = dev->cs_pin;
}
dev->spi_cfg.clock_speed_hz = clock_speed_hz;
dev->spi_cfg.mode = 0;
dev->spi_cfg.queue_size = 1;
Expand Down
5 changes: 5 additions & 0 deletions components/mcp23x17/mcp23x17.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ typedef struct
spi_device_interface_config_t spi_cfg;
spi_device_handle_t spi_dev;
uint8_t addr;
bool use_software_cs; //!< Use software CS control instead of hardware.
//!< Whether to use a software Chip Select (CS) line instead of the hardware
//!< one. This is useful when multiple MCP23S17 chips are sharing the same CS
//!< line on the SPI bus.
gpio_port_t cs_pin; //!< GPIO pin number for CS.
} mcp23x17_t;

#endif
Expand Down

0 comments on commit c6da185

Please sign in to comment.