rm_balance/BuzzerAlarm.hpp
2025-10-23 01:59:27 +08:00

98 lines
3.1 KiB
C++

#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<LibXR::PWM>({"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<int>(note) + static_cast<int>((octave + 1) * 12);
float freq =
440.0f * std::pow(2.0f, (static_cast<float>(midi_num) - 69.0f) / 12.0f);
Play(static_cast<uint32_t>(freq), static_cast<uint32_t>(duration));
}
void OnMonitor() override {
}
private:
uint32_t alarm_delay_;
LibXR::PWM* pwm_;
};