#pypp 0 // Iris: micro-kernel for a capability-based operating system. // boot-programs/buzzer.ccp: Piezo buzzer driver. // Copyright 2009 Bas Wijnen // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "devices.hh" #define ARCH #include "arch.hh" class DevBuzzer: static unsigned const pwm = 4 Kernel::Cap event bool is_beeping public: DevBuzzer (): is_beeping = false tcu_stop_counter (pwm) tcu_select_extalclk (pwm) tcu_select_clk_div64 (pwm) tcu_enable_pwm_output (pwm) void stop (): if !is_beeping: return tcu_stop_counter (pwm) event.invoke () Kernel::free_cap (event) is_beeping = false void beep (unsigned freq, unsigned ms, Kernel::Cap cb): stop () event = cb unsigned full = JZ_EXTAL / 64 / freq tcu_set_full_data (pwm, full) tcu_set_half_data (pwm, full / 2) tcu_set_count (pwm, 0) tcu_start_counter (pwm) Kernel::my_receiver.set_alarm (ms * HZ / 1000) is_beeping = true enum codes: BUZZER = 32 Kernel::Num start (): kdebug ("buzzer started.\n") map_tcu () DevBuzzer buzzer Device dev = Kernel::my_receiver.create_capability (BUZZER) Kernel::my_parent.provide_device (dev.copy ()) Kernel::free_cap (dev) unsigned user (~0) unsigned next_user (0) while true: Kernel::wait () switch Kernel::recv.protected_data.h: case ~0: // Alarm. buzzer.stop () break case 0: switch Kernel::recv.protected_data.l: case BUZZER: // Buzzer device control request. switch Kernel::recv.data[0].l: case Device::CREATE_USER: Kernel::Cap reply = Kernel::get_reply () Keyboard cap = Kernel::my_receiver.create_capability (Kernel::Num (next_user++, BUZZER)) reply.invoke (0, 0, cap.copy ()) Kernel::free_cap (cap) Kernel::free_cap (reply) break case Device::DESTROY_USER: Kernel::recv.reply.invoke () break case Device::UNUSE: buzzer.stop () Kernel::recv.reply.invoke () break case Device::USE: Kernel::Cap reply = Kernel::get_reply () user = Kernel::my_receiver.get_protected (Kernel::recv.arg).l reply.invoke () Kernel::free_cap (reply) break default: kdebug ("invalid buzzer control command: ") kdebug_num (Kernel::recv.data[0].l) kdebug ("\n") break break default: kdebug ("invalid buzzer request\n") break break case BUZZER: // Buzzer device user request. if Kernel::recv.protected_data.l != user: kdebug ("invalid user requesting buzzer\n") Kernel::recv.reply.invoke () break switch Kernel::recv.data[0].l: case Buzzer::BEEP: // Volume is not used by this buzzer. Kernel::Cap arg = Kernel::get_arg () Kernel::Cap reply = Kernel::get_reply () buzzer.beep (Kernel::recv.data[1].l, Kernel::recv.data[1].h, arg) reply.invoke () Kernel::free_cap (reply) break case Buzzer::STOP: buzzer.stop () Kernel::recv.reply.invoke () break default: kdebug ("Buzzer: other\n") break break default: kdebug ("Buzzer: unknown num: ") kdebug_num (Kernel::recv.protected_data.h) kdebug ("\n")