Compare commits

...

2 commits

Author SHA1 Message Date
072498d59d drivers: spi: spi_bitbang: reduce the ROM usage by making MISO optional
In the same way as mipi_dbi_spi, check if any of the spi_bitbang
instances define MISO and, if not, omit the supporting code. This is
useful on boards with limited memory with write-only devices such as
many SPI LCDs.

This reduces the ROM usage by 60 B. It didn't reduce as much as I
hoped due to how the half duplex support is implemented.

Signed-off-by: Michael Hope <mlhx@google.com>
2024-07-27 10:50:43 +00:00
37efde62fc drivers: spi: spi_bitbang: reduce the RAM overhead
Constify the config, shrink the data types so they fit the maximum
values, and reorder for better packing. This reduces the RAM usage by
32 bytes.

Signed-off-by: Michael Hope <mlhx@google.com>
2024-07-27 10:50:43 +00:00

View file

@ -14,17 +14,25 @@ LOG_MODULE_REGISTER(spi_bitbang);
#include <zephyr/drivers/spi.h>
#include "spi_context.h"
/* Expands to 1 if the node has no MISO GPIOs */
#define _MISO_PRESENT(n) (DT_INST_PROP_LEN_OR(n, miso_gpios, 0) != 0) |
#define SPI_BITBANG_MISO_REQUIRED DT_INST_FOREACH_STATUS_OKAY(_MISO_PRESENT) 0
struct spi_bitbang_data {
struct spi_context ctx;
int bits;
int wait_us;
int dfs;
int16_t wait_us;
/* Number of bits per word. Maximum is 16. */
int8_t bits;
/* Number of bytes per word. Maximum is 2. */
int8_t dfs;
};
struct spi_bitbang_config {
struct gpio_dt_spec clk_gpio;
struct gpio_dt_spec mosi_gpio;
#if SPI_BITBANG_MISO_REQUIRED
struct gpio_dt_spec miso_gpio;
#endif
};
static int spi_bitbang_configure(const struct spi_bitbang_config *info,
@ -105,10 +113,11 @@ static int spi_bitbang_transceive(const struct device *dev,
if (info->mosi_gpio.port) {
mosi = &info->mosi_gpio;
}
#if SPI_BITBANG_MISO_REQUIRED
if (info->miso_gpio.port) {
miso = &info->miso_gpio;
}
#endif
}
if (info->mosi_gpio.port) {
@ -284,6 +293,7 @@ int spi_bitbang_init(const struct device *dev)
}
}
#if SPI_BITBANG_MISO_REQUIRED
if (config->miso_gpio.port != NULL) {
if (!gpio_is_ready_dt(&config->miso_gpio)) {
LOG_ERR("GPIO port for miso pin is not ready");
@ -297,6 +307,7 @@ int spi_bitbang_init(const struct device *dev)
return rc;
}
}
#endif
rc = spi_context_cs_configure_all(&data->ctx);
if (rc < 0) {
@ -307,26 +318,25 @@ int spi_bitbang_init(const struct device *dev)
return 0;
}
#define SPI_BITBANG_INIT(inst) \
static struct spi_bitbang_config spi_bitbang_config_##inst = { \
.clk_gpio = GPIO_DT_SPEC_INST_GET(inst, clk_gpios), \
.mosi_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mosi_gpios, {0}), \
.miso_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, miso_gpios, {0}), \
}; \
\
static struct spi_bitbang_data spi_bitbang_data_##inst = { \
SPI_CONTEXT_INIT_LOCK(spi_bitbang_data_##inst, ctx), \
SPI_CONTEXT_INIT_SYNC(spi_bitbang_data_##inst, ctx), \
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx) \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
spi_bitbang_init, \
NULL, \
&spi_bitbang_data_##inst, \
&spi_bitbang_config_##inst, \
POST_KERNEL, \
CONFIG_SPI_INIT_PRIORITY, \
&spi_bitbang_api);
#if SPI_BITBANG_MISO_REQUIRED
#define SPI_BITBANG_INIT_MISO(inst) .miso_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, miso_gpios, {0}),
#else
#define SPI_BITBANG_INIT_MISO(inst)
#endif
#define SPI_BITBANG_INIT(inst) \
static const struct spi_bitbang_config spi_bitbang_config_##inst = { \
.clk_gpio = GPIO_DT_SPEC_INST_GET(inst, clk_gpios), \
.mosi_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mosi_gpios, {0}), \
SPI_BITBANG_INIT_MISO(inst)}; \
\
static struct spi_bitbang_data spi_bitbang_data_##inst = { \
SPI_CONTEXT_INIT_LOCK(spi_bitbang_data_##inst, ctx), \
SPI_CONTEXT_INIT_SYNC(spi_bitbang_data_##inst, ctx), \
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx)}; \
\
DEVICE_DT_INST_DEFINE(inst, spi_bitbang_init, NULL, &spi_bitbang_data_##inst, \
&spi_bitbang_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \
&spi_bitbang_api);
DT_INST_FOREACH_STATUS_OKAY(SPI_BITBANG_INIT)