#pragma once // clang-format off /* === MODULE MANIFEST V2 === module_description: 无源蜂鸣器报警模块 / Buzzer alarm module constructor_args: - alarm_delay: 5000 template_args: [] required_hardware: pwm_buzzer depends: [] === END MANIFEST === */ // clang-format on #include "app_framework.hpp" #include "pwm.hpp" class BuzzerAlarm : public LibXR::Application { public: // NOLINTNEXTLINE enum class NoteName { C = 0, Cs, D, Ds, E, F, Fs, G, Gs, A, As, B }; BuzzerAlarm(LibXR::HardwareContainer& hw, LibXR::ApplicationManager& app, uint32_t alarm_delay) : alarm_delay_(alarm_delay), pwm_(hw.template FindOrExit({"pwm_tim12_ch2"})) { app.Register(*this); auto error_callback = LibXR::Assert::Callback::Create( [](bool in_isr, BuzzerAlarm* alarm, const char* file, uint32_t line) { UNUSED(file); UNUSED(line); alarm->PlayNote(NoteName::D, 4, 600); alarm->PlayNote(NoteName::E, 4, 600); alarm->PlayNote(NoteName::G, 4, 600); alarm->PlayNote(NoteName::E, 4, 600); alarm->PlayNote(NoteName::D, 4, 300); alarm->PlayNote(NoteName::E, 4, 150); alarm->PlayNote(NoteName::D, 4, 300); alarm->PlayNote(NoteName::C, 4, 300); alarm->PlayNote(NoteName::A, 3, 900); LibXR::Thread::Sleep(300); alarm->PlayNote(NoteName::D, 4, 600); alarm->PlayNote(NoteName::E, 4, 600); alarm->PlayNote(NoteName::G, 4, 600); alarm->PlayNote(NoteName::E, 4, 600); alarm->PlayNote(NoteName::D, 4, 300); alarm->PlayNote(NoteName::E, 4, 150); alarm->PlayNote(NoteName::D, 4, 300); alarm->PlayNote(NoteName::A, 3, 300); alarm->PlayNote(NoteName::C, 4, 900); if (!in_isr) { LibXR::Thread::Sleep(alarm->alarm_delay_); } }, this); LibXR::Assert::RegisterFatalErrorCallback(error_callback); PlayNote(NoteName::B, 5, 200); PlayNote(NoteName::G, 4, 200); PlayNote(NoteName::B, 5, 400); PlayNote(NoteName::G, 4, 200); PlayNote(NoteName::B, 5, 400); PlayNote(NoteName::G, 4, 200); PlayNote(NoteName::D, 5, 400); PlayNote(NoteName::G, 4, 200); PlayNote(NoteName::C, 5, 200); PlayNote(NoteName::C, 5, 200); PlayNote(NoteName::G, 4, 200); PlayNote(NoteName::B, 5, 200); PlayNote(NoteName::C, 5, 200); } void Play(uint32_t freq, uint32_t duration) { pwm_->SetConfig({freq}); pwm_->Enable(); pwm_->SetDutyCycle(0.5); LibXR::Thread::Sleep(duration); pwm_->Disable(); } void PlayNote(NoteName note, uint32_t octave, uint32_t duration) { int midi_num = static_cast(note) + static_cast((octave + 1) * 12); float freq = 440.0f * std::pow(2.0f, (static_cast(midi_num) - 69.0f) / 12.0f); Play(static_cast(freq), static_cast(duration)); } void OnMonitor() override { } private: uint32_t alarm_delay_; LibXR::PWM* pwm_; };