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 <morsisko@gmail.com>
This commit is contained in:
Michal Morsisko 2024-09-01 22:15:29 +02:00 committed by Benjamin Cabé
parent f4267ecce4
commit b76b2bbc8c

View file

@ -37,8 +37,7 @@ static int spi_bitbang_configure(const struct spi_bitbang_config *info,
return -ENOTSUP; return -ENOTSUP;
} }
if (config->operation & (SPI_TRANSFER_LSB | SPI_LINES_DUAL if (config->operation & (SPI_LINES_DUAL | SPI_LINES_QUAD)) {
| SPI_LINES_QUAD)) {
LOG_ERR("Unsupported configuration"); LOG_ERR("Unsupported configuration");
return -ENOTSUP; return -ENOTSUP;
} }
@ -125,6 +124,7 @@ static int spi_bitbang_transceive(const struct device *dev,
int clock_state = 0; int clock_state = 0;
int cpha = 0; int cpha = 0;
bool loop = false; bool loop = false;
bool lsb = false;
if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) { if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) {
clock_state = 1; clock_state = 1;
@ -135,6 +135,9 @@ static int spi_bitbang_transceive(const struct device *dev,
if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_LOOP) { if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_LOOP) {
loop = true; loop = true;
} }
if (spi_cfg->operation & SPI_TRANSFER_LSB) {
lsb = true;
}
/* set the initial clock state before CS */ /* set the initial clock state before CS */
gpio_pin_set_dt(&info->clk_gpio, clock_state); gpio_pin_set_dt(&info->clk_gpio, clock_state);
@ -157,8 +160,8 @@ static int spi_bitbang_transceive(const struct device *dev,
} }
} }
int shift = data->bits - 1;
uint16_t r = 0; uint16_t r = 0;
uint8_t i = 0;
int b = 0; int b = 0;
bool do_read = false; bool do_read = false;
@ -166,7 +169,8 @@ static int spi_bitbang_transceive(const struct device *dev,
do_read = true; 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; const int d = (w >> shift) & 0x1;
b = 0; b = 0;
@ -198,9 +202,9 @@ static int spi_bitbang_transceive(const struct device *dev,
b = d; b = d;
} }
r = (r << 1) | (b ? 0x1 : 0x0); r |= (b ? 0x1 : 0x0) << shift;
--shift; ++i;
} }
if (spi_context_rx_buf_on(ctx)) { if (spi_context_rx_buf_on(ctx)) {