[FL-2131] IR: continuous signal tx on learn scene (#1002)
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									3922ae93b7
								
							
						
					
					
						commit
						ddd909faa0
					
				| @ -46,6 +46,8 @@ static void dialogs_app_message_callback(DialogExResult result, void* context) { | ||||
|     case DialogExResultCenter: | ||||
|         message_context->result = DialogMessageButtonCenter; | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|     API_LOCK_UNLOCK(message_context->lock); | ||||
| } | ||||
|  | ||||
| @ -6,6 +6,7 @@ struct DialogEx { | ||||
|     View* view; | ||||
|     void* context; | ||||
|     DialogExResultCallback callback; | ||||
|     bool enable_extended_events; | ||||
| }; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -96,8 +97,8 @@ static bool dialog_ex_view_input_callback(InputEvent* event, void* context) { | ||||
|             return true; | ||||
|         }); | ||||
| 
 | ||||
|     // Process key presses only
 | ||||
|     if(event->type == InputTypeShort && dialog_ex->callback) { | ||||
|     if(dialog_ex->callback) { | ||||
|         if(event->type == InputTypeShort) { | ||||
|             if(event->key == InputKeyLeft && left_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExResultLeft, dialog_ex->context); | ||||
|                 consumed = true; | ||||
| @ -110,6 +111,33 @@ static bool dialog_ex_view_input_callback(InputEvent* event, void* context) { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(event->type == InputTypePress && dialog_ex->enable_extended_events) { | ||||
|             if(event->key == InputKeyLeft && left_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExPressLeft, dialog_ex->context); | ||||
|                 consumed = true; | ||||
|             } else if(event->key == InputKeyOk && center_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExPressCenter, dialog_ex->context); | ||||
|                 consumed = true; | ||||
|             } else if(event->key == InputKeyRight && right_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExPressRight, dialog_ex->context); | ||||
|                 consumed = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(event->type == InputTypeRelease && dialog_ex->enable_extended_events) { | ||||
|             if(event->key == InputKeyLeft && left_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExReleaseLeft, dialog_ex->context); | ||||
|                 consumed = true; | ||||
|             } else if(event->key == InputKeyOk && center_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExReleaseCenter, dialog_ex->context); | ||||
|                 consumed = true; | ||||
|             } else if(event->key == InputKeyRight && right_text != NULL) { | ||||
|                 dialog_ex->callback(DialogExReleaseRight, dialog_ex->context); | ||||
|                 consumed = true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
| @ -144,6 +172,7 @@ DialogEx* dialog_ex_alloc() { | ||||
| 
 | ||||
|             return true; | ||||
|         }); | ||||
|     dialog_ex->enable_extended_events = false; | ||||
|     return dialog_ex; | ||||
| } | ||||
| 
 | ||||
| @ -262,3 +291,13 @@ void dialog_ex_reset(DialogEx* dialog_ex) { | ||||
|     dialog_ex->context = NULL; | ||||
|     dialog_ex->callback = NULL; | ||||
| } | ||||
| 
 | ||||
| void dialog_ex_enable_extended_events(DialogEx* dialog_ex) { | ||||
|     furi_assert(dialog_ex); | ||||
|     dialog_ex->enable_extended_events = true; | ||||
| } | ||||
| 
 | ||||
| void dialog_ex_disable_extended_events(DialogEx* dialog_ex) { | ||||
|     furi_assert(dialog_ex); | ||||
|     dialog_ex->enable_extended_events = false; | ||||
| } | ||||
|  | ||||
| @ -19,6 +19,12 @@ typedef enum { | ||||
|     DialogExResultLeft, | ||||
|     DialogExResultCenter, | ||||
|     DialogExResultRight, | ||||
|     DialogExPressLeft, | ||||
|     DialogExPressCenter, | ||||
|     DialogExPressRight, | ||||
|     DialogExReleaseLeft, | ||||
|     DialogExReleaseCenter, | ||||
|     DialogExReleaseRight, | ||||
| } DialogExResult; | ||||
| 
 | ||||
| /** DialogEx result callback type
 | ||||
| @ -145,6 +151,18 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text); | ||||
|  */ | ||||
| void dialog_ex_reset(DialogEx* dialog_ex); | ||||
| 
 | ||||
| /** Enable press/release events
 | ||||
|  * | ||||
|  * @param      dialog_ex  DialogEx instance | ||||
|  */ | ||||
| void dialog_ex_enable_extended_events(DialogEx* dialog_ex); | ||||
| 
 | ||||
| /** Disable press/release events
 | ||||
|  * | ||||
|  * @param      dialog_ex  DialogEx instance | ||||
|  */ | ||||
| void dialog_ex_disable_extended_events(DialogEx* dialog_ex); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -279,3 +279,8 @@ const IrdaAppSignal& IrdaApp::get_received_signal() const { | ||||
| void IrdaApp::set_received_signal(const IrdaAppSignal& signal) { | ||||
|     received_signal = signal; | ||||
| } | ||||
| 
 | ||||
| void IrdaApp::signal_sent_callback(void* context) { | ||||
|     IrdaApp* app = static_cast<IrdaApp*>(context); | ||||
|     app->notify_blink_green(); | ||||
| } | ||||
|  | ||||
| @ -87,6 +87,7 @@ public: | ||||
| 
 | ||||
|     static void text_input_callback(void* context); | ||||
|     static void popup_callback(void* context); | ||||
|     static void signal_sent_callback(void* context); | ||||
| 
 | ||||
|     IrdaApp(); | ||||
|     ~IrdaApp(); | ||||
|  | ||||
| @ -1,8 +1,10 @@ | ||||
| #include "furi.h" | ||||
| #include "gui/modules/button_panel.h" | ||||
| #include <furi.h> | ||||
| #include <gui/modules/button_panel.h> | ||||
| #include <gui/modules/dialog_ex.h> | ||||
| #include <callback-connector.h> | ||||
| 
 | ||||
| #include "irda_app.h" | ||||
| #include "irda/irda_app_event.h" | ||||
| #include <callback-connector.h> | ||||
| 
 | ||||
| IrdaAppViewManager::IrdaAppViewManager() { | ||||
|     event_queue = osMessageQueueNew(10, sizeof(IrdaAppEvent), NULL); | ||||
| @ -113,11 +115,16 @@ void IrdaAppViewManager::receive_event(IrdaAppEvent* event) { | ||||
| 
 | ||||
| void IrdaAppViewManager::send_event(IrdaAppEvent* event) { | ||||
|     uint32_t timeout = 0; | ||||
|     /* Rapid button hammering on Remote Scene causes queue overflow - ignore it,
 | ||||
|     /* Rapid button hammering on signal send scenes causes queue overflow - ignore it,
 | ||||
|      * but try to keep button release event - it switches off IRDA DMA sending. */ | ||||
|     if(event->type == IrdaAppEvent::Type::MenuSelectedRelease) { | ||||
|         timeout = 200; | ||||
|     } | ||||
|     if((event->type == IrdaAppEvent::Type::DialogExSelected) && | ||||
|        (event->payload.dialog_ex_result == DialogExReleaseCenter)) { | ||||
|         timeout = 200; | ||||
|     } | ||||
| 
 | ||||
|     osMessageQueuePut(event_queue, event, 0, timeout); | ||||
|     /* furi_check(result == osOK); */ | ||||
| } | ||||
|  | ||||
| @ -50,6 +50,7 @@ public: | ||||
|     void on_enter(IrdaApp* app) final; | ||||
|     bool on_event(IrdaApp* app, IrdaAppEvent* event) final; | ||||
|     void on_exit(IrdaApp* app) final; | ||||
|     bool button_pressed = false; | ||||
| }; | ||||
| 
 | ||||
| class IrdaAppSceneLearnEnterName : public IrdaAppScene { | ||||
|  | ||||
| @ -57,6 +57,8 @@ bool IrdaAppSceneAskBack::on_event(IrdaApp* app, IrdaAppEvent* event) { | ||||
|             app->switch_to_previous_scene(); | ||||
|             consumed = true; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -70,7 +70,7 @@ bool IrdaAppSceneEditDelete::on_event(IrdaApp* app, IrdaAppEvent* event) { | ||||
|         case DialogExResultCenter: | ||||
|             furi_assert(0); | ||||
|             break; | ||||
|         case DialogExResultRight: | ||||
|         case DialogExResultRight: { | ||||
|             auto remote_manager = app->get_remote_manager(); | ||||
|             bool result = false; | ||||
|             if(app->get_edit_element() == IrdaApp::EditElement::Remote) { | ||||
| @ -88,6 +88,9 @@ bool IrdaAppSceneEditDelete::on_event(IrdaApp* app, IrdaAppEvent* event) { | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return consumed; | ||||
|  | ||||
| @ -1,9 +1,11 @@ | ||||
| #include "../irda_app.h" | ||||
| #include <gui/modules/dialog_ex.h> | ||||
| #include <file_worker_cpp.h> | ||||
| #include "irda.h" | ||||
| #include <memory> | ||||
| #include <dolphin/dolphin.h> | ||||
| 
 | ||||
| #include "../irda_app.h" | ||||
| #include "irda.h" | ||||
| 
 | ||||
| static void dialog_result_callback(DialogExResult result, void* context) { | ||||
|     auto app = static_cast<IrdaApp*>(context); | ||||
|     IrdaAppEvent event; | ||||
| @ -21,6 +23,11 @@ void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) { | ||||
|     DOLPHIN_DEED(DolphinDeedIrLearnSuccess); | ||||
|     app->notify_green_on(); | ||||
| 
 | ||||
|     irda_worker_tx_set_get_signal_callback( | ||||
|         app->get_irda_worker(), irda_worker_tx_get_signal_steady_callback, app); | ||||
|     irda_worker_tx_set_signal_sent_callback( | ||||
|         app->get_irda_worker(), IrdaApp::signal_sent_callback, app); | ||||
| 
 | ||||
|     auto signal = app->get_received_signal(); | ||||
| 
 | ||||
|     if(!signal.is_raw()) { | ||||
| @ -55,6 +62,7 @@ void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) { | ||||
|     dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); | ||||
|     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback); | ||||
|     dialog_ex_set_context(dialog_ex, app); | ||||
|     dialog_ex_enable_extended_events(dialog_ex); | ||||
| 
 | ||||
|     view_manager->switch_to(IrdaAppViewManager::ViewType::DialogEx); | ||||
| } | ||||
| @ -63,36 +71,65 @@ bool IrdaAppSceneLearnSuccess::on_event(IrdaApp* app, IrdaAppEvent* event) { | ||||
|     bool consumed = false; | ||||
|     if(event->type == IrdaAppEvent::Type::Tick) { | ||||
|         /* Send event every tick to suppress any switching off green light */ | ||||
|         if(!button_pressed) { | ||||
|             app->notify_green_on(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(event->type == IrdaAppEvent::Type::DialogExSelected) { | ||||
|         switch(event->payload.dialog_ex_result) { | ||||
|         case DialogExResultLeft: | ||||
|             consumed = true; | ||||
|             if(!button_pressed) { | ||||
|                 app->switch_to_next_scene_without_saving(IrdaApp::Scene::Learn); | ||||
|             break; | ||||
|         case DialogExResultCenter: { | ||||
|             app->notify_sent_just_learnt(); | ||||
|             auto signal = app->get_received_signal(); | ||||
|             signal.transmit(); | ||||
|             break; | ||||
|             } | ||||
|             break; | ||||
|         case DialogExResultRight: { | ||||
|             consumed = true; | ||||
|             FileWorkerCpp file_worker; | ||||
|             if(!button_pressed) { | ||||
|                 if(file_worker.check_errors()) { | ||||
|                     app->switch_to_next_scene(IrdaApp::Scene::LearnEnterName); | ||||
|                 } else { | ||||
|                     app->switch_to_previous_scene(); | ||||
|                 } | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         case DialogExPressCenter: | ||||
|             if(!button_pressed) { | ||||
|                 button_pressed = true; | ||||
|                 app->notify_click_and_green_blink(); | ||||
| 
 | ||||
|                 auto signal = app->get_received_signal(); | ||||
|                 if(signal.is_raw()) { | ||||
|                     irda_worker_set_raw_signal( | ||||
|                         app->get_irda_worker(), | ||||
|                         signal.get_raw_signal().timings, | ||||
|                         signal.get_raw_signal().timings_cnt); | ||||
|                 } else { | ||||
|                     irda_worker_set_decoded_signal(app->get_irda_worker(), &signal.get_message()); | ||||
|                 } | ||||
| 
 | ||||
|                 irda_worker_tx_start(app->get_irda_worker()); | ||||
|             } | ||||
|             break; | ||||
|         case DialogExReleaseCenter: | ||||
|             if(button_pressed) { | ||||
|                 button_pressed = false; | ||||
|                 irda_worker_tx_stop(app->get_irda_worker()); | ||||
|                 app->notify_green_off(); | ||||
|             } | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(event->type == IrdaAppEvent::Type::Back) { | ||||
|         if(!button_pressed) { | ||||
|             app->switch_to_next_scene(IrdaApp::Scene::AskBack); | ||||
|         } | ||||
|         consumed = true; | ||||
|     } | ||||
| 
 | ||||
| @ -104,4 +141,6 @@ void IrdaAppSceneLearnSuccess::on_exit(IrdaApp* app) { | ||||
|     DialogEx* dialog_ex = view_manager->get_dialog_ex(); | ||||
|     dialog_ex_reset(dialog_ex); | ||||
|     app->notify_green_off(); | ||||
|     irda_worker_tx_set_get_signal_callback(app->get_irda_worker(), nullptr, nullptr); | ||||
|     irda_worker_tx_set_signal_sent_callback(app->get_irda_worker(), nullptr, nullptr); | ||||
| } | ||||
|  | ||||
| @ -29,11 +29,6 @@ static void button_menu_callback(void* context, int32_t index, InputType type) { | ||||
|     app->get_view_manager()->send_event(&event); | ||||
| } | ||||
| 
 | ||||
| static void irda_app_message_sent_callback(void* context) { | ||||
|     IrdaApp* app = static_cast<IrdaApp*>(context); | ||||
|     app->notify_blink_green(); | ||||
| } | ||||
| 
 | ||||
| void IrdaAppSceneRemote::on_enter(IrdaApp* app) { | ||||
|     IrdaAppViewManager* view_manager = app->get_view_manager(); | ||||
|     ButtonMenu* button_menu = view_manager->get_button_menu(); | ||||
| @ -44,7 +39,7 @@ void IrdaAppSceneRemote::on_enter(IrdaApp* app) { | ||||
|     irda_worker_tx_set_get_signal_callback( | ||||
|         app->get_irda_worker(), irda_worker_tx_get_signal_steady_callback, app); | ||||
|     irda_worker_tx_set_signal_sent_callback( | ||||
|         app->get_irda_worker(), irda_app_message_sent_callback, app); | ||||
|         app->get_irda_worker(), IrdaApp::signal_sent_callback, app); | ||||
|     buttons_names = remote_manager->get_button_list(); | ||||
| 
 | ||||
|     i = 0; | ||||
|  | ||||
| @ -320,6 +320,7 @@ void irda_worker_rx_enable_blink_on_receiving(IrdaWorker* instance, bool enable) | ||||
| void irda_worker_tx_start(IrdaWorker* instance) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(instance->state == IrdaWorkerStateIdle); | ||||
|     furi_assert(instance->tx.get_signal_callback); | ||||
| 
 | ||||
|     // size have to be greater than api hal irda async tx buffer size
 | ||||
|     xStreamBufferSetTriggerLevel(instance->stream, sizeof(IrdaWorkerTiming)); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Albert Kharisov
						Albert Kharisov