xref: /aosp_15_r20/external/pigweed/pw_i2c_mcuxpresso/public/pw_i2c_mcuxpresso/i3c_initiator.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 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 #pragma once
15 
16 #include <optional>
17 
18 #include "fsl_clock.h"
19 #include "fsl_i3c.h"
20 #include "pw_bytes/span.h"
21 #include "pw_containers/vector.h"
22 #include "pw_i2c/initiator.h"
23 #include "pw_i2c_mcuxpresso/i3c_ccc.h"
24 #include "pw_status/status.h"
25 #include "pw_sync/mutex.h"
26 
27 namespace pw::i2c {
28 
29 // I2C initiator interface implementation fsl_i3c driver in NXP MCUXpresso SDK.
30 class I3cMcuxpressoInitiator final : public pw::i2c::Initiator {
31  public:
32   struct Config {
33     uint32_t base_address;              // I3C peripheral base address.
34     uint32_t i2c_baud_rate;             // I2C baud rate in Hz.
35     uint32_t i3c_open_drain_baud_rate;  // I3C open drain baud rate in Hz.
36     uint32_t i3c_push_pull_baud_rate;   // I3C push pull baud rate in Hz.
37     bool enable_open_drain_stop;  // Whether to emit open-drain speed STOP.
38     bool enable_open_drain_high;  // Enable Open-Drain High to be 1 PPBAUD count
39                                   // for I3C messages, or 1 ODBAUD.
40   };
I3cMcuxpressoInitiator(const Config & config)41   I3cMcuxpressoInitiator(const Config& config)
42       : config_(config),
43         base_(reinterpret_cast<I3C_Type*>(config.base_address)) {}
44 
45   // Initializes the I3C controller peripheral as configured in the constructor.
46   void Enable() PW_LOCKS_EXCLUDED(mutex_);
47 
48   // Deinitializes the I3C controller peripheral.
49   void Disable() PW_LOCKS_EXCLUDED(mutex_);
50 
51   // Set dynamic address list, which will be used to assign dynamic addresses to
52   // I3C devices on the bus during bus initialization step, or to determine the
53   // type (I2C or I3C) for each transaction.
54   //
55   // Warning: dynamic address list can only be set once.
56   pw::Status SetDynamicAddressList(
57       pw::span<const uint8_t> dynamic_address_list);
58 
59   // Initialize the I3C bus (Dynamic address assignment)
60   //
61   // Warning: Users should set correct dynamic addresses (SetDynamicAddressList)
62   // before calling this function.
63   pw::Status Initialize() PW_LOCKS_EXCLUDED(mutex_);
64 
65  private:
66   pw::Status DoTransferCcc(I3cCccAction rnw,
67                            I3cCcc ccc_id,
68                            pw::i2c::Address address,
69                            pw::ByteSpan buffer);
70   pw::Status DoWriteReadFor(pw::i2c::Address address,
71                             pw::ConstByteSpan tx_buffer,
72                             pw::ByteSpan rx_buffer,
73                             pw::chrono::SystemClock::duration timeout)
74       PW_LOCKS_EXCLUDED(mutex_);
75 
76   const Config& config_;
77   I3C_Type* base_;
78   i3c_device_info_t* device_list_ = nullptr;
79   uint8_t device_count_ = 0;
80   bool enabled_ PW_GUARDED_BY(mutex_) = false;
81   pw::sync::Mutex mutex_;
82   std::optional<pw::Vector<uint8_t, I3C_MAX_DEVCNT>> i3c_dynamic_address_list_;
83 };
84 
85 }  // namespace pw::i2c
86