From e73a9f98a1cf3ff2933a11a52506aa738095deb0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 12 Jan 2016 21:49:29 -0800 Subject: [PATCH] Move EventDispatcher code into event_*.hpp. More code redistribution coming shortly... --- firmware/application/Makefile | 1 + firmware/application/event_m0.cpp | 43 +++++++ firmware/application/event_m0.hpp | 200 ++++++++++++++++++++++++++++++ firmware/application/main.cpp | 191 ---------------------------- firmware/baseband/Makefile | 1 + firmware/baseband/event_m4.cpp | 43 +++++++ firmware/baseband/event_m4.hpp | 90 ++++++++++++++ firmware/baseband/main.cpp | 92 -------------- 8 files changed, 378 insertions(+), 283 deletions(-) create mode 100644 firmware/application/event_m0.cpp create mode 100644 firmware/baseband/event_m4.cpp diff --git a/firmware/application/Makefile b/firmware/application/Makefile index ce6da9dce..41c8e7616 100755 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -122,6 +122,7 @@ CPPSRC = main.cpp \ irq_controls.cpp \ irq_rtc.cpp \ event.cpp \ + event_m0.cpp \ message_queue.cpp \ hackrf_hal.cpp \ portapack.cpp \ diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp new file mode 100644 index 000000000..0d8946feb --- /dev/null +++ b/firmware/application/event_m0.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * + * This file is part of PortaPack. + * + * 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 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "event_m0.hpp" + +#include "ch.h" + +#include "lpc43xx_cpp.hpp" +using namespace lpc43xx; + +extern "C" { + +CH_IRQ_HANDLER(M4Core_IRQHandler) { + CH_IRQ_PROLOGUE(); + + chSysLockFromIsr(); + events_flag_isr(EVT_MASK_APPLICATION); + chSysUnlockFromIsr(); + + creg::m4txevent::clear(); + + CH_IRQ_EPILOGUE(); +} + +} diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index f2cb5e41d..890fdcb93 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -24,6 +24,31 @@ #include "event.hpp" +#include "portapack.hpp" +#include "portapack_shared_memory.hpp" + +#include "ui_widget.hpp" +#include "ui_painter.hpp" + +#include "touch.hpp" + +#include "irq_lcd_frame.hpp" +#include "irq_controls.hpp" +#include "irq_rtc.hpp" + +#include "message.hpp" +#include "message_queue.hpp" + +#include "sd_card.hpp" + +#include "ch.h" + +#include "lpc43xx_cpp.hpp" +using namespace lpc43xx; + +#include +#include + constexpr auto EVT_MASK_RTC_TICK = EVENT_MASK(0); constexpr auto EVT_MASK_LCD_FRAME_SYNC = EVENT_MASK(1); constexpr auto EVT_MASK_SWITCHES = EVENT_MASK(3); @@ -31,4 +56,179 @@ constexpr auto EVT_MASK_ENCODER = EVENT_MASK(4); constexpr auto EVT_MASK_TOUCH = EVENT_MASK(5); constexpr auto EVT_MASK_APPLICATION = EVENT_MASK(6); +class EventDispatcher { +public: + EventDispatcher( + ui::Widget* const top_widget, + ui::Painter& painter, + ui::Context& context + ) : top_widget { top_widget }, + painter(painter), + context(context) + { + touch_manager.on_event = [this](const ui::TouchEvent event) { + this->on_touch_event(event); + }; + } + + void run() { + creg::m4txevent::enable(); + + while(is_running) { + const auto events = wait(); + dispatch(events); + } + + creg::m4txevent::disable(); + } + + void request_stop() { + is_running = false; + } + +private: + touch::Manager touch_manager; + ui::Widget* const top_widget; + ui::Painter& painter; + ui::Context& context; + uint32_t encoder_last = 0; + bool is_running = true; + bool sd_card_present = false; + + eventmask_t wait() { + return chEvtWaitAny(ALL_EVENTS); + } + + void dispatch(const eventmask_t events) { + if( events & EVT_MASK_APPLICATION ) { + handle_application_queue(); + } + + if( events & EVT_MASK_RTC_TICK ) { + handle_rtc_tick(); + } + + if( events & EVT_MASK_LCD_FRAME_SYNC ) { + handle_lcd_frame_sync(); + } + + if( events & EVT_MASK_SWITCHES ) { + handle_switches(); + } + + if( events & EVT_MASK_ENCODER ) { + handle_encoder(); + } + + if( events & EVT_MASK_TOUCH ) { + handle_touch(); + } + } + + void handle_application_queue() { + std::array message_buffer; + while(Message* const message = shared_memory.application_queue.pop(message_buffer)) { + context.message_map().send(message); + } + } + + void handle_rtc_tick() { + sd_card::poll_inserted(); + + portapack::temperature_logger.second_tick(); + } + + static ui::Widget* touch_widget(ui::Widget* const w, ui::TouchEvent event) { + if( !w->hidden() ) { + // To achieve reverse depth ordering (last object drawn is + // considered "top"), descend first. + for(const auto child : w->children()) { + const auto touched_widget = touch_widget(child, event); + if( touched_widget ) { + return touched_widget; + } + } + + const auto r = w->screen_rect(); + if( r.contains(event.point) ) { + if( w->on_touch(event) ) { + // This widget responded. Return it up the call stack. + return w; + } + } + } + return nullptr; + } + + ui::Widget* captured_widget { nullptr }; + + void on_touch_event(ui::TouchEvent event) { + /* TODO: Capture widget receiving the Start event, send Move and + * End events to the same widget. + */ + /* Capture Start widget. + * If touch is over Start widget at Move event, then the widget + * should be highlighted. If the touch is not over the Start + * widget at Move event, widget should un-highlight. + * If touch is over Start widget at End event, then the widget + * action should occur. + */ + if( event.type == ui::TouchEvent::Type::Start ) { + captured_widget = touch_widget(this->top_widget, event); + } + + if( captured_widget ) { + captured_widget->on_touch(event); + } + } + + void handle_lcd_frame_sync() { + DisplayFrameSyncMessage message; + context.message_map().send(&message); + painter.paint_widget_tree(top_widget); + } + + void handle_switches() { + const auto switches_state = get_switches_state(); + for(size_t i=0; i(i); + if( !event_bubble_key(event) ) { + context.focus_manager().update(top_widget, event); + } + } + } + } + + void handle_encoder() { + const uint32_t encoder_now = get_encoder_position(); + const int32_t delta = static_cast(encoder_now - encoder_last); + encoder_last = encoder_now; + const auto event = static_cast(delta); + event_bubble_encoder(event); + } + + void handle_touch() { + touch_manager.feed(get_touch_frame()); + } + + bool event_bubble_key(const ui::KeyEvent event) { + auto target = context.focus_manager().focus_widget(); + while( (target != nullptr) && !target->on_key(event) ) { + target = target->parent(); + } + + /* Return true if event was consumed. */ + return (target != nullptr); + } + + void event_bubble_encoder(const ui::EncoderEvent event) { + auto target = context.focus_manager().focus_widget(); + while( (target != nullptr) && !target->on_encoder(event) ) { + target = target->parent(); + } + } +}; + #endif/*__EVENT_M0_H__*/ diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index cdbc1e207..2746beeb7 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -54,197 +54,6 @@ using namespace lpc43xx; #include -extern "C" { - -CH_IRQ_HANDLER(M4Core_IRQHandler) { - CH_IRQ_PROLOGUE(); - - chSysLockFromIsr(); - events_flag_isr(EVT_MASK_APPLICATION); - chSysUnlockFromIsr(); - - creg::m4txevent::clear(); - - CH_IRQ_EPILOGUE(); -} - -} - -class EventDispatcher { -public: - EventDispatcher( - ui::Widget* const top_widget, - ui::Painter& painter, - ui::Context& context - ) : top_widget { top_widget }, - painter(painter), - context(context) - { - touch_manager.on_event = [this](const ui::TouchEvent event) { - this->on_touch_event(event); - }; - } - - void run() { - creg::m4txevent::enable(); - - while(is_running) { - const auto events = wait(); - dispatch(events); - } - - creg::m4txevent::disable(); - } - - void request_stop() { - is_running = false; - } - -private: - touch::Manager touch_manager; - ui::Widget* const top_widget; - ui::Painter& painter; - ui::Context& context; - uint32_t encoder_last = 0; - bool is_running = true; - bool sd_card_present = false; - - eventmask_t wait() { - return chEvtWaitAny(ALL_EVENTS); - } - - void dispatch(const eventmask_t events) { - if( events & EVT_MASK_APPLICATION ) { - handle_application_queue(); - } - - if( events & EVT_MASK_RTC_TICK ) { - handle_rtc_tick(); - } - - if( events & EVT_MASK_LCD_FRAME_SYNC ) { - handle_lcd_frame_sync(); - } - - if( events & EVT_MASK_SWITCHES ) { - handle_switches(); - } - - if( events & EVT_MASK_ENCODER ) { - handle_encoder(); - } - - if( events & EVT_MASK_TOUCH ) { - handle_touch(); - } - } - - void handle_application_queue() { - std::array message_buffer; - while(Message* const message = shared_memory.application_queue.pop(message_buffer)) { - context.message_map().send(message); - } - } - - void handle_rtc_tick() { - sd_card::poll_inserted(); - - portapack::temperature_logger.second_tick(); - } - - static ui::Widget* touch_widget(ui::Widget* const w, ui::TouchEvent event) { - if( !w->hidden() ) { - // To achieve reverse depth ordering (last object drawn is - // considered "top"), descend first. - for(const auto child : w->children()) { - const auto touched_widget = touch_widget(child, event); - if( touched_widget ) { - return touched_widget; - } - } - - const auto r = w->screen_rect(); - if( r.contains(event.point) ) { - if( w->on_touch(event) ) { - // This widget responded. Return it up the call stack. - return w; - } - } - } - return nullptr; - } - - ui::Widget* captured_widget { nullptr }; - - void on_touch_event(ui::TouchEvent event) { - /* TODO: Capture widget receiving the Start event, send Move and - * End events to the same widget. - */ - /* Capture Start widget. - * If touch is over Start widget at Move event, then the widget - * should be highlighted. If the touch is not over the Start - * widget at Move event, widget should un-highlight. - * If touch is over Start widget at End event, then the widget - * action should occur. - */ - if( event.type == ui::TouchEvent::Type::Start ) { - captured_widget = touch_widget(this->top_widget, event); - } - - if( captured_widget ) { - captured_widget->on_touch(event); - } - } - - void handle_lcd_frame_sync() { - DisplayFrameSyncMessage message; - context.message_map().send(&message); - painter.paint_widget_tree(top_widget); - } - - void handle_switches() { - const auto switches_state = get_switches_state(); - for(size_t i=0; i(i); - if( !event_bubble_key(event) ) { - context.focus_manager().update(top_widget, event); - } - } - } - } - - void handle_encoder() { - const uint32_t encoder_now = get_encoder_position(); - const int32_t delta = static_cast(encoder_now - encoder_last); - encoder_last = encoder_now; - const auto event = static_cast(delta); - event_bubble_encoder(event); - } - - void handle_touch() { - touch_manager.feed(get_touch_frame()); - } - - bool event_bubble_key(const ui::KeyEvent event) { - auto target = context.focus_manager().focus_widget(); - while( (target != nullptr) && !target->on_key(event) ) { - target = target->parent(); - } - - /* Return true if event was consumed. */ - return (target != nullptr); - } - - void event_bubble_encoder(const ui::EncoderEvent event) { - auto target = context.focus_manager().focus_widget(); - while( (target != nullptr) && !target->on_encoder(event) ) { - target = target->parent(); - } - } -}; - int main(void) { portapack::init(); diff --git a/firmware/baseband/Makefile b/firmware/baseband/Makefile index 26c974c92..413ed0ded 100755 --- a/firmware/baseband/Makefile +++ b/firmware/baseband/Makefile @@ -125,6 +125,7 @@ CSRC = $(PORTSRC) \ CPPSRC = main.cpp \ message_queue.cpp \ event.cpp \ + event_m4.cpp \ gpdma.cpp \ baseband_dma.cpp \ baseband_sgpio.cpp \ diff --git a/firmware/baseband/event_m4.cpp b/firmware/baseband/event_m4.cpp new file mode 100644 index 000000000..ae72c8426 --- /dev/null +++ b/firmware/baseband/event_m4.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * + * This file is part of PortaPack. + * + * 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 2, 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "event_m4.hpp" + +#include "ch.h" + +#include "lpc43xx_cpp.hpp" +using namespace lpc43xx; + +extern "C" { + +CH_IRQ_HANDLER(MAPP_IRQHandler) { + CH_IRQ_PROLOGUE(); + + chSysLockFromIsr(); + events_flag_isr(EVT_MASK_BASEBAND); + chSysUnlockFromIsr(); + + creg::m0apptxevent::clear(); + + CH_IRQ_EPILOGUE(); +} + +} diff --git a/firmware/baseband/event_m4.hpp b/firmware/baseband/event_m4.hpp index 03277443c..b257c158f 100644 --- a/firmware/baseband/event_m4.hpp +++ b/firmware/baseband/event_m4.hpp @@ -24,7 +24,97 @@ #include "event.hpp" +#include "portapack_shared_memory.hpp" + +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" + +#include "message.hpp" +#include "message_queue.hpp" + +#include "ch.h" + +#include "lpc43xx_cpp.hpp" + +#include + constexpr auto EVT_MASK_BASEBAND = EVENT_MASK(0); constexpr auto EVT_MASK_SPECTRUM = EVENT_MASK(1); +class EventDispatcher { +public: + void run() { + events_initialize(chThdSelf()); + lpc43xx::creg::m0apptxevent::enable(); + + baseband_thread.thread_main = chThdSelf(); + baseband_thread.thread_rssi = rssi_thread.start(NORMALPRIO + 10); + baseband_thread.start(NORMALPRIO + 20); + + while(is_running) { + const auto events = wait(); + dispatch(events); + } + + lpc43xx::creg::m0apptxevent::disable(); + } + + void request_stop() { + is_running = false; + } + +private: + BasebandThread baseband_thread; + RSSIThread rssi_thread; + + bool is_running = true; + + eventmask_t wait() { + return chEvtWaitAny(ALL_EVENTS); + } + + void dispatch(const eventmask_t events) { + if( events & EVT_MASK_BASEBAND ) { + handle_baseband_queue(); + } + + if( events & EVT_MASK_SPECTRUM ) { + handle_spectrum(); + } + } + + void handle_baseband_queue() { + std::array message_buffer; + while(Message* const message = shared_memory.baseband_queue.peek(message_buffer)) { + on_message(message); + shared_memory.baseband_queue.skip(); + } + } + + void on_message(const Message* const message) { + switch(message->id) { + case Message::ID::Shutdown: + on_message_shutdown(*reinterpret_cast(message)); + break; + + default: + on_message_default(message); + break; + } + } + + void on_message_shutdown(const ShutdownMessage&) { + request_stop(); + } + + void on_message_default(const Message* const message) { + baseband_thread.on_message(message); + } + + void handle_spectrum() { + const UpdateSpectrumMessage message; + baseband_thread.on_message(&message); + } +}; + #endif/*__EVENT_M4_H__*/ diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index d74dd148c..d6a895a77 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -117,98 +117,6 @@ static void shutdown() { halt(); } -extern "C" { - -CH_IRQ_HANDLER(MAPP_IRQHandler) { - CH_IRQ_PROLOGUE(); - - chSysLockFromIsr(); - events_flag_isr(EVT_MASK_BASEBAND); - chSysUnlockFromIsr(); - - creg::m0apptxevent::clear(); - - CH_IRQ_EPILOGUE(); -} - -} - -class EventDispatcher { -public: - void run() { - events_initialize(chThdSelf()); - lpc43xx::creg::m0apptxevent::enable(); - - baseband_thread.thread_main = chThdSelf(); - baseband_thread.thread_rssi = rssi_thread.start(NORMALPRIO + 10); - baseband_thread.start(NORMALPRIO + 20); - - while(is_running) { - const auto events = wait(); - dispatch(events); - } - - lpc43xx::creg::m0apptxevent::disable(); - } - - void request_stop() { - is_running = false; - } - -private: - BasebandThread baseband_thread; - RSSIThread rssi_thread; - - bool is_running = true; - - eventmask_t wait() { - return chEvtWaitAny(ALL_EVENTS); - } - - void dispatch(const eventmask_t events) { - if( events & EVT_MASK_BASEBAND ) { - handle_baseband_queue(); - } - - if( events & EVT_MASK_SPECTRUM ) { - handle_spectrum(); - } - } - - void handle_baseband_queue() { - std::array message_buffer; - while(Message* const message = shared_memory.baseband_queue.peek(message_buffer)) { - on_message(message); - shared_memory.baseband_queue.skip(); - } - } - - void on_message(const Message* const message) { - switch(message->id) { - case Message::ID::Shutdown: - on_message_shutdown(*reinterpret_cast(message)); - break; - - default: - on_message_default(message); - break; - } - } - - void on_message_shutdown(const ShutdownMessage&) { - request_stop(); - } - - void on_message_default(const Message* const message) { - baseband_thread.on_message(message); - } - - void handle_spectrum() { - const UpdateSpectrumMessage message; - baseband_thread.on_message(&message); - } -}; - int main(void) { init();