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 "fsl_usart.h" 17 #include "pw_bytes/span.h" 18 #include "pw_clock_tree/clock_tree.h" 19 #include "pw_status/status.h" 20 #include "pw_stream/stream.h" 21 22 namespace pw::stream { 23 24 // Stream to output to a UART that is safe to use in an interrupt or fault 25 // handler context. 26 class InterruptSafeUartWriterMcuxpresso : public pw::stream::NonSeekableWriter { 27 public: 28 // Make sure constructor is constexpr. When used with `constinit`, this 29 // ensures that the object is fully constructed prior to static constructors 30 // having been executed. 31 // Doing so requires passing in the uart base pointer as a uintptr_t instead 32 // of USART_Type* to avoid needing a reinterpret_cast. InterruptSafeUartWriterMcuxpresso(uintptr_t base,clock_name_t clock_name,unsigned int baudrate,pw::clock_tree::ClockTree & clock_tree,pw::clock_tree::Element & clock_tree_element)33 constexpr InterruptSafeUartWriterMcuxpresso( 34 uintptr_t base, 35 clock_name_t clock_name, 36 unsigned int baudrate, 37 pw::clock_tree::ClockTree& clock_tree, 38 pw::clock_tree::Element& clock_tree_element) 39 : base_(base), 40 baudrate_(baudrate), 41 element_controller_(&clock_tree, &clock_tree_element), 42 clock_name_(clock_name) {} 43 InterruptSafeUartWriterMcuxpresso(uintptr_t base,clock_name_t clock_name,unsigned int baudrate)44 constexpr InterruptSafeUartWriterMcuxpresso(uintptr_t base, 45 clock_name_t clock_name, 46 unsigned int baudrate) 47 : base_(base), baudrate_(baudrate), clock_name_(clock_name) {} 48 49 // Initialize uart to known good state. Can be used on UART that was already 50 // used by another driver to enable use in fault handler context. 51 pw::Status Enable(); 52 53 private: 54 pw::Status DoWrite(pw::ConstByteSpan data) override; base()55 USART_Type* base() { return reinterpret_cast<USART_Type*>(base_); } 56 57 const uintptr_t base_; 58 const unsigned int baudrate_; 59 pw::clock_tree::ElementController element_controller_; 60 const clock_name_t clock_name_; 61 }; 62 63 } // namespace pw::stream 64