1 // Copyright 2021 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 #include "pw_spi/chip_selector.h"
15 #include "pw_spi/device.h"
16 #include "pw_spi/initiator.h"
17 #include "pw_spi/responder.h"
18 #include "pw_status/status.h"
19 #include "pw_sync/borrow.h"
20 #include "pw_sync/mutex.h"
21 #include "pw_unit_test/framework.h"
22
23 namespace pw::spi {
24 namespace {
25
26 constexpr pw::spi::Config kConfig = {
27 .polarity = ClockPolarity::kActiveHigh,
28 .phase = ClockPhase::kFallingEdge,
29 .bits_per_word = BitsPerWord(8),
30 .bit_order = BitOrder::kMsbFirst,
31 };
32
33 class SpiTestDevice : public ::testing::Test {
34 public:
SpiTestDevice()35 SpiTestDevice()
36 : initiator_(),
37 chip_selector_(),
38 initiator_lock_(),
39 borrowable_initiator_(initiator_, initiator_lock_),
40 device_(borrowable_initiator_, kConfig, chip_selector_) {}
41
42 private:
43 // Stub SPI Initiator/ChipSelect objects, used to exercise public API surface.
44 class TestInitiator : public Initiator {
45 private:
DoConfigure(const Config &)46 Status DoConfigure(const Config& /*config */) override {
47 return OkStatus();
48 }
DoWriteRead(ConstByteSpan,ByteSpan)49 Status DoWriteRead(ConstByteSpan /* write_buffer */,
50 ByteSpan /* read_buffer */) override {
51 return OkStatus();
52 }
53 };
54
55 class TestChipSelector : public ChipSelector {
56 public:
SetActive(bool)57 Status SetActive(bool /*active*/) override { return OkStatus(); }
58 };
59
60 TestInitiator initiator_;
61 TestChipSelector chip_selector_;
62 sync::VirtualMutex initiator_lock_;
63 sync::Borrowable<Initiator> borrowable_initiator_;
64 Device device_;
65 };
66
67 class SpiResponderTestDevice : public ::testing::Test {
68 public:
SpiResponderTestDevice()69 SpiResponderTestDevice() : responder_() {}
70
71 private:
72 // Stub SPI Responder, used to exercise public API surface.
73 class TestResponder : public Responder {
74 private:
DoSetCompletionHandler(Function<void (ByteSpan,Status)>)75 void DoSetCompletionHandler(
76 Function<void(ByteSpan, Status)> /* callback */) override {}
DoWriteReadAsync(ConstByteSpan,ByteSpan)77 Status DoWriteReadAsync(ConstByteSpan /* tx_data */,
78 ByteSpan /* rx_data */) override {
79 return OkStatus();
80 }
DoCancel()81 void DoCancel() override {}
82 };
83
84 TestResponder responder_;
85 };
86
87 // Simple test ensuring the SPI HAL compiles
TEST_F(SpiTestDevice,CompilationSucceeds)88 TEST_F(SpiTestDevice, CompilationSucceeds) {
89 // arrange
90 // act
91 // assert
92 EXPECT_TRUE(true);
93 }
94
95 // Simple test ensuring the SPI Responder HAL compiles
TEST_F(SpiResponderTestDevice,CompilationSucceeds)96 TEST_F(SpiResponderTestDevice, CompilationSucceeds) { EXPECT_TRUE(true); }
97
98 // Config tests
99 static_assert(kConfig == kConfig);
100 static_assert(!(kConfig != kConfig));
101
TEST(Config,Equals)102 TEST(Config, Equals) {
103 Config lhs = kConfig;
104 Config rhs = kConfig;
105 EXPECT_EQ(lhs, rhs);
106 EXPECT_TRUE(lhs == rhs);
107 EXPECT_FALSE(lhs != rhs);
108 }
109
TEST(Config,NotEquals)110 TEST(Config, NotEquals) {
111 Config lhs = kConfig;
112 Config rhs = {
113 .polarity = ClockPolarity::kActiveLow, // different
114 .phase = ClockPhase::kFallingEdge,
115 .bits_per_word = BitsPerWord(8),
116 .bit_order = BitOrder::kMsbFirst,
117 };
118 EXPECT_NE(lhs, rhs);
119 EXPECT_FALSE(lhs == rhs);
120 EXPECT_TRUE(lhs != rhs);
121 }
122
123 } // namespace
124 } // namespace pw::spi
125