CV-Bowen opened a new pull request, #21069:
URL: https://github.com/apache/nuttx/pull/21069
## Summary
`spi_transfer()` always de-selects the device at the end of a sequence,
so a caller cannot express "keep CS asserted for the next sequence". A
protocol backend needs that: virtio-spi carries a `cs_change` flag, and
its false value means the next request continues on the same chip select
without a new select/deselect cycle.
Add `spi_sequence_s.keepcs`. With it set, the trailing `SPI_SELECT()` is
skipped; an aborted sequence (`ret < 0`) still de-selects, so CS is never
left asserted after an error. Honor `HWFEAT_FORCE_CS_ACTIVE/INACTIVE_AFTER_
TRANSFER` in the per-transfer de-select decision as well.
## Impact
- `struct spi_sequence_s` gains a byte. Nothing in tree initializes it
positionally (`regmap_spi.c` and `spitool` assign fields by name), and a
zero-initialized sequence keeps the current behavior, so existing
callers are unaffected.
- No Kconfig change.
- The first user will be the vhost-spi backend, which is not upstream yet.
## Testing
Host: Ubuntu 22.04.5 LTS x86_64, QEMU version 10.2.1, sim: cc (Ubuntu
13.1.0-8ubuntu1~22.04) 13.1.0, qemu-armv8a: aarch64-none-elf-gcc (Arm GNU
Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
A sequence that keeps CS leaves it asserted, one that does not still
de-asserts it. Checked on `sim:nsh` with a small app that builds its own
`spi_dev_s` whose `select` records the state and calls `spi_transfer()`
directly, so no board SPI controller is involved:
```
nsh> keepcstest
keepcs=0 cs=0
keepcs=1 round 0 cs=1 selects=2
keepcs=1 round 1 cs=1 selects=4
```
`cs=0` for the first sequence is the unchanged behavior; `cs=1` after
each `keepcs=1` sequence shows CS carried over, and `selects` counts the
two `select(true)` calls per sequence (one before the loop, one inside
it).
<details><summary>Test app (not part of this PR)</summary>
```c
int main(int argc, FAR char *argv[])
{
FAR struct keepcs_dev_s *priv = &g_keepcs_dev;
struct spi_sequence_s seq;
int i;
memset(&seq, 0, sizeof(seq));
seq.dev = SPIDEV_NONE(0);
seq.ntrans = 1;
seq.trans = &g_trans;
seq.frequency = 1000000;
seq.keepcs = 0;
spi_transfer(&priv->dev, &seq);
printf("keepcs=0 cs=%d\n", priv->selected ? 1 : 0);
priv->selected = false;
priv->selects = 0;
seq.keepcs = 1;
for (i = 0; i < 2; i++)
{
spi_transfer(&priv->dev, &seq);
printf("keepcs=1 round %d cs=%d selects=%d\n",
i, priv->selected ? 1 : 0, priv->selects);
}
return 0;
}
```
</details>
Baseline (`test.sh`, cases: baseline.yaml):
- host: Ubuntu 22.04.5 LTS x86_64, QEMU version 10.2.1, sim: cc (Ubuntu
13.1.0-8ubuntu1~22.04) 13.1.0, qemu-armv8a: aarch64-none-elf-gcc (Arm GNU
Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
- tested: nuttx 848c63288a9 apps 5f1100d02
- qemu-armv8a built with test-only overlay: disabled LIBC_ENVPATH
BINFMT_CHECKEXEC
- sim:rpserver + sim:rpproxy: PASS
- [x] `uname -a` (server)
- [x] `rpmsg dump all` (server)
- [x] `rpmsg ping all 10 1024 3 0` (server)
- [x] `uname -a` (proxy)
- [x] `rpmsg ping all 10 1024 3 0` (proxy)
- [x] `mount -t rpmsgfs -o cpu=server,fs=/proc /sp` (proxy)
- [x] `cat /sp/version` (proxy)
- [x] `rpmsg dump all` (proxy)
- qemu-armv8a:rpserver + qemu-armv8a:rpproxy: PASS
- [x] `uname -a` (server)
- [x] `uname -a` (proxy)
- [x] `rpmsg dump all` (server)
- [x] `rpmsg ping all 10 1024 3 0` (server)
- [x] `rpmsg ping all 10 1024 3 0` (proxy)
- [x] `mount -t rpmsgfs -o cpu=server,fs=/proc /sp` (proxy)
- [x] `cat /sp/version` (proxy)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]