xref: /aosp_15_r20/external/pigweed/pw_spi_mcuxpresso/public/pw_spi_mcuxpresso/spi.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 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 <cinttypes>
18 #include <mutex>
19 #include <optional>
20 
21 #include "fsl_spi.h"
22 #include "pw_spi/chip_selector.h"
23 #include "pw_spi/initiator.h"
24 #include "pw_status/status.h"
25 #include "pw_sync/binary_semaphore.h"
26 #include "pw_sync/lock_annotations.h"
27 #include "pw_sync/mutex.h"
28 
29 namespace pw::spi {
30 
31 // Mcuxpresso SDK implementation of the SPI Initiator
32 class McuxpressoInitiator : public Initiator {
33  public:
34   McuxpressoInitiator(SPI_Type* register_map,
35                       uint32_t max_speed_hz,
36                       uint32_t baud_rate_bps,
37                       bool blocking = true)
register_map_(register_map)38       : register_map_(register_map),
39         max_speed_hz_(max_speed_hz),
40         baud_rate_bps_(baud_rate_bps),
41         blocking_(blocking) {}
42   ~McuxpressoInitiator();
43 
44   Status SetChipSelect(uint32_t pin) PW_LOCKS_EXCLUDED(mutex_);
45 
46  private:
47   // inclusive-language: disable
48   static void SpiCallback(SPI_Type* base,
49                           spi_master_handle_t* driver_handle,
50                           status_t status,
51                           void* context);
52 
53   Status DoConfigureLocked(const Config& config,
54                            const std::lock_guard<sync::Mutex>& lock);
55 
is_initialized()56   bool is_initialized() { return !!current_config_; }
57 
58   // Implements pw::spi::Initiator
59   Status DoConfigure(const Config& config) PW_LOCKS_EXCLUDED(mutex_) override;
60   Status DoWriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer)
61       PW_LOCKS_EXCLUDED(mutex_) override;
62 
63   SPI_Type* register_map_;
64   spi_master_handle_t driver_handle_;
65   // inclusive-language: enable
66   sync::BinarySemaphore transfer_semaphore_;
67   sync::Mutex mutex_;
68   Status last_transfer_status_;
69   uint32_t max_speed_hz_;
70   uint32_t baud_rate_bps_;
71   bool blocking_;
72   std::optional<const Config> current_config_;
73   uint32_t pin_ = 0;
74 };
75 
76 // Mcuxpresso userspace implementation of SPI ChipSelector
77 // NOTE: This implementation deviates from the expected for this interface.
78 // It only specifies which chipselect pin should be activated and does not
79 // activate the pin itself. Activation of the pin is handled at a lower level by
80 // the Mcuxpresso vendor driver.
81 // This chipselector may only be used with a single McuxpressoInitiator
82 class McuxpressoChipSelector : public ChipSelector {
83  public:
McuxpressoChipSelector(McuxpressoInitiator & initiator,uint32_t pin)84   McuxpressoChipSelector(McuxpressoInitiator& initiator, uint32_t pin)
85       : initiator_(initiator), pin_(pin) {}
86 
87   // Implements pw::spi::ChipSelector
88   // Instead of directly activating the cs line, this informs the underlying
89   // driver to do so.
SetActive(bool active)90   Status SetActive(bool active) override {
91     // TODO: https://pwbug.dev/348512572 - Respect 'active'
92     static_cast<void>(active);
93     return initiator_.SetChipSelect(pin_);
94   }
95 
96  private:
97   McuxpressoInitiator& initiator_;
98   uint32_t pin_;
99 };
100 
101 }  // namespace pw::spi
102