1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #pragma once
16
17 #include <array>
18 #include <cstddef>
19 #include <optional>
20
21 #include "pw_bytes/span.h"
22 #include "pw_containers/to_array.h"
23 #include "pw_spi/initiator.h"
24
25 namespace pw::spi {
26
27 // Represents a complete parameter set for the Initiator::WriteRead().
28 class MockTransaction {
29 public:
30 // Same set of parameters as Initiator::WriteRead().
MockTransaction(Status expected_return_value,ConstByteSpan write_buffer,ConstByteSpan read_buffer)31 constexpr MockTransaction(Status expected_return_value,
32 ConstByteSpan write_buffer,
33 ConstByteSpan read_buffer)
34 : return_value_(expected_return_value),
35 read_buffer_(read_buffer),
36 write_buffer_(write_buffer) {}
37
38 // Gets the buffer that is virtually read.
read_buffer()39 ConstByteSpan read_buffer() const { return read_buffer_; }
40
41 // Gets the buffer that should be written by the driver.
write_buffer()42 ConstByteSpan write_buffer() const { return write_buffer_; }
43
44 // Gets the expected return value.
return_value()45 Status return_value() const { return return_value_; }
46
47 private:
48 const Status return_value_;
49 const ConstByteSpan read_buffer_;
50 const ConstByteSpan write_buffer_;
51 };
52
53 // Read transaction is a helper that constructs a read only transaction.
MockReadTransaction(Status expected_return_value,ConstByteSpan read_buffer)54 constexpr MockTransaction MockReadTransaction(Status expected_return_value,
55 ConstByteSpan read_buffer) {
56 return MockTransaction(expected_return_value, ConstByteSpan(), read_buffer);
57 }
58
59 // WriteTransaction is a helper that constructs a write only transaction.
MockWriteTransaction(Status expected_return_value,ConstByteSpan write_buffer)60 constexpr MockTransaction MockWriteTransaction(Status expected_return_value,
61 ConstByteSpan write_buffer) {
62 return MockTransaction(expected_return_value, write_buffer, ConstByteSpan());
63 }
64
65 // MockInitiator takes a series of read and/or write transactions and
66 // compares them against user/driver input.
67 //
68 // This mock uses Gtest to ensure that the transactions instantiated meet
69 // expectations. This MockedInitiator should be instantiated inside a Gtest test
70 // frame.
71 class MockInitiator : public pw::spi::Initiator {
72 public:
MockInitiator(span<MockTransaction> transaction_list)73 explicit constexpr MockInitiator(span<MockTransaction> transaction_list)
74 : expected_transactions_(transaction_list),
75 expected_transaction_index_(0) {}
76
77 // Should be called at the end of the test to ensure that all expected
78 // transactions have been met.
79 // Returns:
80 // Ok - Success.
81 // OutOfRange - The mocked set of transactions has not been exhausted.
Finalize()82 Status Finalize() const {
83 if (expected_transaction_index_ != expected_transactions_.size()) {
84 return Status::OutOfRange();
85 }
86 return Status();
87 }
88
89 // Runs Finalize() regardless of whether it was already optionally finalized.
90 ~MockInitiator() override;
91
92 private:
93 span<MockTransaction> expected_transactions_;
94 size_t expected_transaction_index_;
95
96 // Implements a mocked backend for the SPI initiator.
97 //
98 // Expects (via Gtest):
99 // tx_buffer == expected_transaction_tx_buffer
100 // tx_buffer.size() == expected_transaction_tx_buffer.size()
101 // rx_buffer.size() == expected_transaction_rx_buffer.size()
102 //
103 // Asserts:
104 // When the number of calls to this method exceed the number of expected
105 // transactions.
106 //
107 // Returns:
108 // Specified transaction return type
109 pw::Status DoWriteRead(pw::ConstByteSpan, pw::ByteSpan) override;
110
DoConfigure(const pw::spi::Config &)111 pw::Status DoConfigure(const pw::spi::Config& /*config */) override {
112 return pw::OkStatus();
113 }
114 };
115
116 // Makes a new SPI transactions list.
117 template <size_t kSize>
MakeExpectedTransactionArray(const MockTransaction (& transactions)[kSize])118 constexpr std::array<MockTransaction, kSize> MakeExpectedTransactionArray(
119 const MockTransaction (&transactions)[kSize]) {
120 return containers::to_array(transactions);
121 }
122
123 } // namespace pw::spi
124