xref: /aosp_15_r20/external/pigweed/pw_i2c_mcuxpresso/public/pw_i2c_mcuxpresso/initiator.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2022 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 "fsl_clock.h"
17 #include "fsl_i2c.h"
18 #include "pw_i2c/initiator.h"
19 #include "pw_sync/interrupt_spin_lock.h"
20 #include "pw_sync/lock_annotations.h"
21 #include "pw_sync/mutex.h"
22 #include "pw_sync/timed_thread_notification.h"
23 
24 namespace pw::i2c {
25 
26 // Initiator interface implementation based on I2C driver in NXP MCUXpresso SDK.
27 // Currently supports only devices with 7 bit adresses.
28 class McuxpressoInitiator final : public Initiator {
29  public:
30   struct Config {
31     uint32_t flexcomm_address;
32     clock_name_t clock_name;
33     uint32_t baud_rate_bps;
34   };
35 
McuxpressoInitiator(const Config & config)36   McuxpressoInitiator(const Config& config)
37       : config_(config),
38         base_(reinterpret_cast<I2C_Type*>(config_.flexcomm_address)) {}
39 
40   // Should be called before attempting any transfers.
41   void Enable() PW_LOCKS_EXCLUDED(mutex_);
42   void Disable() PW_LOCKS_EXCLUDED(mutex_);
43 
44   ~McuxpressoInitiator() final;
45 
46  private:
47   Status DoWriteReadFor(Address device_address,
48                         ConstByteSpan tx_buffer,
49                         ByteSpan rx_buffer,
50                         chrono::SystemClock::duration timeout) override
51       PW_LOCKS_EXCLUDED(mutex_);
52 
53   // inclusive-language: disable
54   Status InitiateNonBlockingTransfer(chrono::SystemClock::duration rw_timeout,
55                                      i2c_master_transfer_t* transfer)
56       PW_LOCKS_EXCLUDED(callback_isl_);
57 
58   // Non-blocking I2C transfer callback.
59   static void TransferCompleteCallback(I2C_Type* base,
60                                        i2c_master_handle_t* handle,
61                                        status_t status,
62                                        void* initiator_ptr)
63       PW_GUARDED_BY(callback_isl_);
64   // inclusive-language: enable
65 
66   sync::Mutex mutex_;
67   Config const config_;
68   I2C_Type* const base_;
69   bool enabled_ PW_GUARDED_BY(mutex_);
70 
71   // Transfer completion status for non-blocking I2C transfer.
72   sync::TimedThreadNotification callback_complete_notification_;
73   sync::InterruptSpinLock callback_isl_;
74   status_t transfer_status_ PW_GUARDED_BY(callback_isl_);
75 
76   // inclusive-language: disable
77   i2c_master_handle_t handle_ PW_GUARDED_BY(mutex_);
78   // inclusive-language: enable
79 };
80 
81 }  // namespace pw::i2c
82