From 6f62099a7ed0c5f5c12d12f8a797f04b6a797feb Mon Sep 17 00:00:00 2001 From: Michal Morsisko Date: Sun, 1 Sep 2024 22:15:29 +0200 Subject: [PATCH] drivers: spi_bitbang: Add support for SPI_TRANSFER_LSB flag Add support for sending and receiving the least significant bit first for the spi_bitbang driver. This driver can now be used with SPI_TRANFER_LSB flag. Signed-off-by: Michal Morsisko --- drivers/spi/spi_bitbang.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index bffe93771794302..137f63b89b0e23c 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -36,8 +36,7 @@ static int spi_bitbang_configure(const struct spi_bitbang_config *info, return -ENOTSUP; } - if (config->operation & (SPI_TRANSFER_LSB | SPI_LINES_DUAL - | SPI_LINES_QUAD)) { + if (config->operation & (SPI_LINES_DUAL | SPI_LINES_QUAD)) { LOG_ERR("Unsupported configuration"); return -ENOTSUP; } @@ -124,6 +123,7 @@ static int spi_bitbang_transceive(const struct device *dev, int clock_state = 0; int cpha = 0; bool loop = false; + bool lsb = false; if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) { clock_state = 1; @@ -134,6 +134,9 @@ static int spi_bitbang_transceive(const struct device *dev, if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_LOOP) { loop = true; } + if (spi_cfg->operation & SPI_TRANSFER_LSB) { + lsb = true; + } /* set the initial clock state before CS */ gpio_pin_set_dt(&info->clk_gpio, clock_state); @@ -156,8 +159,8 @@ static int spi_bitbang_transceive(const struct device *dev, } } - int shift = data->bits - 1; uint16_t r = 0; + uint8_t i = 0; int b = 0; bool do_read = false; @@ -165,7 +168,8 @@ static int spi_bitbang_transceive(const struct device *dev, do_read = true; } - while (shift >= 0) { + while (i < data->bits) { + const int shift = lsb ? i : (data->bits - 1 - i); const int d = (w >> shift) & 0x1; b = 0; @@ -197,9 +201,9 @@ static int spi_bitbang_transceive(const struct device *dev, b = d; } - r = (r << 1) | (b ? 0x1 : 0x0); - - --shift; + r |= (b ? 0x1 : 0x0) << shift; + + ++i; } if (spi_context_rx_buf_on(ctx)) {