C/C++ API Reference
Loading...
Searching...
No Matches
device.h
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
15#pragma once
16
17#include <utility>
18
19#include "pw_bytes/span.h"
20#include "pw_spi/chip_selector.h"
21#include "pw_spi/initiator.h"
22#include "pw_status/status.h"
23#include "pw_status/try.h"
24#include "pw_sync/borrow.h"
25
26namespace pw::spi {
27
29
58class Device {
59 public:
61 const Config config,
62 ChipSelector& selector)
63 : initiator_(initiator), config_(config), selector_(selector) {}
64
65 ~Device() = default;
66
78 Status Read(ByteSpan read_buffer) { return WriteRead({}, read_buffer); }
79
90 Status Write(ConstByteSpan write_buffer) {
91 return WriteRead(write_buffer, {});
92 }
93
110 Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer) {
111 return StartTransaction(ChipSelectBehavior::kPerWriteRead)
112 .WriteRead(write_buffer, read_buffer);
113 }
114
119 class Transaction final {
120 public:
121 Transaction() = delete;
122 ~Transaction() {
123 if ((selector_ != nullptr) &&
124 (behavior_ == ChipSelectBehavior::kPerTransaction) &&
125 (!first_write_read_)) {
126 selector_->Deactivate()
127 .IgnoreError(); // TODO: b/242598609 - Handle Status properly
128 }
129 }
130
133 : initiator_(std::move(other.initiator_)),
134 config_(other.config_),
135 selector_(other.selector_),
136 behavior_(other.behavior_),
137 first_write_read_(other.first_write_read_) {
138 other.selector_ = nullptr;
139 }
140
141 Transaction& operator=(Transaction&& other) {
142 initiator_ = std::move(other.initiator_);
143 config_ = other.config_;
144 selector_ = other.selector_;
145 other.selector_ = nullptr;
146 behavior_ = other.behavior_;
147 first_write_read_ = other.first_write_read_;
148 return *this;
149 }
150
151 Transaction(const Transaction&) = delete;
152 Transaction& operator=(const Transaction&) = delete;
153
159 Status Read(ByteSpan read_buffer) { return WriteRead({}, read_buffer); }
160
166 Status Write(ConstByteSpan write_buffer) {
167 return WriteRead(write_buffer, {});
168 }
169
181 Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer) {
182 // Lazy-init: Configure the SPI bus when performing the first transfer in
183 // a transaction.
184 if (first_write_read_) {
185 PW_TRY(initiator_->Configure(config_));
186 }
187
188 if ((behavior_ == ChipSelectBehavior::kPerWriteRead) ||
189 (first_write_read_)) {
190 PW_TRY(selector_->Activate());
191 first_write_read_ = false;
192 }
193
194 auto status = initiator_->WriteRead(write_buffer, read_buffer);
195
196 if (behavior_ == ChipSelectBehavior::kPerWriteRead) {
197 PW_TRY(selector_->Deactivate());
198 }
199
200 return status;
201 }
202
203 private:
204 friend Device;
206 const Config& config,
207 ChipSelector& selector,
208 ChipSelectBehavior& behavior)
209 : initiator_(std::move(initiator)),
210 config_(config),
211 selector_(&selector),
212 behavior_(behavior),
213 first_write_read_(true) {}
214
216 Config config_;
217 ChipSelector* selector_;
218 ChipSelectBehavior behavior_;
219 bool first_write_read_;
220 };
221
232 return Transaction(initiator_.acquire(), config_, selector_, behavior);
233 }
234
235 private:
237 const Config config_;
238 ChipSelector& selector_;
239};
240
242
243} // namespace pw::spi
Definition: status.h:109
constexpr void IgnoreError() const
Definition: status.h:283
Definition: chip_selector.h:49
Status Deactivate()
Definition: chip_selector.h:93
Status Activate()
Definition: chip_selector.h:80
Definition: device.h:119
Transaction(Transaction &&other)
Transaction objects are moveable but not copyable.
Definition: device.h:132
Status Write(ConstByteSpan write_buffer)
Definition: device.h:166
Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer)
Definition: device.h:181
Status Read(ByteSpan read_buffer)
Definition: device.h:159
Definition: device.h:58
Status Write(ConstByteSpan write_buffer)
Definition: device.h:90
Transaction StartTransaction(ChipSelectBehavior behavior)
Definition: device.h:231
Status Read(ByteSpan read_buffer)
Definition: device.h:78
Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer)
Definition: device.h:110
Definition: borrow.h:164
Definition: borrow.h:33
ChipSelectBehavior
Definition: chip_selector.h:30
#define PW_TRY(expr)
Returns early if expr is a non-OK Status or Result.
Definition: try.h:27
Definition: initiator.h:67