pw_spi: Correct full-duplex behavior of linux_spi

Prior to this change, LinuxInitiator::WriteRead() would always perform a
compound transfer, sending write_buffer *then* receiving read_buffer,
i.e. a half-duplex write-then-read operation.

This corrects that behavior to match the interface which describes a
full-duplex (simultaneous write and read) operation.

Note that `struct spi_ioc_transfer` only has a single `len` field
describing the number of bytes to send and receive in that transfer.
Because write_buffer and read_buffer could have different sizes,
this implementation will split the transaction into two transfers if
necessary to transfer the longer of the two.

Also add missing "override" to ~LinuxInitiator(), and remove a few
extraneous #includes.

Test: bazel test //pw_spi:linux_spi_test
Test: Execute a test application on a Linux host connected to a SPI
      responder MCU programmed to send a fixed message with no dummy
      cycles.
Test: Call WriteRead() with buffers of the same size. Verify message
      is received in read_buffer. Verify via logic analyzer that a
      single transaction is performed (no extra clock cycles).
Test: Call WriteRead with write_buffer longer than read_buffer.
      Verify (partial) message is received in read_buffer. Verify via
      logic analyzer that two transfers were performed (indicated by
      inter-transfer delay with CS still active), and only
      write_buffer.size() bytes were transmitted.
Test: Call WriteRead with read_buffer longer than write_buffer.
      Verify message is received in read_buffer. Verify via logic
      analyzer that two transfers were performed, and the transmitted
      data was zero-padded out to read_buffer.size().
