xref: /aosp_15_r20/external/pigweed/pw_spi_mcuxpresso/public/pw_spi_mcuxpresso/flexio_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 "fsl_flexio_spi.h"
18 #include "pw_digital_io/digital_io.h"
19 #include "pw_spi/chip_selector.h"
20 #include "pw_spi/initiator.h"
21 #include "pw_status/status.h"
22 #include "pw_sync/binary_semaphore.h"
23 #include "pw_sync/lock_annotations.h"
24 #include "pw_sync/mutex.h"
25 
26 namespace pw::spi {
27 
28 // Mcuxpresso SDK implementation of the FLEXIO SPI Initiator
29 class McuxpressoFlexIoInitiator : public Initiator {
30  public:
31   McuxpressoFlexIoInitiator(FLEXIO_SPI_Type flexio_spi_config,
32                             uint32_t src_clock_hz,
33                             uint32_t baud_rate_bps,
34                             bool blocking = true)
flexio_spi_config_(flexio_spi_config)35       : flexio_spi_config_(flexio_spi_config),
36         src_clock_hz_(src_clock_hz),
37         baud_rate_bps_(baud_rate_bps),
38         blocking_(blocking) {}
39   ~McuxpressoFlexIoInitiator();
40 
41  private:
42   // inclusive-language: disable
43   static void SpiCallback(FLEXIO_SPI_Type*,
44                           flexio_spi_master_handle_t*,
45                           status_t status,
46                           void* context);
47   // Add support to FLEXIO_SPI for negative clock polarity.
48   void ConfigureClock(flexio_spi_master_config_t* masterConfig,
49                       ClockPolarity clockPolarity);
50 
is_initialized()51   bool is_initialized() { return !!current_config_; }
52 
53   // Implements pw::spi::Initiator
54   pw::Status DoConfigure(const Config& config)
55       PW_LOCKS_EXCLUDED(mutex_) override;
56   pw::Status DoWriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer)
57       PW_LOCKS_EXCLUDED(mutex_) override;
58 
59   std::optional<const Config> current_config_;
60   FLEXIO_SPI_Type flexio_spi_config_;
61   flexio_spi_master_handle_t driver_handle_;
62   // inclusive-language: enable
63   sync::BinarySemaphore transfer_semaphore_;
64   sync::Mutex mutex_;
65   Status last_transfer_status_;
66   uint32_t src_clock_hz_;
67   uint32_t baud_rate_bps_;
68   bool blocking_;
69   uint8_t transfer_flags_;
70 };
71 
72 // Mcuxpresso userspace implementation of SPI ChipSelector. Implemented using
73 // GPIO so as to support manual control of chip select. GPIO pin passed in
74 // should be already initialized and ungated.
75 class McuxpressoFlexIoChipSelector : public ChipSelector {
76  public:
McuxpressoFlexIoChipSelector(digital_io::DigitalOut & pin)77   explicit McuxpressoFlexIoChipSelector(digital_io::DigitalOut& pin)
78       : pin_(pin) {}
79 
80   // Implements pw::spi::ChipSelector
81   pw::Status SetActive(bool active) override;
82 
83  private:
84   digital_io::DigitalOut& pin_;
85 };
86 
87 }  // namespace pw::spi
88