diff --git a/applications/accessor/accessor-app.cpp b/applications/accessor/accessor-app.cpp index a6f8e59f..eb430bc3 100644 --- a/applications/accessor/accessor-app.cpp +++ b/applications/accessor/accessor-app.cpp @@ -8,8 +8,6 @@ void AccessorApp::run(void) { bool consumed; bool exit = false; - notify_init(); - wiegand.begin(); onewire_master.start(); @@ -36,9 +34,14 @@ void AccessorApp::run(void) { AccessorApp::AccessorApp() : onewire_master{&ibutton_gpio} { api_hal_power_insomnia_enter(); + notification = static_cast(furi_record_open("notification")); + notify_init(); + api_hal_power_enable_otg(); } AccessorApp::~AccessorApp() { + api_hal_power_disable_otg(); + furi_record_close("notification"); api_hal_power_insomnia_exit(); } @@ -102,11 +105,6 @@ AccessorApp::Scene AccessorApp::get_previous_scene() { /***************************** NOTIFY *******************************/ void AccessorApp::notify_init() { - // TODO open record - const GpioPin* vibro_record = &vibro_gpio; - hal_gpio_init(vibro_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(vibro_record, false); - GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = PB3_Pin; @@ -118,35 +116,21 @@ void AccessorApp::notify_init() { } void AccessorApp::notify_green_blink() { - api_hal_light_set(LightGreen, 0xFF); - delay(10); - api_hal_light_set(LightGreen, 0x00); -} - -void AccessorApp::notify_green_on() { - api_hal_light_set(LightGreen, 0xFF); -} - -void AccessorApp::notify_green_off() { - api_hal_light_set(LightGreen, 0x00); + notification_message(notification, &sequence_blink_green_10); } void AccessorApp::notify_success() { - api_hal_light_set(LightBacklight, 0xFF); + notification_message(notification, &sequence_success); hal_pwm_set(0.5, 1760 / 2, &htim2, TIM_CHANNEL_2); - notify_green_on(); delay(100); hal_pwm_stop(&htim2, TIM_CHANNEL_2); - notify_green_off(); delay(100); hal_pwm_set(0.5, 1760, &htim2, TIM_CHANNEL_2); - notify_green_on(); delay(100); hal_pwm_stop(&htim2, TIM_CHANNEL_2); - notify_green_off(); } /*************************** TEXT STORE *****************************/ diff --git a/applications/accessor/accessor-app.h b/applications/accessor/accessor-app.h index 7d880ed4..32af88ee 100644 --- a/applications/accessor/accessor-app.h +++ b/applications/accessor/accessor-app.h @@ -9,6 +9,8 @@ #include +#include + class AccessorApp { public: void run(void); @@ -29,8 +31,6 @@ public: void notify_init(); void notify_green_blink(); - void notify_green_on(); - void notify_green_off(); void notify_success(); @@ -55,4 +55,6 @@ private: WIEGAND wiegand; OneWireMaster onewire_master; + + NotificationApp* notification; }; \ No newline at end of file diff --git a/applications/applications.c b/applications/applications.c index 011e923b..d530b86d 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -38,6 +38,7 @@ int32_t passport(void* p); int32_t app_accessor(void* p); int32_t internal_storage_task(void* p); int32_t app_archive(void* p); +int32_t notification_app(void* p); // On system start hooks declaration void nfc_cli_init(); @@ -155,6 +156,10 @@ const FlipperApplication FLIPPER_SERVICES[] = { {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14}, #endif +#ifdef SRV_NOTIFICATION + {.app = notification_app, .name = "notification", .stack_size = 1024, .icon = A_Plugins_14}, +#endif + }; const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); diff --git a/applications/applications.mk b/applications/applications.mk index d009fcf2..03b2b5b3 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -19,6 +19,7 @@ SRV_CLI = 1 SRV_SD_FILESYSTEM = 1 SRV_INTERNAL_STORAGE = 1 SRV_DOLPHIN = 1 +SRV_NOTIFICATION = 1 # Main Apps APP_IRDA = 1 @@ -328,3 +329,8 @@ ifeq ($(SRV_CLI), 1) SRV_GUI = 1 CFLAGS += -DSRV_CLI endif + +SRV_NOTIFICATION ?= 0 +ifeq ($(SRV_NOTIFICATION), 1) +CFLAGS += -DSRV_NOTIFICATION +endif diff --git a/applications/backlight-control/backlight-control.c b/applications/backlight-control/backlight-control.c index a2fdddea..44d91a1a 100644 --- a/applications/backlight-control/backlight-control.c +++ b/applications/backlight-control/backlight-control.c @@ -1,5 +1,6 @@ #include #include +#include #define BACKLIGHT_TIME 30000 #define BACKLIGHT_FLAG_ACTIVITY 0x00000001U @@ -10,18 +11,19 @@ static void event_cb(const void* value, void* ctx) { int32_t backlight_control(void* p) { // open record + NotificationApp* notifications = furi_record_open("notification"); PubSub* event_record = furi_record_open("input_events"); subscribe_pubsub(event_record, event_cb, (void*)osThreadGetId()); - api_hal_light_set(LightBacklight, 0xFF); + notification_internal_message(notifications, &sequence_display_on); while(1) { // wait for event if(osThreadFlagsWait(BACKLIGHT_FLAG_ACTIVITY, osFlagsWaitAny, BACKLIGHT_TIME) == BACKLIGHT_FLAG_ACTIVITY) { - api_hal_light_set(LightBacklight, 0xFF); + notification_internal_message(notifications, &sequence_display_on); } else { - api_hal_light_set(LightBacklight, 0x00); + notification_internal_message(notifications, &sequence_display_off); } } diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 101ff6ee..6df4967b 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -4,6 +4,7 @@ #include #include #include +#include void cli_command_help(Cli* cli, string_t args, void* context) { (void)args; @@ -106,9 +107,13 @@ void cli_command_hw_info(Cli* cli, string_t args, void* context) { void cli_command_vibro(Cli* cli, string_t args, void* context) { if(!string_cmp(args, "0")) { - api_hal_vibro_on(false); + NotificationApp* notification = furi_record_open("notification"); + notification_message_block(notification, &sequence_reset_vibro); + furi_record_close("notification"); } else if(!string_cmp(args, "1")) { - api_hal_vibro_on(true); + NotificationApp* notification = furi_record_open("notification"); + notification_message_block(notification, &sequence_set_vibro_on); + furi_record_close("notification"); } else { printf("Wrong input"); } @@ -116,7 +121,7 @@ void cli_command_vibro(Cli* cli, string_t args, void* context) { void cli_command_led(Cli* cli, string_t args, void* context) { // Get first word as light name - Light light; + NotificationMessage notification_led_message; string_t light_name; string_init(light_name); size_t ws = string_search_char(args, ' '); @@ -131,13 +136,13 @@ void cli_command_led(Cli* cli, string_t args, void* context) { } // Check light name if(!string_cmp(light_name, "r")) { - light = LightRed; + notification_led_message.type = NotificationMessageTypeLedRed; } else if(!string_cmp(light_name, "g")) { - light = LightGreen; + notification_led_message.type = NotificationMessageTypeLedGreen; } else if(!string_cmp(light_name, "b")) { - light = LightBlue; + notification_led_message.type = NotificationMessageTypeLedBlue; } else if(!string_cmp(light_name, "bl")) { - light = LightBacklight; + notification_led_message.type = NotificationMessageTypeLedDisplay; } else { printf("Wrong argument"); string_clear(light_name); @@ -151,7 +156,20 @@ void cli_command_led(Cli* cli, string_t args, void* context) { printf("Wrong argument"); return; } - api_hal_light_set(light, value); + + // Set led value + notification_led_message.data.led.value = value; + + // Form notification sequence + const NotificationSequence notification_sequence = { + ¬ification_led_message, + NULL, + }; + + // Send notification + NotificationApp* notification = furi_record_open("notification"); + notification_internal_message_block(notification, ¬ification_sequence); + furi_record_close("notification"); } void cli_command_gpio_set(Cli* cli, string_t args, void* context) { diff --git a/applications/examples/blink.c b/applications/examples/blink.c index ea6babaf..308b30f0 100644 --- a/applications/examples/blink.c +++ b/applications/examples/blink.c @@ -4,6 +4,10 @@ #include #include +#include + +#define BLINK_COLOR_COUNT 7 + typedef enum { EventTypeTick, EventTypeKey, @@ -14,12 +18,6 @@ typedef struct { InputEvent input; } BlinkEvent; -void rgb_set(bool r, bool g, bool b) { - api_hal_light_set(LightRed, r ? 0xFF : 0x00); - api_hal_light_set(LightGreen, g ? 0xFF : 0x00); - api_hal_light_set(LightBlue, b ? 0xFF : 0x00); -} - void blink_update(void* ctx) { furi_assert(ctx); osMessageQueueId_t event_queue = ctx; @@ -57,16 +55,18 @@ int32_t application_blink(void* p) { Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); - bool blink_color[][3] = { - {1, 0, 0}, - {0, 1, 0}, - {0, 0, 1}, - {1, 1, 0}, - {0, 1, 1}, - {1, 0, 1}, - {1, 1, 1}, - {0, 0, 0}, + NotificationApp* notifications = furi_record_open("notification"); + + const NotificationSequence* colors[BLINK_COLOR_COUNT] = { + &sequence_blink_red_100, + &sequence_blink_green_100, + &sequence_blink_blue_100, + &sequence_blink_yellow_100, + &sequence_blink_cyan_100, + &sequence_blink_magenta_100, + &sequence_blink_white_100, }; + uint8_t state = 0; BlinkEvent event; @@ -74,7 +74,7 @@ int32_t application_blink(void* p) { furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); if(event.type == EventTypeKey) { if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { - rgb_set(0, 0, 0); + furi_record_close("notification"); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); view_port_free(view_port); @@ -84,12 +84,12 @@ int32_t application_blink(void* p) { return 0; } } else { - if(state < sizeof(blink_color) / sizeof(blink_color[0])) { - state++; - } else { + notification_message(notifications, colors[state]); + + state++; + if(state >= BLINK_COLOR_COUNT) { state = 0; } - rgb_set(blink_color[state][0], blink_color[state][1], blink_color[state][2]); } } diff --git a/applications/examples/strobe.c b/applications/examples/strobe.c deleted file mode 100644 index ef95bd23..00000000 --- a/applications/examples/strobe.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include - -static void event_cb(const void* value, void* ctx) { - const InputEvent* event = value; - - uint32_t* delay_time = acquire_mutex(ctx, 0); - if(delay_time == NULL) return; - - if(event->key == InputKeyUp && *delay_time < 1000) { - *delay_time += 5; - } - - if(event->key == InputKeyDown && *delay_time > 10) { - *delay_time -= 5; - } - release_mutex(ctx, delay_time); -} - -void application_strobe(void* p) { - // WAT - osDelay(100); - - uint32_t delay_time_holder = 100; - ValueMutex delay_mutex; - init_mutex(&delay_mutex, &delay_time_holder, sizeof(delay_time_holder)); - - PubSub* event_record = furi_record_open("input_events"); - subscribe_pubsub(event_record, event_cb, &delay_mutex); - - while(1) { - uint32_t delay_time = 100; - read_mutex_block(&delay_mutex, &delay_time, sizeof(delay_time)); - - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); - osDelay(delay_time / 10); - - api_hal_light_set(LightRed, 0xFF); - api_hal_light_set(LightGreen, 0xFF); - api_hal_light_set(LightBlue, 0xFF); - osDelay(delay_time); - } -} \ No newline at end of file diff --git a/applications/examples/vibro.c b/applications/examples/vibro.c index 4edcb275..9c4edf30 100644 --- a/applications/examples/vibro.c +++ b/applications/examples/vibro.c @@ -3,6 +3,7 @@ #include #include +#include typedef struct { InputEvent input; @@ -27,7 +28,6 @@ void vibro_input_callback(InputEvent* input_event, void* ctx) { } int32_t application_vibro(void* p) { - GpioPin* gpio = (GpioPin*)&vibro_gpio; osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(VibroEvent), NULL); // Configure view port @@ -40,15 +40,16 @@ int32_t application_vibro(void* p) { Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); - hal_gpio_init(gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(gpio, false); + NotificationApp* notification = furi_record_open("notification"); + VibroEvent event; while(1) { furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { - hal_gpio_write(gpio, false); - api_hal_light_set(LightGreen, 0); + notification_message(notification, &sequence_reset_vibro); + notification_message(notification, &sequence_reset_green); + furi_record_close("notification"); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); view_port_free(view_port); @@ -58,11 +59,11 @@ int32_t application_vibro(void* p) { } if(event.input.key == InputKeyOk) { if(event.input.type == InputTypePress) { - hal_gpio_write(gpio, true); - api_hal_light_set(LightGreen, 255); + notification_message(notification, &sequence_set_vibro_on); + notification_message(notification, &sequence_set_green_255); } else if(event.input.type == InputTypeRelease) { - hal_gpio_write(gpio, false); - api_hal_light_set(LightGreen, 0); + notification_message(notification, &sequence_reset_vibro); + notification_message(notification, &sequence_reset_green); } } } diff --git a/applications/gpio-tester/gpio-tester.c b/applications/gpio-tester/gpio-tester.c index fa3de140..a61cc0ce 100644 --- a/applications/gpio-tester/gpio-tester.c +++ b/applications/gpio-tester/gpio-tester.c @@ -3,6 +3,7 @@ #include #include +#include typedef struct { const char* name; @@ -81,6 +82,8 @@ int32_t app_gpio_test(void* p) { Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); + NotificationApp* notification = furi_record_open("notification"); + // configure pin for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) { hal_gpio_init( @@ -97,8 +100,8 @@ int32_t app_gpio_test(void* p) { if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) { printf("[gpio-tester] bye!\r\n"); - - api_hal_light_set(LightGreen, 0x00); + notification_message(notification, &sequence_reset_green); + furi_record_close("notification"); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); @@ -124,10 +127,10 @@ int32_t app_gpio_test(void* p) { if(event.value.input.key == InputKeyOk) { if(event.value.input.type == InputTypePress) { hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, true); - api_hal_light_set(LightGreen, 0xFF); + notification_message(notification, &sequence_set_green_255); } else if(event.value.input.type == InputTypeRelease) { hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, false); - api_hal_light_set(LightGreen, 0x00); + notification_message(notification, &sequence_reset_green); } } } diff --git a/applications/ibutton/helpers/key-reader.cpp b/applications/ibutton/helpers/key-reader.cpp index 1b3a9b85..f5885870 100644 --- a/applications/ibutton/helpers/key-reader.cpp +++ b/applications/ibutton/helpers/key-reader.cpp @@ -61,6 +61,7 @@ bool KeyReader::read_key(iButtonKeyType* key_type, uint8_t* data, uint8_t data_s switch(read_mode) { case ReadMode::DALLAS: + __disable_irq(); if(onewire_master->search(data)) { onewire_master->reset_search(); readed = true; @@ -68,6 +69,7 @@ bool KeyReader::read_key(iButtonKeyType* key_type, uint8_t* data, uint8_t data_s } else { onewire_master->reset_search(); } + __enable_irq(); break; case ReadMode::CYFRAL_METAKOM: if(cyfral_decoder.read(data, 2)) { @@ -89,7 +91,7 @@ bool KeyReader::verify_key(iButtonKeyType key_type, const uint8_t* const data, u switch(key_type) { case iButtonKeyType::KeyDallas: switch_to(ReadMode::DALLAS); - + __disable_irq(); if(onewire_master->reset()) { onewire_master->write(DS1990::CMD_READ_ROM); for(uint8_t i = 0; i < data_size; i++) { @@ -101,7 +103,7 @@ bool KeyReader::verify_key(iButtonKeyType key_type, const uint8_t* const data, u result = false; break; } - + __enable_irq(); break; default: diff --git a/applications/ibutton/ibutton-app.cpp b/applications/ibutton/ibutton-app.cpp index c2663d62..5d8e0297 100644 --- a/applications/ibutton/ibutton-app.cpp +++ b/applications/ibutton/ibutton-app.cpp @@ -178,7 +178,6 @@ void iButtonApp::cli_send_event(iButtonApp::CliEvent scene) { } iButtonApp::iButtonApp() { - notify_init(); api_hal_power_insomnia_enter(); cli_event_result = osMessageQueueNew(1, sizeof(iButtonApp::Scene), NULL); @@ -186,6 +185,8 @@ iButtonApp::iButtonApp() { sd_ex_api = static_cast(furi_record_open("sdcard-ex")); fs_api = static_cast(furi_record_open("sdcard")); cli = static_cast(furi_record_open("cli")); + notification = static_cast(furi_record_open("notification")); + auto callback = cbc::obtain_connector(this, &iButtonApp::cli_cmd_callback); cli_add_command(cli, "tm", callback, cli); @@ -194,10 +195,13 @@ iButtonApp::iButtonApp() { } iButtonApp::~iButtonApp() { + cli_delete_command(cli, "tm"); + furi_record_close("sdcard-ex"); furi_record_close("sdcard"); - cli_delete_command(cli, "tm"); furi_record_close("cli"); + furi_record_close("notification"); + osMessageQueueDelete(cli_event_result); for(std::map::iterator it = scenes.begin(); it != scenes.end(); ++it) { @@ -294,73 +298,40 @@ uint8_t iButtonApp::get_file_name_size() { return file_name_size; } -void iButtonApp::notify_init() { - // TODO open record - const GpioPin* vibro_record = &vibro_gpio; - hal_gpio_init(vibro_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(vibro_record, false); -} - void iButtonApp::notify_green_blink() { - notify_green_on(); - delay(10); - notify_green_off(); + notification_message(notification, &sequence_blink_green_10); } void iButtonApp::notify_yellow_blink() { - notify_red_on(); - notify_green_on(); - delay(10); - notify_green_off(); - notify_red_off(); + notification_message(notification, &sequence_blink_yellow_10); } void iButtonApp::notify_red_blink() { - notify_red_on(); - delay(10); - notify_red_off(); -} - -void iButtonApp::notify_green_on() { - api_hal_light_set(LightGreen, 0xFF); -} - -void iButtonApp::notify_green_off() { - api_hal_light_set(LightGreen, 0x00); -} - -void iButtonApp::notify_red_on() { - api_hal_light_set(LightRed, 0xFF); -} - -void iButtonApp::notify_red_off() { - api_hal_light_set(LightRed, 0x00); + notification_message(notification, &sequence_blink_red_10); } void iButtonApp::notify_error() { - notify_vibro_on(); - delay(50); - notify_vibro_off(); - delay(100); - notify_vibro_on(); - delay(50); - notify_vibro_off(); + notification_message(notification, &sequence_error); } void iButtonApp::notify_success() { - notify_vibro_on(); - hal_pwm_set(0.5, 1760, &SPEAKER_TIM, SPEAKER_CH); - delay(50); - hal_pwm_stop(&SPEAKER_TIM, SPEAKER_CH); - notify_vibro_off(); + notification_message(notification, &sequence_success); } -void iButtonApp::notify_vibro_on() { - hal_gpio_write(&vibro_gpio, true); +void iButtonApp::notify_green_on() { + notification_message_block(notification, &sequence_set_green_255); } -void iButtonApp::notify_vibro_off() { - hal_gpio_write(&vibro_gpio, false); +void iButtonApp::notify_green_off() { + notification_message(notification, &sequence_reset_green); +} + +void iButtonApp::notify_red_on() { + notification_message_block(notification, &sequence_set_red_255); +} + +void iButtonApp::notify_red_off() { + notification_message(notification, &sequence_reset_red); } void iButtonApp::set_text_store(const char* text...) { diff --git a/applications/ibutton/ibutton-app.h b/applications/ibutton/ibutton-app.h index a32d4abd..48db20f8 100644 --- a/applications/ibutton/ibutton-app.h +++ b/applications/ibutton/ibutton-app.h @@ -36,6 +36,8 @@ #include "maxim_crc.h" #include "ibutton-key.h" +#include + class iButtonApp { public: void run(void); @@ -92,17 +94,13 @@ public: void notify_yellow_blink(); void notify_red_blink(); + void notify_error(); + void notify_success(); void notify_green_on(); void notify_green_off(); void notify_red_on(); void notify_red_off(); - void notify_error(); - void notify_success(); - - void notify_vibro_on(); - void notify_vibro_off(); - void set_text_store(const char* text...); char* get_text_store(); uint8_t get_text_store_size(); @@ -160,7 +158,8 @@ private: static const uint8_t text_store_size = 128; char text_store[text_store_size + 1]; - void notify_init(); + NotificationApp* notification; + bool read_hex_byte(string_t arg, uint8_t* byte); void print_key_data(void); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton-scene-read-crc-error.cpp b/applications/ibutton/scene/ibutton-scene-read-crc-error.cpp index 00d03845..c86ae32a 100644 --- a/applications/ibutton/scene/ibutton-scene-read-crc-error.cpp +++ b/applications/ibutton/scene/ibutton-scene-read-crc-error.cpp @@ -33,6 +33,7 @@ void iButtonSceneReadCRCError::on_enter(iButtonApp* app) { view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); app->notify_error(); + app->notify_red_on(); } bool iButtonSceneReadCRCError::on_event(iButtonApp* app, iButtonEvent* event) { @@ -62,6 +63,8 @@ void iButtonSceneReadCRCError::on_exit(iButtonApp* app) { dialog_ex_set_left_button_text(dialog_ex, NULL); dialog_ex_set_result_callback(dialog_ex, NULL); dialog_ex_set_context(dialog_ex, NULL); + + app->notify_red_off(); } void iButtonSceneReadCRCError::dialog_ex_callback(DialogExResult result, void* context) { diff --git a/applications/ibutton/scene/ibutton-scene-read-not-key-error.cpp b/applications/ibutton/scene/ibutton-scene-read-not-key-error.cpp index 8cd3cd00..b0cea3e7 100644 --- a/applications/ibutton/scene/ibutton-scene-read-not-key-error.cpp +++ b/applications/ibutton/scene/ibutton-scene-read-not-key-error.cpp @@ -33,6 +33,7 @@ void iButtonSceneReadNotKeyError::on_enter(iButtonApp* app) { view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); app->notify_error(); + app->notify_red_on(); } bool iButtonSceneReadNotKeyError::on_event(iButtonApp* app, iButtonEvent* event) { @@ -62,6 +63,8 @@ void iButtonSceneReadNotKeyError::on_exit(iButtonApp* app) { dialog_ex_set_left_button_text(dialog_ex, NULL); dialog_ex_set_result_callback(dialog_ex, NULL); dialog_ex_set_context(dialog_ex, NULL); + + app->notify_red_off(); } void iButtonSceneReadNotKeyError::dialog_ex_callback(DialogExResult result, void* context) { diff --git a/applications/ibutton/scene/ibutton-scene-read-success.cpp b/applications/ibutton/scene/ibutton-scene-read-success.cpp index 28b38e61..5e037a96 100644 --- a/applications/ibutton/scene/ibutton-scene-read-success.cpp +++ b/applications/ibutton/scene/ibutton-scene-read-success.cpp @@ -42,8 +42,9 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { dialog_ex_set_context(dialog_ex, app); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); - app->notify_green_on(); + app->notify_success(); + app->notify_green_on(); } bool iButtonSceneReadSuccess::on_event(iButtonApp* app, iButtonEvent* event) { @@ -74,6 +75,7 @@ void iButtonSceneReadSuccess::on_exit(iButtonApp* app) { dialog_ex_set_result_callback(dialog_ex, NULL); dialog_ex_set_context(dialog_ex, NULL); dialog_ex_set_icon(dialog_ex, -1, -1, I_ButtonCenter_7x7); + app->notify_green_off(); } diff --git a/applications/ibutton/scene/ibutton-scene-write-success.cpp b/applications/ibutton/scene/ibutton-scene-write-success.cpp index 2c5e77ee..f66181a4 100644 --- a/applications/ibutton/scene/ibutton-scene-write-success.cpp +++ b/applications/ibutton/scene/ibutton-scene-write-success.cpp @@ -19,8 +19,9 @@ void iButtonSceneWriteSuccess::on_enter(iButtonApp* app) { popup_enable_timeout(popup); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - app->notify_green_on(); + app->notify_success(); + app->notify_green_on(); } bool iButtonSceneWriteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { @@ -44,7 +45,6 @@ void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); - app->notify_green_off(); } void iButtonSceneWriteSuccess::popup_callback(void* context) { @@ -52,4 +52,5 @@ void iButtonSceneWriteSuccess::popup_callback(void* context) { iButtonEvent event; event.type = iButtonEvent::Type::EventTypeBack; app->get_view_manager()->send_event(&event); + app->notify_green_off(); } \ No newline at end of file diff --git a/applications/irda/irda_app.c b/applications/irda/irda_app.c index 896cb7aa..d5aa03a5 100644 --- a/applications/irda/irda_app.c +++ b/applications/irda/irda_app.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "irda.h" @@ -284,7 +285,8 @@ void irda_rx_callback(void* ctx, bool level, uint32_t duration) { if(message) { event.value.rx = *message; - furi_assert(osOK == osMessageQueuePut(isr_context->event_queue, &event, 0, 0)); + osStatus_t result = osMessageQueuePut(isr_context->event_queue, &event, 0, 0); + furi_assert(osOK == result); } } @@ -305,6 +307,8 @@ int32_t irda(void* p) { irda_app.cli_ir_rx_queue = osMessageQueueNew(1, sizeof(IrDAPacket), NULL); irda_app.cli_cmd_is_active = false; + NotificationApp* notification = furi_record_open("notification"); + for(uint8_t i = 0; i < IRDA_PACKET_COUNT; i++) { init_packet(&_state, i, 0, 0, 0); } @@ -367,6 +371,7 @@ int32_t irda(void* p) { cli_delete_command(irda_app.cli, "ir_rx"); cli_delete_command(irda_app.cli, "ir_tx"); furi_record_close("cli"); + furi_record_close("notification"); api_hal_irda_rx_irq_deinit(); irda_free_decoder(isr_context.handler); @@ -394,9 +399,7 @@ int32_t irda(void* p) { view_port_update(view_port); } else if(event.type == EventTypeRX) { - api_hal_light_set(LightRed, 0xFF); - delay(60); - api_hal_light_set(LightRed, 0xFF); + notification_message(notification, &sequence_blink_red_10); // save only if we in packet mode State* state = (State*)acquire_mutex_block(&state_mutex); @@ -422,8 +425,7 @@ int32_t irda(void* p) { view_port_update(view_port); // blink anyway - api_hal_light_set(LightGreen, 0xFF); - api_hal_light_set(LightGreen, 0x00); + notification_message(notification, &sequence_blink_green_10); } } else { diff --git a/applications/irda_monitor/irda_monitor.c b/applications/irda_monitor/irda_monitor.c index dd6c9328..651f6368 100644 --- a/applications/irda_monitor/irda_monitor.c +++ b/applications/irda_monitor/irda_monitor.c @@ -2,6 +2,7 @@ #include #include #include +#include #define IRDA_TIMINGS_SIZE 2000 @@ -30,6 +31,7 @@ int32_t irda_monitor_app(void* p) { static uint32_t counter = 0; IrdaDelaysArray* delays = furi_alloc(sizeof(IrdaDelaysArray)); + NotificationApp* notification = furi_record_open("notification"); api_hal_irda_rx_irq_init(); api_hal_irda_rx_irq_set_callback(irda_rx_callback, delays); @@ -38,13 +40,8 @@ int32_t irda_monitor_app(void* p) { delay(20); if(counter != delays->timing_cnt) { - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0xFF); - delay(20); - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); + notification_message(notification, &sequence_blink_blue_100); + counter = delays->timing_cnt; } diff --git a/applications/lf-rfid/lf-rfid-app.cpp b/applications/lf-rfid/lf-rfid-app.cpp index a9f5c7b2..38f5d12e 100644 --- a/applications/lf-rfid/lf-rfid-app.cpp +++ b/applications/lf-rfid/lf-rfid-app.cpp @@ -27,6 +27,7 @@ void LfrfidApp::run(void) { LfrfidApp::LfrfidApp() { api_hal_power_insomnia_enter(); + notification = static_cast(furi_record_open("notification")); } LfrfidApp::~LfrfidApp() { @@ -35,6 +36,8 @@ LfrfidApp::~LfrfidApp() { scenes.erase(it); } + furi_record_close("notification"); + api_hal_power_insomnia_exit(); } @@ -97,25 +100,12 @@ LfrfidApp::Scene LfrfidApp::get_previous_scene() { /***************************** NOTIFY *******************************/ -void LfrfidApp::notify_init() { - // TODO open record - const GpioPin* vibro_record = &vibro_gpio; - hal_gpio_init(vibro_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(vibro_record, false); -} - void LfrfidApp::notify_green_blink() { - api_hal_light_set(LightGreen, 0xFF); - delay(10); - api_hal_light_set(LightGreen, 0x00); + notification_message(notification, &sequence_blink_green_10); } -void LfrfidApp::notify_green_on() { - api_hal_light_set(LightGreen, 0xFF); -} - -void LfrfidApp::notify_green_off() { - api_hal_light_set(LightGreen, 0x00); +void LfrfidApp::notify_success() { + notification_message(notification, &sequence_success); } /*************************** TEXT STORE *****************************/ diff --git a/applications/lf-rfid/lf-rfid-app.h b/applications/lf-rfid/lf-rfid-app.h index 1bd7c677..00ff29eb 100644 --- a/applications/lf-rfid/lf-rfid-app.h +++ b/applications/lf-rfid/lf-rfid-app.h @@ -15,6 +15,8 @@ #include "helpers/rfid-reader.h" #include "helpers/rfid-timer-emulator.h" +#include + class LfrfidApp { public: void run(void); @@ -40,10 +42,8 @@ public: bool switch_to_previous_scene(uint8_t count = 1); Scene get_previous_scene(); - void notify_init(); void notify_green_blink(); - void notify_green_on(); - void notify_green_off(); + void notify_success(); char* get_text_store(); uint8_t get_text_store_size(); @@ -72,6 +72,7 @@ private: static const uint8_t text_store_size = 128; char text_store[text_store_size + 1]; + NotificationApp* notification; RfidReader reader; RfidTimerEmulator emulator; RfidWriter writer; diff --git a/applications/lf-rfid/scene/lf-rfid-scene-read-normal.cpp b/applications/lf-rfid/scene/lf-rfid-scene-read-normal.cpp index ca080627..f1c9f020 100644 --- a/applications/lf-rfid/scene/lf-rfid-scene-read-normal.cpp +++ b/applications/lf-rfid/scene/lf-rfid-scene-read-normal.cpp @@ -25,13 +25,13 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { LfrfidKeyType type; if(app->get_reader()->read(&type, data, data_size)) { - app->notify_green_blink(); - if(memcmp(last_data, data, data_size) == 0) { success_reads++; + app->notify_green_blink(); } else { success_reads = 1; memcpy(last_data, data, data_size); + app->notify_success(); } switch(type) { diff --git a/applications/lf-rfid/scene/lf-rfid-scene-write.cpp b/applications/lf-rfid/scene/lf-rfid-scene-write.cpp index 48de9154..9692d589 100644 --- a/applications/lf-rfid/scene/lf-rfid-scene-write.cpp +++ b/applications/lf-rfid/scene/lf-rfid-scene-write.cpp @@ -31,7 +31,7 @@ bool LfrfidSceneWrite::on_event(LfrfidApp* app, LfrfidEvent* event) { app->get_writer()->start(); app->get_writer()->write_em(em_data); app->get_writer()->stop(); - delay(100); + delay(200); app->get_reader()->start(RfidReader::Type::Normal); } else { uint8_t data[LFRFID_KEY_SIZE]; diff --git a/applications/notification/notification-app-api.c b/applications/notification/notification-app-api.c new file mode 100644 index 00000000..5905d30a --- /dev/null +++ b/applications/notification/notification-app-api.c @@ -0,0 +1,37 @@ +#include +#include +#include "notification.h" +#include "notification-messages.h" +#include "notification-app.h" + +void notification_message(NotificationApp* app, const NotificationSequence* sequence) { + NotificationAppMessage m = { + .type = NotificationLayerMessage, .sequence = sequence, .back_event = NULL}; + furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); +}; + +void notification_internal_message(NotificationApp* app, const NotificationSequence* sequence) { + NotificationAppMessage m = { + .type = InternalLayerMessage, .sequence = sequence, .back_event = NULL}; + furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); +}; + +void notification_message_block(NotificationApp* app, const NotificationSequence* sequence) { + NotificationAppMessage m = { + .type = NotificationLayerMessage, + .sequence = sequence, + .back_event = osEventFlagsNew(NULL)}; + furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); + osEventFlagsWait(m.back_event, NOTIFICATION_EVENT_COMPLETE, osFlagsWaitAny, osWaitForever); + osEventFlagsDelete(m.back_event); +}; + +void notification_internal_message_block( + NotificationApp* app, + const NotificationSequence* sequence) { + NotificationAppMessage m = { + .type = InternalLayerMessage, .sequence = sequence, .back_event = osEventFlagsNew(NULL)}; + furi_check(osMessageQueuePut(app->queue, &m, 0, osWaitForever) == osOK); + osEventFlagsWait(m.back_event, NOTIFICATION_EVENT_COMPLETE, osFlagsWaitAny, osWaitForever); + osEventFlagsDelete(m.back_event); +}; \ No newline at end of file diff --git a/applications/notification/notification-app.c b/applications/notification/notification-app.c new file mode 100644 index 00000000..a4a24e99 --- /dev/null +++ b/applications/notification/notification-app.c @@ -0,0 +1,371 @@ +#include +#include +#include "notification.h" +#include "notification-messages.h" +#include "notification-app.h" + +static const uint8_t minimal_delay = 100; +static const uint8_t led_off_values[NOTIFICATION_LED_COUNT] = {0x00, 0x00, 0x00}; + +static const uint8_t reset_red_mask = 1 << 0; +static const uint8_t reset_green_mask = 1 << 1; +static const uint8_t reset_blue_mask = 1 << 2; +static const uint8_t reset_vibro_mask = 1 << 3; +static const uint8_t reset_sound_mask = 1 << 4; +static const uint8_t reset_display_mask = 1 << 5; + +void notification_vibro_on(); +void notification_vibro_off(); +void notification_sound_on(float pwm, float freq); +void notification_sound_off(); + +uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value); +uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value); +uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app); + +// internal layer +void notification_apply_internal_led_layer(NotificationLedLayer* layer, uint8_t layer_value) { + furi_assert(layer); + furi_assert(layer->index < LayerMAX); + + // set value + layer->value[LayerInternal] = layer_value; + + // apply if current layer is internal + if(layer->index == LayerInternal) { + api_hal_light_set(layer->light, layer->value[LayerInternal]); + } +} + +bool notification_is_any_led_layer_internal_and_not_empty(NotificationApp* app) { + bool result = false; + if((app->led[0].index == LayerInternal) || (app->led[1].index == LayerInternal) || + (app->led[2].index == LayerInternal)) { + if((app->led[0].value[LayerInternal] != 0x00) || + (app->led[1].value[LayerInternal] != 0x00) || + (app->led[2].value[LayerInternal] != 0x00)) { + result = true; + } + } + + return result; +} + +// notification layer +void notification_apply_notification_led_layer( + NotificationLedLayer* layer, + const uint8_t layer_value) { + furi_assert(layer); + furi_assert(layer->index < LayerMAX); + + // set value + layer->index = LayerNotification; + // set layer + layer->value[LayerNotification] = layer_value; + // apply + api_hal_light_set(layer->light, layer->value[LayerNotification]); +} + +void notification_reset_notification_led_layer(NotificationLedLayer* layer) { + furi_assert(layer); + furi_assert(layer->index < LayerMAX); + + // set value + layer->value[LayerNotification] = 0; + // set layer + layer->index = LayerInternal; + + // apply + api_hal_light_set(layer->light, layer->value[LayerInternal]); +} + +void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) { + if(reset_mask & reset_red_mask) { + notification_reset_notification_led_layer(&app->led[0]); + } + if(reset_mask & reset_green_mask) { + notification_reset_notification_led_layer(&app->led[1]); + } + if(reset_mask & reset_blue_mask) { + notification_reset_notification_led_layer(&app->led[2]); + } + if(reset_mask & reset_vibro_mask) { + notification_vibro_off(); + } + if(reset_mask & reset_sound_mask) { + notification_sound_off(); + } + if(reset_mask & reset_display_mask) { + osTimerStart(app->display_timer, notification_settings_display_off_delay_ticks(app)); + } +} + +static void notification_apply_notification_leds(NotificationApp* app, const uint8_t* values) { + for(uint8_t i = 0; i < NOTIFICATION_LED_COUNT; i++) { + notification_apply_notification_led_layer( + &app->led[i], notification_settings_get_display_brightness(app, values[i])); + } +} + +// settings +uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value) { + return (value * app->settings.display_brightness); +} + +uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value) { + return (value * app->settings.led_brightness); +} + +uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) { + return ((float)(app->settings.display_off_delay_ms) / (1000.0f / osKernelGetTickFreq())); +} + +// generics +void notification_vibro_on() { + api_hal_vibro_on(true); +} + +void notification_vibro_off() { + api_hal_vibro_on(false); +} + +void notification_sound_on(float pwm, float freq) { + hal_pwm_set(pwm, freq, &SPEAKER_TIM, SPEAKER_CH); +} + +void notification_sound_off() { + hal_pwm_stop(&SPEAKER_TIM, SPEAKER_CH); +} + +// display timer +static void notification_display_timer(void* ctx) { + furi_assert(ctx); + NotificationApp* app = ctx; + notification_message(app, &sequence_display_off); +} + +// message processing +void notification_process_notification_message( + NotificationApp* app, + NotificationAppMessage* message) { + uint32_t notification_message_index = 0; + const NotificationMessage* notification_message; + notification_message = (*message->sequence)[notification_message_index]; + + bool led_active = false; + uint8_t led_values[NOTIFICATION_LED_COUNT] = {0x00, 0x00, 0x00}; + bool reset_notifications = true; + + uint8_t reset_mask = 0; + + while(notification_message != NULL) { + switch(notification_message->type) { + case NotificationMessageTypeLedDisplay: + // if on - switch on and start timer + // if off - switch off and stop timer + // on timer - switch off + if(notification_message->data.led.value > 0x00) { + notification_apply_notification_led_layer( + &app->display, + notification_settings_get_display_brightness( + app, notification_message->data.led.value)); + } else { + notification_reset_notification_led_layer(&app->display); + if(osTimerIsRunning(app->display_timer)) { + osTimerStop(app->display_timer); + } + } + reset_mask |= reset_display_mask; + break; + case NotificationMessageTypeLedRed: + // store and send on delay or after seq + led_active = true; + led_values[0] = notification_message->data.led.value; + reset_mask |= reset_red_mask; + break; + case NotificationMessageTypeLedGreen: + // store and send on delay or after seq + led_active = true; + led_values[1] = notification_message->data.led.value; + reset_mask |= reset_green_mask; + break; + case NotificationMessageTypeLedBlue: + // store and send on delay or after seq + led_active = true; + led_values[2] = notification_message->data.led.value; + reset_mask |= reset_blue_mask; + break; + case NotificationMessageTypeVibro: + if(notification_message->data.vibro.on) { + notification_vibro_on(); + } else { + notification_vibro_off(); + } + reset_mask |= reset_vibro_mask; + break; + case NotificationMessageTypeSoundOn: + notification_sound_on( + notification_message->data.sound.pwm, notification_message->data.sound.frequency); + reset_mask |= reset_sound_mask; + break; + case NotificationMessageTypeSoundOff: + notification_sound_off(); + reset_mask |= reset_sound_mask; + break; + case NotificationMessageTypeDelay: + if(led_active) { + if(notification_is_any_led_layer_internal_and_not_empty(app)) { + notification_apply_notification_leds(app, led_off_values); + delay(minimal_delay); + } + + led_active = false; + + notification_apply_notification_leds(app, led_values); + reset_mask |= reset_red_mask; + reset_mask |= reset_green_mask; + reset_mask |= reset_blue_mask; + } + + delay(notification_message->data.delay.length); + break; + case NotificationMessageTypeDoNotReset: + reset_notifications = false; + break; + } + notification_message_index++; + notification_message = (*message->sequence)[notification_message_index]; + }; + + // send and do minimal delay + if(led_active) { + bool need_minimal_delay = false; + if(notification_is_any_led_layer_internal_and_not_empty(app)) { + need_minimal_delay = true; + } + + led_active = false; + notification_apply_notification_leds(app, led_values); + reset_mask |= reset_red_mask; + reset_mask |= reset_green_mask; + reset_mask |= reset_blue_mask; + + if(need_minimal_delay) { + notification_apply_notification_leds(app, led_off_values); + delay(minimal_delay); + } + } + + if(reset_notifications) { + notification_reset_notification_layer(app, reset_mask); + } + + if(message->back_event != NULL) { + osEventFlagsSet(message->back_event, NOTIFICATION_EVENT_COMPLETE); + } +} + +void notification_process_internal_message(NotificationApp* app, NotificationAppMessage* message) { + uint32_t notification_message_index = 0; + const NotificationMessage* notification_message; + notification_message = (*message->sequence)[notification_message_index]; + + while(notification_message != NULL) { + switch(notification_message->type) { + case NotificationMessageTypeLedDisplay: + notification_apply_internal_led_layer( + &app->display, + notification_settings_get_display_brightness( + app, notification_message->data.led.value)); + break; + case NotificationMessageTypeLedRed: + notification_apply_internal_led_layer( + &app->led[0], + notification_settings_get_rgb_led_brightness( + app, notification_message->data.led.value)); + break; + case NotificationMessageTypeLedGreen: + notification_apply_internal_led_layer( + &app->led[1], + notification_settings_get_rgb_led_brightness( + app, notification_message->data.led.value)); + break; + case NotificationMessageTypeLedBlue: + notification_apply_internal_led_layer( + &app->led[2], + notification_settings_get_rgb_led_brightness( + app, notification_message->data.led.value)); + break; + default: + break; + } + notification_message_index++; + notification_message = (*message->sequence)[notification_message_index]; + } + + if(message->back_event != NULL) { + osEventFlagsSet(message->back_event, NOTIFICATION_EVENT_COMPLETE); + } +} + +// App alloc +static NotificationApp* notification_app_alloc() { + NotificationApp* app = furi_alloc(sizeof(NotificationApp)); + app->queue = osMessageQueueNew(8, sizeof(NotificationAppMessage), NULL); + app->display_timer = osTimerNew(notification_display_timer, osTimerOnce, app, NULL); + + app->settings.display_brightness = 1.0f; + app->settings.led_brightness = 1.0f; + app->settings.display_off_delay_ms = 30000; + + app->display.value[LayerInternal] = 0x00; + app->display.value[LayerNotification] = 0x00; + app->display.index = LayerInternal; + app->display.light = LightBacklight; + + app->led[0].value[LayerInternal] = 0x00; + app->led[0].value[LayerNotification] = 0x00; + app->led[0].index = LayerInternal; + app->led[0].light = LightRed; + + app->led[1].value[LayerInternal] = 0x00; + app->led[1].value[LayerNotification] = 0x00; + app->led[1].index = LayerInternal; + app->led[1].light = LightGreen; + + app->led[2].value[LayerInternal] = 0x00; + app->led[2].value[LayerNotification] = 0x00; + app->led[2].index = LayerInternal; + app->led[2].light = LightBlue; + + return app; +}; + +// App +int32_t notification_app(void* p) { + NotificationApp* app = notification_app_alloc(); + + notification_vibro_off(); + notification_sound_off(); + notification_apply_internal_led_layer(&app->display, 0x00); + notification_apply_internal_led_layer(&app->led[0], 0x00); + notification_apply_internal_led_layer(&app->led[1], 0x00); + notification_apply_internal_led_layer(&app->led[2], 0x00); + + furi_record_create("notification", app); + + NotificationAppMessage message; + while(1) { + furi_check(osMessageQueueGet(app->queue, &message, NULL, osWaitForever) == osOK); + + switch(message.type) { + case NotificationLayerMessage: + notification_process_notification_message(app, &message); + break; + case InternalLayerMessage: + notification_process_internal_message(app, &message); + } + } + + return 0; +}; \ No newline at end of file diff --git a/applications/notification/notification-app.h b/applications/notification/notification-app.h new file mode 100644 index 00000000..b50ad036 --- /dev/null +++ b/applications/notification/notification-app.h @@ -0,0 +1,46 @@ +#include +#include +#include "notification.h" +#include "notification-messages.h" + +#define NOTIFICATION_LED_COUNT 3 +#define NOTIFICATION_EVENT_COMPLETE 0x00000001U + +typedef enum { + NotificationLayerMessage, + InternalLayerMessage, +} NotificationAppMessageType; + +typedef struct { + const NotificationSequence* sequence; + NotificationAppMessageType type; + osEventFlagsId_t back_event; +} NotificationAppMessage; + +typedef enum { + LayerInternal = 0, + LayerNotification = 1, + LayerMAX = 2, +} NotificationLedLayerIndex; + +typedef struct { + uint8_t value[LayerMAX]; + NotificationLedLayerIndex index; + Light light; +} NotificationLedLayer; + +typedef struct { + float display_brightness; + float led_brightness; + uint32_t display_off_delay_ms; +} NotificationSettings; + +struct NotificationApp { + osMessageQueueId_t queue; + osTimerId_t display_timer; + + NotificationLedLayer display; + NotificationLedLayer led[NOTIFICATION_LED_COUNT]; + + NotificationSettings settings; +}; \ No newline at end of file diff --git a/applications/notification/notification-messages-notes.c b/applications/notification/notification-messages-notes.c new file mode 100644 index 00000000..5d0a0350 --- /dev/null +++ b/applications/notification/notification-messages-notes.c @@ -0,0 +1,568 @@ +#include "notification.h" + +/* +Python script for note messages generation + +# coding: utf-8 +# Python script for note messages generation +from typing import List + +note_names: List = ['c', 'cs', 'd', 'ds', 'e', 'f', 'fs', 'g', 'gs', 'a', 'as', 'b'] +base_note: float = 16.3515979 +cf: float = 2 ** (1.0 / 12) + +note: float = base_note +for octave in range(9): + for name in note_names: + print(f"const NotificationMessage message_note_{name}{octave}" + " = {\n" + "\t.type = NotificationMessageTypeSoundOn,\n" + f"\t.data.sound.frequency = {round(note, 2)}f,\n" + "\t.data.sound.pwm = 0.5f,\n" + "};") + note = note * cf + +for octave in range(9): + for name in note_names: + print(f"extern const NotificationMessage message_note_{name}{octave};") +*/ + +const NotificationMessage message_note_c0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 16.35f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 17.32f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 18.35f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 19.45f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 20.6f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 21.83f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 23.12f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 24.5f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 25.96f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 27.5f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 29.14f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b0 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 30.87f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 32.7f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 34.65f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 36.71f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 38.89f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 41.2f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 43.65f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 46.25f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 49.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 51.91f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 55.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 58.27f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b1 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 61.74f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 65.41f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 69.3f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 73.42f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 77.78f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 82.41f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 87.31f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 92.5f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 98.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 103.83f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 110.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 116.54f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b2 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 123.47f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 130.81f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 138.59f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 146.83f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 155.56f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 164.81f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 174.61f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 185.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 196.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 207.65f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 220.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 233.08f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b3 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 246.94f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 261.63f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 277.18f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 293.66f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 311.13f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 329.63f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 349.23f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 369.99f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 392.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 415.3f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 440.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 466.16f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b4 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 493.88f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 523.25f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 554.37f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 587.33f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 622.25f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 659.26f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 698.46f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 739.99f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 783.99f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 830.61f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 880.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 932.33f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b5 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 987.77f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1046.5f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1108.73f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1174.66f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1244.51f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1318.51f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1396.91f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1479.98f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1567.98f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1661.22f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1760.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1864.66f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b6 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 1975.53f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2093.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2217.46f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2349.32f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2489.02f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2637.02f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2793.83f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 2959.96f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 3135.96f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 3322.44f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 3520.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 3729.31f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b7 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 3951.07f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_c8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 4186.01f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_cs8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 4434.92f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_d8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 4698.64f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_ds8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 4978.03f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_e8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 5274.04f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_f8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 5587.65f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_fs8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 5919.91f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_g8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 6271.93f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_gs8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 6644.88f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_a8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 7040.0f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_as8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 7458.62f, + .data.sound.pwm = 0.5f, +}; +const NotificationMessage message_note_b8 = { + .type = NotificationMessageTypeSoundOn, + .data.sound.frequency = 7902.13f, + .data.sound.pwm = 0.5f, +}; \ No newline at end of file diff --git a/applications/notification/notification-messages-notes.h b/applications/notification/notification-messages-notes.h new file mode 100644 index 00000000..7ba4b609 --- /dev/null +++ b/applications/notification/notification-messages-notes.h @@ -0,0 +1,119 @@ +#pragma once +#include "notification.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const NotificationMessage message_note_c0; +extern const NotificationMessage message_note_cs0; +extern const NotificationMessage message_note_d0; +extern const NotificationMessage message_note_ds0; +extern const NotificationMessage message_note_e0; +extern const NotificationMessage message_note_f0; +extern const NotificationMessage message_note_fs0; +extern const NotificationMessage message_note_g0; +extern const NotificationMessage message_note_gs0; +extern const NotificationMessage message_note_a0; +extern const NotificationMessage message_note_as0; +extern const NotificationMessage message_note_b0; +extern const NotificationMessage message_note_c1; +extern const NotificationMessage message_note_cs1; +extern const NotificationMessage message_note_d1; +extern const NotificationMessage message_note_ds1; +extern const NotificationMessage message_note_e1; +extern const NotificationMessage message_note_f1; +extern const NotificationMessage message_note_fs1; +extern const NotificationMessage message_note_g1; +extern const NotificationMessage message_note_gs1; +extern const NotificationMessage message_note_a1; +extern const NotificationMessage message_note_as1; +extern const NotificationMessage message_note_b1; +extern const NotificationMessage message_note_c2; +extern const NotificationMessage message_note_cs2; +extern const NotificationMessage message_note_d2; +extern const NotificationMessage message_note_ds2; +extern const NotificationMessage message_note_e2; +extern const NotificationMessage message_note_f2; +extern const NotificationMessage message_note_fs2; +extern const NotificationMessage message_note_g2; +extern const NotificationMessage message_note_gs2; +extern const NotificationMessage message_note_a2; +extern const NotificationMessage message_note_as2; +extern const NotificationMessage message_note_b2; +extern const NotificationMessage message_note_c3; +extern const NotificationMessage message_note_cs3; +extern const NotificationMessage message_note_d3; +extern const NotificationMessage message_note_ds3; +extern const NotificationMessage message_note_e3; +extern const NotificationMessage message_note_f3; +extern const NotificationMessage message_note_fs3; +extern const NotificationMessage message_note_g3; +extern const NotificationMessage message_note_gs3; +extern const NotificationMessage message_note_a3; +extern const NotificationMessage message_note_as3; +extern const NotificationMessage message_note_b3; +extern const NotificationMessage message_note_c4; +extern const NotificationMessage message_note_cs4; +extern const NotificationMessage message_note_d4; +extern const NotificationMessage message_note_ds4; +extern const NotificationMessage message_note_e4; +extern const NotificationMessage message_note_f4; +extern const NotificationMessage message_note_fs4; +extern const NotificationMessage message_note_g4; +extern const NotificationMessage message_note_gs4; +extern const NotificationMessage message_note_a4; +extern const NotificationMessage message_note_as4; +extern const NotificationMessage message_note_b4; +extern const NotificationMessage message_note_c5; +extern const NotificationMessage message_note_cs5; +extern const NotificationMessage message_note_d5; +extern const NotificationMessage message_note_ds5; +extern const NotificationMessage message_note_e5; +extern const NotificationMessage message_note_f5; +extern const NotificationMessage message_note_fs5; +extern const NotificationMessage message_note_g5; +extern const NotificationMessage message_note_gs5; +extern const NotificationMessage message_note_a5; +extern const NotificationMessage message_note_as5; +extern const NotificationMessage message_note_b5; +extern const NotificationMessage message_note_c6; +extern const NotificationMessage message_note_cs6; +extern const NotificationMessage message_note_d6; +extern const NotificationMessage message_note_ds6; +extern const NotificationMessage message_note_e6; +extern const NotificationMessage message_note_f6; +extern const NotificationMessage message_note_fs6; +extern const NotificationMessage message_note_g6; +extern const NotificationMessage message_note_gs6; +extern const NotificationMessage message_note_a6; +extern const NotificationMessage message_note_as6; +extern const NotificationMessage message_note_b6; +extern const NotificationMessage message_note_c7; +extern const NotificationMessage message_note_cs7; +extern const NotificationMessage message_note_d7; +extern const NotificationMessage message_note_ds7; +extern const NotificationMessage message_note_e7; +extern const NotificationMessage message_note_f7; +extern const NotificationMessage message_note_fs7; +extern const NotificationMessage message_note_g7; +extern const NotificationMessage message_note_gs7; +extern const NotificationMessage message_note_a7; +extern const NotificationMessage message_note_as7; +extern const NotificationMessage message_note_b7; +extern const NotificationMessage message_note_c8; +extern const NotificationMessage message_note_cs8; +extern const NotificationMessage message_note_d8; +extern const NotificationMessage message_note_ds8; +extern const NotificationMessage message_note_e8; +extern const NotificationMessage message_note_f8; +extern const NotificationMessage message_note_fs8; +extern const NotificationMessage message_note_g8; +extern const NotificationMessage message_note_gs8; +extern const NotificationMessage message_note_a8; +extern const NotificationMessage message_note_as8; +extern const NotificationMessage message_note_b8; + +#ifdef __cplusplus +} +#endif diff --git a/applications/notification/notification-messages.c b/applications/notification/notification-messages.c new file mode 100644 index 00000000..a5f92ad0 --- /dev/null +++ b/applications/notification/notification-messages.c @@ -0,0 +1,323 @@ +#include "notification.h" +#include "notification-messages-notes.h" +#include + +/*********************************** Messages **********************************/ + +// Display +const NotificationMessage message_display_on = { + .type = NotificationMessageTypeLedDisplay, + .data.led.value = 0xFF, +}; + +const NotificationMessage message_display_off = { + .type = NotificationMessageTypeLedDisplay, + .data.led.value = 0x00, +}; + +// Led ON +const NotificationMessage message_red_255 = { + .type = NotificationMessageTypeLedRed, + .data.led.value = 0xFF, +}; + +const NotificationMessage message_green_255 = { + .type = NotificationMessageTypeLedGreen, + .data.led.value = 0xFF, +}; + +const NotificationMessage message_blue_255 = { + .type = NotificationMessageTypeLedBlue, + .data.led.value = 0xFF, +}; + +// Led OFF +const NotificationMessage message_red_0 = { + .type = NotificationMessageTypeLedRed, + .data.led.value = 0x00, +}; + +const NotificationMessage message_green_0 = { + .type = NotificationMessageTypeLedGreen, + .data.led.value = 0x00, +}; + +const NotificationMessage message_blue_0 = { + .type = NotificationMessageTypeLedBlue, + .data.led.value = 0x00, +}; + +// Delay +const NotificationMessage message_delay_10 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 10, +}; + +const NotificationMessage message_delay_25 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 25, +}; + +const NotificationMessage message_delay_50 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 50, +}; + +const NotificationMessage message_delay_100 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 100, +}; + +const NotificationMessage message_delay_250 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 250, +}; + +const NotificationMessage message_delay_500 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 500, +}; + +const NotificationMessage message_delay_1000 = { + .type = NotificationMessageTypeDelay, + .data.delay.length = 1000, +}; + +// Sound +const NotificationMessage message_sound_off = { + .type = NotificationMessageTypeSoundOff, +}; + +// Vibro +const NotificationMessage message_vibro_on = { + .type = NotificationMessageTypeVibro, + .data.vibro.on = true, +}; + +const NotificationMessage message_vibro_off = { + .type = NotificationMessageTypeVibro, + .data.vibro.on = false, +}; + +// Reset +const NotificationMessage message_do_not_reset = { + .type = NotificationMessageTypeDoNotReset, +}; + +/****************************** Message sequences ******************************/ + +// Reset +const NotificationSequence sequence_reset_red = { + &message_red_0, + NULL, +}; + +const NotificationSequence sequence_reset_green = { + &message_blue_0, + NULL, +}; + +const NotificationSequence sequence_reset_blue = { + &message_green_0, + NULL, +}; + +const NotificationSequence sequence_reset_rgb = { + &message_red_0, + &message_blue_0, + &message_green_0, + NULL, +}; + +const NotificationSequence sequence_reset_display = { + &message_display_off, + NULL, +}; + +const NotificationSequence sequence_reset_sound = { + &message_sound_off, + NULL, +}; + +const NotificationSequence sequence_reset_vibro = { + &message_vibro_off, + NULL, +}; + +// Vibro +const NotificationSequence sequence_set_vibro_on = { + &message_vibro_on, + &message_do_not_reset, + NULL, +}; + +// Display +const NotificationSequence sequence_display_on = { + &message_display_on, + NULL, +}; + +const NotificationSequence sequence_display_off = { + &message_display_off, + NULL, +}; + +// Charging +const NotificationSequence sequence_charging = { + &message_red_255, + &message_green_0, + NULL, +}; + +const NotificationSequence sequence_charged = { + &message_green_255, + &message_red_0, + NULL, +}; + +const NotificationSequence sequence_not_charging = { + &message_red_0, + &message_green_0, + NULL, +}; + +// Light up +const NotificationSequence sequence_set_only_red_255 = { + &message_red_255, + &message_green_0, + &message_blue_0, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sequence_set_only_green_255 = { + &message_red_0, + &message_green_255, + &message_blue_0, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sequence_set_only_blue_255 = { + &message_red_0, + &message_green_0, + &message_blue_255, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sequence_set_red_255 = { + &message_red_255, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sequence_set_green_255 = { + &message_green_255, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sequence_set_blue_255 = { + &message_blue_255, + &message_do_not_reset, + NULL, +}; + +// Blink +const NotificationSequence sequence_blink_red_10 = { + &message_red_255, + &message_delay_10, + NULL, +}; + +const NotificationSequence sequence_blink_green_10 = { + &message_green_255, + &message_delay_10, + NULL, +}; + +const NotificationSequence sequence_blink_yellow_10 = { + &message_red_255, + &message_green_255, + &message_delay_10, + NULL, +}; + +const NotificationSequence sequence_blink_red_100 = { + &message_red_255, + &message_delay_100, + NULL, +}; + +const NotificationSequence sequence_blink_green_100 = { + &message_green_255, + &message_delay_100, + NULL, +}; + +const NotificationSequence sequence_blink_blue_100 = { + &message_blue_255, + &message_delay_100, + NULL, +}; + +const NotificationSequence sequence_blink_yellow_100 = { + &message_red_255, + &message_green_255, + &message_delay_100, + NULL, +}; + +const NotificationSequence sequence_blink_cyan_100 = { + &message_green_255, + &message_blue_255, + &message_delay_100, + NULL, +}; + +const NotificationSequence sequence_blink_magenta_100 = { + &message_red_255, + &message_blue_255, + &message_delay_100, + NULL, +}; + +const NotificationSequence sequence_blink_white_100 = { + &message_red_255, + &message_green_255, + &message_blue_255, + &message_delay_100, + NULL, +}; + +// General +const NotificationSequence sequence_success = { + &message_display_on, + &message_green_255, + &message_vibro_on, + &message_note_c5, + &message_delay_50, + &message_vibro_off, + &message_note_e5, + &message_delay_50, + &message_note_g5, + &message_delay_50, + &message_note_c6, + &message_delay_50, + &message_sound_off, + NULL, +}; + +const NotificationSequence sequence_error = { + &message_display_on, + &message_red_255, + &message_vibro_on, + &message_delay_50, + &message_vibro_off, + &message_delay_100, + &message_vibro_on, + &message_delay_50, + &message_vibro_off, + NULL, +}; \ No newline at end of file diff --git a/applications/notification/notification-messages.h b/applications/notification/notification-messages.h new file mode 100644 index 00000000..c93d9589 --- /dev/null +++ b/applications/notification/notification-messages.h @@ -0,0 +1,94 @@ +#pragma once +#include "notification.h" +#include "notification-messages-notes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************** Messages **********************************/ + +// Display +extern const NotificationMessage message_display_on; +extern const NotificationMessage message_display_off; + +// Led ON +extern const NotificationMessage message_red_255; +extern const NotificationMessage message_green_255; +extern const NotificationMessage message_blue_255; + +// Led OFF +extern const NotificationMessage message_red_0; +extern const NotificationMessage message_green_0; +extern const NotificationMessage message_blue_0; + +// Delay +extern const NotificationMessage message_delay_10; +extern const NotificationMessage message_delay_25; +extern const NotificationMessage message_delay_50; +extern const NotificationMessage message_delay_100; +extern const NotificationMessage message_delay_250; +extern const NotificationMessage message_delay_500; +extern const NotificationMessage message_delay_1000; + +// Sound +extern const NotificationMessage message_sound_off; + +// Vibro +extern const NotificationMessage message_vibro_on; +extern const NotificationMessage message_vibro_off; + +// Reset +extern const NotificationMessage message_do_not_reset; + +/****************************** Message sequences ******************************/ + +// Reset +extern const NotificationSequence sequence_reset_red; +extern const NotificationSequence sequence_reset_green; +extern const NotificationSequence sequence_reset_blue; +extern const NotificationSequence sequence_reset_rgb; +extern const NotificationSequence sequence_reset_display; +extern const NotificationSequence sequence_reset_sound; +extern const NotificationSequence sequence_reset_vibro; + +// Vibro +extern const NotificationSequence sequence_set_vibro_on; + +// Display +extern const NotificationSequence sequence_display_on; +extern const NotificationSequence sequence_display_off; + +// Charging +extern const NotificationSequence sequence_charging; +extern const NotificationSequence sequence_charged; +extern const NotificationSequence sequence_not_charging; + +// Light up +extern const NotificationSequence sequence_set_only_red_255; +extern const NotificationSequence sequence_set_only_green_255; +extern const NotificationSequence sequence_set_only_blue_255; +extern const NotificationSequence sequence_set_red_255; +extern const NotificationSequence sequence_set_green_255; +extern const NotificationSequence sequence_set_blue_255; + +// Blink +extern const NotificationSequence sequence_blink_red_10; +extern const NotificationSequence sequence_blink_green_10; +extern const NotificationSequence sequence_blink_yellow_10; + +extern const NotificationSequence sequence_blink_red_100; +extern const NotificationSequence sequence_blink_green_100; +extern const NotificationSequence sequence_blink_blue_100; +extern const NotificationSequence sequence_blink_yellow_100; +extern const NotificationSequence sequence_blink_cyan_100; +extern const NotificationSequence sequence_blink_magenta_100; +extern const NotificationSequence sequence_blink_white_100; + +// General +extern const NotificationSequence sequence_success; +extern const NotificationSequence sequence_error; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/notification/notification.h b/applications/notification/notification.h new file mode 100644 index 00000000..cb88756c --- /dev/null +++ b/applications/notification/notification.h @@ -0,0 +1,76 @@ +#pragma once +#include "stdint.h" +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct NotificationApp NotificationApp; +typedef struct { + float frequency; + float pwm; +} NotificationMessageDataSound; + +typedef struct { + uint8_t value; +} NotificationMessageDataLed; + +typedef struct { + bool on; +} NotificationMessageDataVibro; + +typedef struct { + uint32_t length; +} NotificationMessageDataDelay; + +typedef union { + NotificationMessageDataSound sound; + NotificationMessageDataLed led; + NotificationMessageDataVibro vibro; + NotificationMessageDataDelay delay; +} NotificationMessageData; + +typedef enum { + NotificationMessageTypeVibro, + NotificationMessageTypeSoundOn, + NotificationMessageTypeSoundOff, + NotificationMessageTypeLedRed, + NotificationMessageTypeLedGreen, + NotificationMessageTypeLedBlue, + NotificationMessageTypeDelay, + NotificationMessageTypeLedDisplay, + NotificationMessageTypeDoNotReset, +} NotificationMessageType; + +typedef struct { + NotificationMessageType type; + NotificationMessageData data; +} NotificationMessage; + +typedef const NotificationMessage* NotificationSequence[]; + +void notification_message(NotificationApp* app, const NotificationSequence* sequence); +void notification_message_block(NotificationApp* app, const NotificationSequence* sequence); + +/** + * @brief Send internal (apply to permanent layer) notification message. Think twice before use. + * + * @param app notification record content + * @param sequence notification sequence + */ +void notification_internal_message(NotificationApp* app, const NotificationSequence* sequence); + +/** + * @brief Send internal (apply to permanent layer) notification message and wait for notification end. Think twice before use. + * + * @param app notification record content + * @param sequence notification sequence + */ +void notification_internal_message_block( + NotificationApp* app, + const NotificationSequence* sequence); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/power/power.c b/applications/power/power.c index 744f8176..151af778 100644 --- a/applications/power/power.c +++ b/applications/power/power.c @@ -16,8 +16,16 @@ #include #include +#include + #define POWER_OFF_TIMEOUT 30 +typedef enum { + PowerStateNotCharging, + PowerStateCharging, + PowerStateCharged, +} PowerState; + struct Power { ViewDispatcher* view_dispatcher; View* info_view; @@ -32,6 +40,8 @@ struct Power { ValueMutex* menu_vm; Cli* cli; MenuItem* menu; + + PowerState state; }; void power_draw_battery_callback(Canvas* canvas, void* context) { @@ -91,6 +101,8 @@ void power_menu_info_callback(void* context) { Power* power_alloc() { Power* power = furi_alloc(sizeof(Power)); + power->state = PowerStateNotCharging; + power->menu_vm = furi_record_open("menu"); power->cli = furi_record_open("cli"); @@ -159,20 +171,26 @@ void power_reset(Power* power, PowerBootMode mode) { api_hal_power_reset(); } -static void power_charging_indication_handler() { +static void power_charging_indication_handler(Power* power, NotificationApp* notifications) { if(api_hal_power_is_charging()) { if(api_hal_power_get_pct() == 100) { - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0xFF); + if(power->state != PowerStateCharged) { + notification_internal_message(notifications, &sequence_charged); + power->state = PowerStateCharged; + } } else { - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightRed, 0xFF); + if(power->state != PowerStateCharging) { + notification_internal_message(notifications, &sequence_charging); + power->state = PowerStateCharging; + } } } if(!api_hal_power_is_charging()) { - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); + if(power->state != PowerStateNotCharging) { + notification_internal_message(notifications, &sequence_not_charging); + power->state = PowerStateNotCharging; + } } } @@ -180,6 +198,7 @@ int32_t power_task(void* p) { (void)p; Power* power = power_alloc(); + NotificationApp* notifications = furi_record_open("notification"); Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, power->battery_view_port, GuiLayerStatusBarRight); view_dispatcher_attach_to_gui(power->view_dispatcher, gui, ViewDispatcherTypeFullscreen); @@ -238,7 +257,7 @@ int32_t power_task(void* p) { return true; }); - power_charging_indication_handler(); + power_charging_indication_handler(power, notifications); view_port_update(power->battery_view_port); diff --git a/applications/sd-card-test/sd-card-test.cpp b/applications/sd-card-test/sd-card-test.cpp index 467c804a..55b26938 100644 --- a/applications/sd-card-test/sd-card-test.cpp +++ b/applications/sd-card-test/sd-card-test.cpp @@ -4,6 +4,7 @@ #include "filesystem-api.h" #include "cli/cli.h" #include "callback-connector.h" +#include // event enumeration type typedef uint8_t event_t; @@ -46,6 +47,7 @@ public: const uint32_t benchmark_data_size = 4096; uint8_t* benchmark_data; FS_Api* fs_api; + NotificationApp* notification; // consts static const uint32_t BENCHMARK_ERROR = UINT_MAX; @@ -58,7 +60,6 @@ public: void wait_for_button(InputKey input_button); bool ask(InputKey input_button_cancel, InputKey input_button_ok); void blink_red(); - void set_red(); void blink_green(); // "tests" @@ -91,6 +92,7 @@ void SdTest::run() { app_ready(); fs_api = static_cast(furi_record_open("sdcard")); + notification = static_cast(furi_record_open("notification")); if(fs_api == NULL) { set_error({"cannot get sdcard api"}); @@ -132,6 +134,8 @@ void SdTest::run() { "press BACK to exit", }); wait_for_button(InputKeyBack); + + furi_record_close("notification"); exit(); } @@ -830,27 +834,18 @@ bool SdTest::ask(InputKey input_button_cancel, InputKey input_button_ok) { // blink red led void SdTest::blink_red() { - api_hal_light_set(LightRed, 0xFF); - delay(50); - api_hal_light_set(LightRed, 0x00); -} - -// light up red led -void SdTest::set_red() { - api_hal_light_set(LightRed, 0x00); + notification_message(notification, &sequence_blink_red_100); } // blink green led void SdTest::blink_green() { - api_hal_light_set(LightGreen, 0xFF); - delay(50); - api_hal_light_set(LightGreen, 0x00); + notification_message(notification, &sequence_blink_green_100); } // set text, but with infinite loop template void SdTest::set_error(std::initializer_list list) { set_text(list); - set_red(); + blink_red(); wait_for_button(InputKeyBack); exit(); } diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c index dbeb1075..316c6e8d 100644 --- a/applications/sd-filesystem/sd-filesystem.c +++ b/applications/sd-filesystem/sd-filesystem.c @@ -206,41 +206,85 @@ void app_sd_format_internal(SdApp* sd_app) { _fs_unlock(&sd_app->info); } -void app_sd_notify_wait_on() { - api_hal_light_set(LightRed, 0xFF); - api_hal_light_set(LightBlue, 0xFF); +const NotificationSequence sd_sequence_success = { + &message_green_255, + &message_delay_50, + &message_green_0, + &message_delay_50, + &message_green_255, + &message_delay_50, + &message_green_0, + &message_delay_50, + &message_green_255, + &message_delay_50, + &message_green_0, + &message_delay_50, + NULL, +}; + +const NotificationSequence sd_sequence_error = { + &message_red_255, + &message_delay_50, + &message_red_0, + &message_delay_50, + &message_red_255, + &message_delay_50, + &message_red_0, + &message_delay_50, + &message_red_255, + &message_delay_50, + &message_red_0, + &message_delay_50, + NULL, +}; + +const NotificationSequence sd_sequence_eject = { + &message_blue_255, + &message_delay_50, + &message_blue_0, + &message_delay_50, + &message_blue_255, + &message_delay_50, + &message_blue_0, + &message_delay_50, + &message_blue_255, + &message_delay_50, + &message_blue_0, + &message_delay_50, + NULL, +}; + +const NotificationSequence sd_sequence_wait = { + &message_red_255, + &message_blue_255, + &message_do_not_reset, + NULL, +}; + +const NotificationSequence sd_sequence_wait_off = { + &message_red_0, + &message_blue_0, + NULL, +}; + +void app_sd_notify_wait(SdApp* sd_app) { + notification_message(sd_app->notifications, &sd_sequence_wait); } -void app_sd_notify_wait_off() { - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightBlue, 0x00); +void app_sd_notify_wait_off(SdApp* sd_app) { + notification_message(sd_app->notifications, &sd_sequence_wait_off); } -void app_sd_notify_success() { - for(uint8_t i = 0; i < 3; i++) { - delay(50); - api_hal_light_set(LightGreen, 0xFF); - delay(50); - api_hal_light_set(LightGreen, 0x00); - } +void app_sd_notify_success(SdApp* sd_app) { + notification_message(sd_app->notifications, &sd_sequence_success); } -void app_sd_notify_eject() { - for(uint8_t i = 0; i < 3; i++) { - delay(50); - api_hal_light_set(LightBlue, 0xFF); - delay(50); - api_hal_light_set(LightBlue, 0x00); - } +void app_sd_notify_eject(SdApp* sd_app) { + notification_message(sd_app->notifications, &sd_sequence_eject); } -void app_sd_notify_error() { - for(uint8_t i = 0; i < 3; i++) { - delay(50); - api_hal_light_set(LightRed, 0xFF); - delay(50); - api_hal_light_set(LightRed, 0x00); - } +void app_sd_notify_error(SdApp* sd_app) { + notification_message(sd_app->notifications, &sd_sequence_error); } bool app_sd_mount_card(SdApp* sd_app) { @@ -252,7 +296,7 @@ bool app_sd_mount_card(SdApp* sd_app) { _fs_lock(&sd_app->info); while(result == false && counter > 0 && hal_sd_detect()) { - app_sd_notify_wait_on(); + app_sd_notify_wait(sd_app); if((counter % 10) == 0) { // power reset sd card @@ -278,7 +322,7 @@ bool app_sd_mount_card(SdApp* sd_app) { } } } - app_sd_notify_wait_off(); + app_sd_notify_wait_off(sd_app); if(!result) { delay(1000); @@ -586,6 +630,7 @@ int32_t sd_filesystem(void* p) { Gui* gui = furi_record_open("gui"); Cli* cli = furi_record_open("cli"); + sd_app->notifications = furi_record_open("notification"); ValueMutex* menu_vm = furi_record_open("menu"); gui_add_view_port(gui, sd_app->icon.view_port, GuiLayerStatusBarLeft); @@ -637,10 +682,10 @@ int32_t sd_filesystem(void* p) { "SD FILESYSTEM", "sd init error: %s", fs_error_get_internal_desc(sd_app->info.status)); - app_sd_notify_error(); + app_sd_notify_error(sd_app); } else { FURI_LOG_I("SD FILESYSTEM", "sd init ok"); - app_sd_notify_success(); + app_sd_notify_success(sd_app); } view_port_enabled_set(sd_app->icon.view_port, true); @@ -661,7 +706,7 @@ int32_t sd_filesystem(void* p) { view_port_enabled_set(sd_app->icon.view_port, false); app_sd_unmount_card(sd_app); sd_was_present = true; - app_sd_notify_eject(); + app_sd_notify_eject(sd_app); } } @@ -686,7 +731,7 @@ int32_t sd_filesystem(void* p) { sd_app->sd_app_state = SdAppStateFormatInProgress; delay(100); app_sd_format_internal(sd_app); - app_sd_notify_success(); + app_sd_notify_success(sd_app); dialog_ex_set_left_button_text(dialog, "Back"); dialog_ex_set_header( dialog, "SD card formatted", 64, 10, AlignCenter, AlignCenter); @@ -708,7 +753,7 @@ int32_t sd_filesystem(void* p) { AlignCenter); sd_app->sd_app_state = SdAppStateEjected; app_sd_unmount_card(sd_app); - app_sd_notify_eject(); + app_sd_notify_eject(sd_app); }; break; case SdAppStateFileSelect: { SdAppFileSelectResultEvent retval = {.result = true}; diff --git a/applications/sd-filesystem/sd-filesystem.h b/applications/sd-filesystem/sd-filesystem.h index 46d4e3c7..0170ef83 100644 --- a/applications/sd-filesystem/sd-filesystem.h +++ b/applications/sd-filesystem/sd-filesystem.h @@ -7,6 +7,7 @@ #include #include "sd-card-api.h" #include "view_holder.h" +#include #define SD_FS_MAX_FILES _FS_LOCK #define SD_STATE_LINES_COUNT 6 @@ -100,6 +101,8 @@ struct SdApp { osMessageQueueId_t event_queue; string_t text_holder; + + NotificationApp* notifications; }; /* core api fns */ diff --git a/applications/subghz/subghz_static.c b/applications/subghz/subghz_static.c index eeadd14a..941a5edf 100644 --- a/applications/subghz/subghz_static.c +++ b/applications/subghz/subghz_static.c @@ -5,6 +5,7 @@ #include #include #include +#include static const uint8_t subghz_static_keys[][4] = { {0x74, 0xBA, 0xDE}, @@ -105,7 +106,8 @@ bool subghz_static_input(InputEvent* event, void* context) { if(event->type == InputTypePress) { const uint8_t* key = subghz_static_keys[model->button]; - api_hal_light_set(LightRed, 0xff); + NotificationApp* notification = furi_record_open("notification"); + notification_message_block(notification, &sequence_set_red_255); __disable_irq(); for(uint8_t r = 0; r < 20; r++) { //Payload @@ -127,7 +129,8 @@ bool subghz_static_input(InputEvent* event, void* context) { delay_us(10600); } __enable_irq(); - api_hal_light_set(LightRed, 0x00); + notification_message(notification, &sequence_reset_red); + furi_record_close("notification"); } } diff --git a/applications/tests/irda_decoder/test_data/irda_decoder_nec_test_data.h b/applications/tests/irda_decoder/test_data/irda_decoder_nec_test_data.h index 7269e3f1..69c7626b 100644 --- a/applications/tests/irda_decoder/test_data/irda_decoder_nec_test_data.h +++ b/applications/tests/irda_decoder/test_data/irda_decoder_nec_test_data.h @@ -11,9 +11,9 @@ const uint32_t test_nec_input1[] = { 1415838, 9080, 4436, 611, 494, 600, 505, 578, 500, 608, 501, 602, 502, 580, 498, 606, 508, 605, 500, 583, 1633, 608, 1608, 611, 1631, 578, 1638, 602, 1614, 606, 1637, 583, 1633, 607, 1609, 611, 494, 600, 505, 570, 500, 604, 501, 602, 502, 581, 497, 606, 499, 605, 499, 583, 1633, 617, 1608, 611, 1631, 579, 1638, 602}; const IrdaMessage test_nec_expected1[] = { - {IrdaProtocolNEC, 0, 0, false}, - {IrdaProtocolNEC, 0, 0, true}, - {IrdaProtocolNEC, 0, 0, false}, + {IrdaProtocolNEC, 0xFF00, 0, false}, + {IrdaProtocolNEC, 0xFF00, 0, true}, + {IrdaProtocolNEC, 0xFF00, 0, false}, }; const uint32_t test_nec_input2[] = { @@ -124,57 +124,57 @@ const uint32_t test_nec_input2[] = { }; const IrdaMessage test_nec_expected2[] = { - {IrdaProtocolNEC, 0, 0x02, false}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, false}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x02, true}, - {IrdaProtocolNEC, 0, 0x06, false}, - {IrdaProtocolNEC, 0, 0x06, true}, - {IrdaProtocolNEC, 0, 0x04, false}, - {IrdaProtocolNEC, 0, 0x04, true}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, true}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, true}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x09, false}, - {IrdaProtocolNEC, 0, 0x09, false}, - {IrdaProtocolNEC, 0, 0x09, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x0A, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, true}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x08, true}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x0A, false}, - {IrdaProtocolNEC, 0, 0x08, false}, - {IrdaProtocolNEC, 0, 0x0A, false}, - {IrdaProtocolNEC, 0, 0x0A, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, false}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, false}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x02, true}, + {IrdaProtocolNEC, 0xFF00, 0x06, false}, + {IrdaProtocolNEC, 0xFF00, 0x06, true}, + {IrdaProtocolNEC, 0xFF00, 0x04, false}, + {IrdaProtocolNEC, 0xFF00, 0x04, true}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, true}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, true}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x09, false}, + {IrdaProtocolNEC, 0xFF00, 0x09, false}, + {IrdaProtocolNEC, 0xFF00, 0x09, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x0A, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, true}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, true}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x0A, false}, + {IrdaProtocolNEC, 0xFF00, 0x08, false}, + {IrdaProtocolNEC, 0xFF00, 0x0A, false}, + {IrdaProtocolNEC, 0xFF00, 0x0A, true}, }; diff --git a/applications/tests/test_index.c b/applications/tests/test_index.c index a5d9fb27..2774a4bb 100644 --- a/applications/tests/test_index.c +++ b/applications/tests/test_index.c @@ -2,6 +2,7 @@ #include #include #include "minunit_vars.h" +#include int run_minunit(); int run_minunit_test_irda_decoder(); @@ -9,28 +10,24 @@ int run_minunit_test_irda_decoder(); int32_t flipper_test_app(void* p) { uint32_t test_result = 0; - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0xFF); + NotificationApp* notification = furi_record_open("notification"); + + notification_message_block(notification, &sequence_set_only_blue_255); test_result |= run_minunit(); test_result |= run_minunit_test_irda_decoder(); - /* power_charging_indication_handler() breaks 1 sec light on */ - for(int i = 0; i < 1000; ++i) { - if(test_result == 0) { - // test passed - api_hal_light_set(LightRed, 0x00); - api_hal_light_set(LightGreen, 0xFF); - api_hal_light_set(LightBlue, 0x00); - } else { - // test failed - api_hal_light_set(LightRed, 0xFF); - api_hal_light_set(LightGreen, 0x00); - api_hal_light_set(LightBlue, 0x00); - } - delay(1); + if(test_result == 0) { + // test passed + notification_message(notification, &sequence_success); + notification_message(notification, &sequence_set_only_green_255); + } else { + // test failed + notification_message(notification, &sequence_error); + notification_message(notification, &sequence_set_only_red_255); } + furi_record_close("notification"); + return 0; } diff --git a/lib/ST25RFAL002/platform.h b/lib/ST25RFAL002/platform.h index 22a6436f..3ff9bf8b 100644 --- a/lib/ST25RFAL002/platform.h +++ b/lib/ST25RFAL002/platform.h @@ -29,11 +29,6 @@ void platformUnprotectST25RComm(); #define ST25R_INT_PIN NFC_IRQ_Pin #define ST25R_INT_PORT NFC_IRQ_GPIO_Port -#define PLATFORM_LED_RX_PIN LightRed -#define PLATFORM_LED_RX_PORT NULL -#define PLATFORM_LED_FIELD_PIN LightBlue -#define PLATFORM_LED_FIELD_PORT NULL - #define RFAL_FEATURE_LISTEN_MODE true /*!< Enable/Disable RFAL support for Listen Mode */ #define RFAL_FEATURE_WAKEUP_MODE true /*!< Enable/Disable RFAL support for the Wake-Up mode */ #define RFAL_FEATURE_LOWPOWER_MODE true /*!< Enable/Disable RFAL support for the Low Power mode */ @@ -65,9 +60,6 @@ void platformUnprotectST25RComm(); #define platformProtectST25RIrqStatus() platformProtectST25RComm() /*!< Protect unique access to IRQ status var - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thread environment */ #define platformUnprotectST25RIrqStatus() platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */ -#define platformLedOff( port, pin ) api_hal_light_set(pin, 0x00) -#define platformLedOn( port, pin ) api_hal_light_set(pin, 0xFF) - #define platformGpioSet( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */ #define platformGpioClear( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */ #define platformGpioToogle( port, pin ) HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */ diff --git a/lib/irda/nec/irda_decoder_nec.c b/lib/irda/nec/irda_decoder_nec.c index 819d3ea9..506adadd 100644 --- a/lib/irda/nec/irda_decoder_nec.c +++ b/lib/irda/nec/irda_decoder_nec.c @@ -3,11 +3,9 @@ #include #include "../irda_i.h" - static bool interpret_nec(IrdaCommonDecoder* decoder); static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder); - static const IrdaCommonProtocolSpec protocol_nec = { { IRDA_NEC_PREAMBULE_MARK, @@ -25,17 +23,15 @@ static const IrdaCommonProtocolSpec protocol_nec = { decode_repeat_nec, }; - static bool interpret_nec(IrdaCommonDecoder* decoder) { furi_assert(decoder); bool result = false; - uint8_t address = decoder->data[0]; - uint8_t address_inverse = decoder->data[1]; + uint16_t address = decoder->data[0] | (decoder->data[1] << 8); uint8_t command = decoder->data[2]; uint8_t command_inverse = decoder->data[3]; - if ((command == (uint8_t) ~command_inverse) && (address == (uint8_t) ~address_inverse)) { + if((command == (uint8_t)~command_inverse)) { decoder->message.command = command; decoder->message.address = address; decoder->message.repeat = false; @@ -53,14 +49,13 @@ static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder) { uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; DecodeStatus status = DecodeStatusError; - if (decoder->timings_cnt < 4) - return DecodeStatusOk; + if(decoder->timings_cnt < 4) return DecodeStatusOk; - if ((decoder->timings[0] > IRDA_NEC_REPEAT_PAUSE_MIN) - && (decoder->timings[0] < IRDA_NEC_REPEAT_PAUSE_MAX) - && MATCH_PREAMBLE_TIMING(decoder->timings[1], IRDA_NEC_REPEAT_MARK, preamble_tolerance) - && MATCH_PREAMBLE_TIMING(decoder->timings[2], IRDA_NEC_REPEAT_SPACE, preamble_tolerance) - && MATCH_BIT_TIMING(decoder->timings[3], decoder->protocol->timings.bit1_mark, bit_tolerance)) { + if((decoder->timings[0] > IRDA_NEC_REPEAT_PAUSE_MIN) && + (decoder->timings[0] < IRDA_NEC_REPEAT_PAUSE_MAX) && + MATCH_PREAMBLE_TIMING(decoder->timings[1], IRDA_NEC_REPEAT_MARK, preamble_tolerance) && + MATCH_PREAMBLE_TIMING(decoder->timings[2], IRDA_NEC_REPEAT_SPACE, preamble_tolerance) && + MATCH_BIT_TIMING(decoder->timings[3], decoder->protocol->timings.bit1_mark, bit_tolerance)) { status = DecodeStatusReady; decoder->timings_cnt = 0; } else { @@ -81,4 +76,3 @@ IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duratio void irda_decoder_nec_free(void* decoder) { irda_common_decoder_free(decoder); } -