Bug: b/316067628
Change-Id: I4bec1d46286384709eca052322a7cf3047d26296
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/192591
Reviewed-by: Mark Slevinsky <markslevinsky@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Commit-Queue: Jonathon Reinhart <jrreinhart@google.com>
6 files changed
tree: 01d77f1ee9d5ca41d1ed88ed7443bb65811a4298
  1. .allstar/
  2. .vscode/
  3. build_overrides/
  4. docker/
  5. docs/
  6. kudzu/
  7. pw_alignment/
  8. pw_allocator/
  9. pw_analog/
  10. pw_android_toolchain/
  11. pw_arduino_build/
  12. pw_assert/
  13. pw_assert_basic/
  14. pw_assert_log/
  15. pw_assert_tokenized/
  16. pw_assert_zephyr/
  17. pw_async/
  18. pw_async2/
  19. pw_async2_basic/
  20. pw_async_basic/
  21. pw_base64/
  22. pw_bloat/
  23. pw_blob_store/
  24. pw_bluetooth/
  25. pw_bluetooth_hci/
  26. pw_bluetooth_profiles/
  27. pw_bluetooth_sapphire/
  28. pw_boot/
  29. pw_boot_cortex_m/
  30. pw_build/
  31. pw_build_info/
  32. pw_build_mcuxpresso/
  33. pw_bytes/
  34. pw_channel/
  35. pw_checksum/
  36. pw_chre/
  37. pw_chrono/
  38. pw_chrono_embos/
  39. pw_chrono_freertos/
  40. pw_chrono_rp2040/
  41. pw_chrono_stl/
  42. pw_chrono_threadx/
  43. pw_chrono_zephyr/
  44. pw_cli/
  45. pw_compilation_testing/
  46. pw_config_loader/
  47. pw_console/
  48. pw_containers/
  49. pw_cpu_exception/
  50. pw_cpu_exception_cortex_m/
  51. pw_crypto/
  52. pw_digital_io/
  53. pw_digital_io_mcuxpresso/
  54. pw_digital_io_rp2040/
  55. pw_docgen/
  56. pw_doctor/
  57. pw_emu/
  58. pw_env_setup/
  59. pw_env_setup_zephyr/
  60. pw_file/
  61. pw_format/
  62. pw_function/
  63. pw_fuzzer/
  64. pw_grpc/
  65. pw_hdlc/
  66. pw_hex_dump/
  67. pw_i2c/
  68. pw_i2c_linux/
  69. pw_i2c_mcuxpresso/
  70. pw_ide/
  71. pw_interrupt/
  72. pw_interrupt_cortex_m/
  73. pw_interrupt_xtensa/
  74. pw_interrupt_zephyr/
  75. pw_intrusive_ptr/
  76. pw_kvs/
  77. pw_libc/
  78. pw_libcxx/
  79. pw_log/
  80. pw_log_android/
  81. pw_log_basic/
  82. pw_log_null/
  83. pw_log_rpc/
  84. pw_log_string/
  85. pw_log_tokenized/
  86. pw_log_zephyr/
  87. pw_malloc/
  88. pw_malloc_freelist/
  89. pw_malloc_freertos/
  90. pw_metric/
  91. pw_minimal_cpp_stdlib/
  92. pw_module/
  93. pw_multibuf/
  94. pw_multisink/
  95. pw_package/
  96. pw_perf_test/
  97. pw_persistent_ram/
  98. pw_polyfill/
  99. pw_preprocessor/
  100. pw_presubmit/
  101. pw_protobuf/
  102. pw_protobuf_compiler/
  103. pw_random/
  104. pw_result/
  105. pw_ring_buffer/
  106. pw_router/
  107. pw_rpc/
  108. pw_rpc_transport/
  109. pw_rust/
  110. pw_snapshot/
  111. pw_software_update/
  112. pw_span/
  113. pw_spi/
  114. pw_spi_mcuxpresso/
  115. pw_status/
  116. pw_stm32cube_build/
  117. pw_stream/
  118. pw_stream_shmem_mcuxpresso/
  119. pw_stream_uart_linux/
  120. pw_stream_uart_mcuxpresso/
  121. pw_string/
  122. pw_symbolizer/
  123. pw_sync/
  124. pw_sync_baremetal/
  125. pw_sync_embos/
  126. pw_sync_freertos/
  127. pw_sync_stl/
  128. pw_sync_threadx/
  129. pw_sync_zephyr/
  130. pw_sys_io/
  131. pw_sys_io_ambiq_sdk/
  132. pw_sys_io_arduino/
  133. pw_sys_io_baremetal_lm3s6965evb/
  134. pw_sys_io_baremetal_stm32f429/
  135. pw_sys_io_emcraft_sf2/
  136. pw_sys_io_mcuxpresso/
  137. pw_sys_io_rp2040/
  138. pw_sys_io_stdio/
  139. pw_sys_io_stm32cube/
  140. pw_sys_io_zephyr/
  141. pw_system/
  142. pw_target_runner/
  143. pw_thread/
  144. pw_thread_embos/
  145. pw_thread_freertos/
  146. pw_thread_stl/
  147. pw_thread_threadx/
  148. pw_thread_zephyr/
  149. pw_tls_client/
  150. pw_tls_client_boringssl/
  151. pw_tls_client_mbedtls/
  152. pw_tokenizer/
  153. pw_toolchain/
  154. pw_toolchain_bazel/
  155. pw_trace/
  156. pw_trace_tokenized/
  157. pw_transfer/
  158. pw_unit_test/
  159. pw_unit_test_zephyr/
  160. pw_varint/
  161. pw_watch/
  162. pw_web/
  163. pw_work_queue/
  164. seed/
  165. targets/
  166. third_party/
  167. ts/
  168. zephyr/
  169. .bazelignore
  170. .bazelrc
  171. .black.toml
  172. .clang-format
  173. .clang-tidy
  174. .eslintrc.cjs
  175. .git-blame-ignore-revs
  176. .gitattributes
  177. .gitignore
  178. .gn
  179. .mypy.ini
  180. .prettierignore
  181. .prettierrc.cjs
  182. .pw_ide.yaml
  183. .pylintrc
  184. activate.bat
  185. Android.bp
  186. AUTHORS
  187. bootstrap.bat
  188. bootstrap.sh
  189. BUILD.bazel
  190. BUILD.gn
  191. BUILDCONFIG.gn
  192. CMakeLists.txt
  193. jest.config.ts
  194. Kconfig.zephyr
  195. LICENSE
  196. modules.gni
  197. OWNERS
  198. package-lock.json
  199. package.json
  200. pigweed.json
  201. PIGWEED_MODULES
  202. README.md
  203. rollup.config.js
  204. tsconfig.json
  205. WORKSPACE
README.md

Pigweed

Pigweed is an open source collection of embedded-targeted libraries–or as we like to call them, modules. These modules are building blocks and infrastructure that enable faster and more reliable development on small-footprint MMU-less 32-bit microcontrollers like the STMicroelectronics STM32L452 or the Nordic nRF52832.

For more information please see our website: https://pigweed.dev/.

Links