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