[FL-1237] Notifications app (#476)
* Notification app: init * Notification app: separate message sequences * Notification app: rename notifications to notification * Notification app: rework api * Notification app: new sequences for charger * Power app: add state for better led handling * Power app: NotificationSequence type, notification led process * Blink app: use notifications * Notification app: sound and vibro notifications * Notification app: note messages * Notification app: more messages * Notification app: update note message generator * Blink app: fix state counter * Notification app: fix delay event * App sd-filesystem: notifications * App notifications: headers c++ compatibility * App notifications: Cmaj success chord sequence * App iButton: use notifications * App notification: display backlight notifications * App notification: add "display on" message to success and error sequences * App accessor: use notifications * App ibutton: guard onewire key read * Lib-RFAL: remove api_hal_light usage * App notification: add blocking mode, rework display api * Cli led command: use internal notification instead of direc access to leds. * App unit test: use notifications * App lfrfid: use notifications * Apps: close notification record * App subghz: rough use of notifications * App notificaton: ignore reset flag * App strobe: removed * Lib irda decoder: fix nec decoding * App irda: fix assert, use notifications * Apps: use notifications * Fix IRDA tests * Cli: better var naming * App notification: readable sources Co-authored-by: Albert Kharisov <albert@flipperdevices.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									eac8626c8c
								
							
						
					
					
						commit
						2daf65b62b
					
				| @ -8,8 +8,6 @@ void AccessorApp::run(void) { | |||||||
|     bool consumed; |     bool consumed; | ||||||
|     bool exit = false; |     bool exit = false; | ||||||
| 
 | 
 | ||||||
|     notify_init(); |  | ||||||
| 
 |  | ||||||
|     wiegand.begin(); |     wiegand.begin(); | ||||||
|     onewire_master.start(); |     onewire_master.start(); | ||||||
| 
 | 
 | ||||||
| @ -36,9 +34,14 @@ void AccessorApp::run(void) { | |||||||
| AccessorApp::AccessorApp() | AccessorApp::AccessorApp() | ||||||
|     : onewire_master{&ibutton_gpio} { |     : onewire_master{&ibutton_gpio} { | ||||||
|     api_hal_power_insomnia_enter(); |     api_hal_power_insomnia_enter(); | ||||||
|  |     notification = static_cast<NotificationApp*>(furi_record_open("notification")); | ||||||
|  |     notify_init(); | ||||||
|  |     api_hal_power_enable_otg(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| AccessorApp::~AccessorApp() { | AccessorApp::~AccessorApp() { | ||||||
|  |     api_hal_power_disable_otg(); | ||||||
|  |     furi_record_close("notification"); | ||||||
|     api_hal_power_insomnia_exit(); |     api_hal_power_insomnia_exit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -102,11 +105,6 @@ AccessorApp::Scene AccessorApp::get_previous_scene() { | |||||||
| /***************************** NOTIFY *******************************/ | /***************************** NOTIFY *******************************/ | ||||||
| 
 | 
 | ||||||
| void AccessorApp::notify_init() { | 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_InitTypeDef GPIO_InitStruct = {0}; | ||||||
| 
 | 
 | ||||||
|     GPIO_InitStruct.Pin = PB3_Pin; |     GPIO_InitStruct.Pin = PB3_Pin; | ||||||
| @ -118,35 +116,21 @@ void AccessorApp::notify_init() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AccessorApp::notify_green_blink() { | void AccessorApp::notify_green_blink() { | ||||||
|     api_hal_light_set(LightGreen, 0xFF); |     notification_message(notification, &sequence_blink_green_10); | ||||||
|     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); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AccessorApp::notify_success() { | 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); |     hal_pwm_set(0.5, 1760 / 2, &htim2, TIM_CHANNEL_2); | ||||||
|     notify_green_on(); |  | ||||||
|     delay(100); |     delay(100); | ||||||
|     hal_pwm_stop(&htim2, TIM_CHANNEL_2); |     hal_pwm_stop(&htim2, TIM_CHANNEL_2); | ||||||
|     notify_green_off(); |  | ||||||
| 
 | 
 | ||||||
|     delay(100); |     delay(100); | ||||||
| 
 | 
 | ||||||
|     hal_pwm_set(0.5, 1760, &htim2, TIM_CHANNEL_2); |     hal_pwm_set(0.5, 1760, &htim2, TIM_CHANNEL_2); | ||||||
|     notify_green_on(); |  | ||||||
|     delay(100); |     delay(100); | ||||||
|     hal_pwm_stop(&htim2, TIM_CHANNEL_2); |     hal_pwm_stop(&htim2, TIM_CHANNEL_2); | ||||||
|     notify_green_off(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*************************** TEXT STORE *****************************/ | /*************************** TEXT STORE *****************************/ | ||||||
|  | |||||||
| @ -9,6 +9,8 @@ | |||||||
| 
 | 
 | ||||||
| #include <one_wire_master.h> | #include <one_wire_master.h> | ||||||
| 
 | 
 | ||||||
|  | #include <notification/notification-messages.h> | ||||||
|  | 
 | ||||||
| class AccessorApp { | class AccessorApp { | ||||||
| public: | public: | ||||||
|     void run(void); |     void run(void); | ||||||
| @ -29,8 +31,6 @@ public: | |||||||
| 
 | 
 | ||||||
|     void notify_init(); |     void notify_init(); | ||||||
|     void notify_green_blink(); |     void notify_green_blink(); | ||||||
|     void notify_green_on(); |  | ||||||
|     void notify_green_off(); |  | ||||||
| 
 | 
 | ||||||
|     void notify_success(); |     void notify_success(); | ||||||
| 
 | 
 | ||||||
| @ -55,4 +55,6 @@ private: | |||||||
| 
 | 
 | ||||||
|     WIEGAND wiegand; |     WIEGAND wiegand; | ||||||
|     OneWireMaster onewire_master; |     OneWireMaster onewire_master; | ||||||
|  | 
 | ||||||
|  |     NotificationApp* notification; | ||||||
| }; | }; | ||||||
| @ -38,6 +38,7 @@ int32_t passport(void* p); | |||||||
| int32_t app_accessor(void* p); | int32_t app_accessor(void* p); | ||||||
| int32_t internal_storage_task(void* p); | int32_t internal_storage_task(void* p); | ||||||
| int32_t app_archive(void* p); | int32_t app_archive(void* p); | ||||||
|  | int32_t notification_app(void* p); | ||||||
| 
 | 
 | ||||||
| // On system start hooks declaration
 | // On system start hooks declaration
 | ||||||
| void nfc_cli_init(); | void nfc_cli_init(); | ||||||
| @ -155,6 +156,10 @@ const FlipperApplication FLIPPER_SERVICES[] = { | |||||||
|     {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14}, |     {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14}, | ||||||
| #endif | #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); | const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ SRV_CLI = 1 | |||||||
| SRV_SD_FILESYSTEM = 1 | SRV_SD_FILESYSTEM = 1 | ||||||
| SRV_INTERNAL_STORAGE = 1 | SRV_INTERNAL_STORAGE = 1 | ||||||
| SRV_DOLPHIN = 1 | SRV_DOLPHIN = 1 | ||||||
|  | SRV_NOTIFICATION = 1 | ||||||
| 
 | 
 | ||||||
| # Main Apps
 | # Main Apps
 | ||||||
| APP_IRDA  = 1 | APP_IRDA  = 1 | ||||||
| @ -328,3 +329,8 @@ ifeq ($(SRV_CLI), 1) | |||||||
| SRV_GUI		= 1 | SRV_GUI		= 1 | ||||||
| CFLAGS		+= -DSRV_CLI | CFLAGS		+= -DSRV_CLI | ||||||
| endif | endif | ||||||
|  | 
 | ||||||
|  | SRV_NOTIFICATION ?= 0 | ||||||
|  | ifeq ($(SRV_NOTIFICATION), 1) | ||||||
|  | CFLAGS		+= -DSRV_NOTIFICATION | ||||||
|  | endif | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| #define BACKLIGHT_TIME 30000 | #define BACKLIGHT_TIME 30000 | ||||||
| #define BACKLIGHT_FLAG_ACTIVITY 0x00000001U | #define BACKLIGHT_FLAG_ACTIVITY 0x00000001U | ||||||
| @ -10,18 +11,19 @@ static void event_cb(const void* value, void* ctx) { | |||||||
| 
 | 
 | ||||||
| int32_t backlight_control(void* p) { | int32_t backlight_control(void* p) { | ||||||
|     // open record
 |     // open record
 | ||||||
|  |     NotificationApp* notifications = furi_record_open("notification"); | ||||||
|     PubSub* event_record = furi_record_open("input_events"); |     PubSub* event_record = furi_record_open("input_events"); | ||||||
|     subscribe_pubsub(event_record, event_cb, (void*)osThreadGetId()); |     subscribe_pubsub(event_record, event_cb, (void*)osThreadGetId()); | ||||||
| 
 | 
 | ||||||
|     api_hal_light_set(LightBacklight, 0xFF); |     notification_internal_message(notifications, &sequence_display_on); | ||||||
| 
 | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|         // wait for event
 |         // wait for event
 | ||||||
|         if(osThreadFlagsWait(BACKLIGHT_FLAG_ACTIVITY, osFlagsWaitAny, BACKLIGHT_TIME) == |         if(osThreadFlagsWait(BACKLIGHT_FLAG_ACTIVITY, osFlagsWaitAny, BACKLIGHT_TIME) == | ||||||
|            BACKLIGHT_FLAG_ACTIVITY) { |            BACKLIGHT_FLAG_ACTIVITY) { | ||||||
|             api_hal_light_set(LightBacklight, 0xFF); |             notification_internal_message(notifications, &sequence_display_on); | ||||||
|         } else { |         } else { | ||||||
|             api_hal_light_set(LightBacklight, 0x00); |             notification_internal_message(notifications, &sequence_display_off); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| #include <rtc.h> | #include <rtc.h> | ||||||
| #include <task-control-block.h> | #include <task-control-block.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| void cli_command_help(Cli* cli, string_t args, void* context) { | void cli_command_help(Cli* cli, string_t args, void* context) { | ||||||
|     (void)args; |     (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) { | void cli_command_vibro(Cli* cli, string_t args, void* context) { | ||||||
|     if(!string_cmp(args, "0")) { |     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")) { |     } 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 { |     } else { | ||||||
|         printf("Wrong input"); |         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) { | void cli_command_led(Cli* cli, string_t args, void* context) { | ||||||
|     // Get first word as light name
 |     // Get first word as light name
 | ||||||
|     Light light; |     NotificationMessage notification_led_message; | ||||||
|     string_t light_name; |     string_t light_name; | ||||||
|     string_init(light_name); |     string_init(light_name); | ||||||
|     size_t ws = string_search_char(args, ' '); |     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
 |     // Check light name
 | ||||||
|     if(!string_cmp(light_name, "r")) { |     if(!string_cmp(light_name, "r")) { | ||||||
|         light = LightRed; |         notification_led_message.type = NotificationMessageTypeLedRed; | ||||||
|     } else if(!string_cmp(light_name, "g")) { |     } else if(!string_cmp(light_name, "g")) { | ||||||
|         light = LightGreen; |         notification_led_message.type = NotificationMessageTypeLedGreen; | ||||||
|     } else if(!string_cmp(light_name, "b")) { |     } else if(!string_cmp(light_name, "b")) { | ||||||
|         light = LightBlue; |         notification_led_message.type = NotificationMessageTypeLedBlue; | ||||||
|     } else if(!string_cmp(light_name, "bl")) { |     } else if(!string_cmp(light_name, "bl")) { | ||||||
|         light = LightBacklight; |         notification_led_message.type = NotificationMessageTypeLedDisplay; | ||||||
|     } else { |     } else { | ||||||
|         printf("Wrong argument"); |         printf("Wrong argument"); | ||||||
|         string_clear(light_name); |         string_clear(light_name); | ||||||
| @ -151,7 +156,20 @@ void cli_command_led(Cli* cli, string_t args, void* context) { | |||||||
|         printf("Wrong argument"); |         printf("Wrong argument"); | ||||||
|         return; |         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) { | void cli_command_gpio_set(Cli* cli, string_t args, void* context) { | ||||||
|  | |||||||
| @ -4,6 +4,10 @@ | |||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| 
 | 
 | ||||||
|  | #include <notification/notification-messages.h> | ||||||
|  | 
 | ||||||
|  | #define BLINK_COLOR_COUNT 7 | ||||||
|  | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     EventTypeTick, |     EventTypeTick, | ||||||
|     EventTypeKey, |     EventTypeKey, | ||||||
| @ -14,12 +18,6 @@ typedef struct { | |||||||
|     InputEvent input; |     InputEvent input; | ||||||
| } BlinkEvent; | } 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) { | void blink_update(void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     osMessageQueueId_t event_queue = ctx; | ||||||
| @ -57,16 +55,18 @@ int32_t application_blink(void* p) { | |||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     bool blink_color[][3] = { |     NotificationApp* notifications = furi_record_open("notification"); | ||||||
|         {1, 0, 0}, | 
 | ||||||
|         {0, 1, 0}, |     const NotificationSequence* colors[BLINK_COLOR_COUNT] = { | ||||||
|         {0, 0, 1}, |         &sequence_blink_red_100, | ||||||
|         {1, 1, 0}, |         &sequence_blink_green_100, | ||||||
|         {0, 1, 1}, |         &sequence_blink_blue_100, | ||||||
|         {1, 0, 1}, |         &sequence_blink_yellow_100, | ||||||
|         {1, 1, 1}, |         &sequence_blink_cyan_100, | ||||||
|         {0, 0, 0}, |         &sequence_blink_magenta_100, | ||||||
|  |         &sequence_blink_white_100, | ||||||
|     }; |     }; | ||||||
|  | 
 | ||||||
|     uint8_t state = 0; |     uint8_t state = 0; | ||||||
|     BlinkEvent event; |     BlinkEvent event; | ||||||
| 
 | 
 | ||||||
| @ -74,7 +74,7 @@ int32_t application_blink(void* p) { | |||||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); |         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); | ||||||
|         if(event.type == EventTypeKey) { |         if(event.type == EventTypeKey) { | ||||||
|             if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { |             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); |                 view_port_enabled_set(view_port, false); | ||||||
|                 gui_remove_view_port(gui, view_port); |                 gui_remove_view_port(gui, view_port); | ||||||
|                 view_port_free(view_port); |                 view_port_free(view_port); | ||||||
| @ -84,12 +84,12 @@ int32_t application_blink(void* p) { | |||||||
|                 return 0; |                 return 0; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             if(state < sizeof(blink_color) / sizeof(blink_color[0])) { |             notification_message(notifications, colors[state]); | ||||||
|  | 
 | ||||||
|             state++; |             state++; | ||||||
|             } else { |             if(state >= BLINK_COLOR_COUNT) { | ||||||
|                 state = 0; |                 state = 0; | ||||||
|             } |             } | ||||||
|             rgb_set(blink_color[state][0], blink_color[state][1], blink_color[state][2]); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,46 +0,0 @@ | |||||||
| #include <furi.h> |  | ||||||
| #include <api-hal.h> |  | ||||||
| #include <input/input.h> |  | ||||||
| 
 |  | ||||||
| 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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -3,6 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     InputEvent input; |     InputEvent input; | ||||||
| @ -27,7 +28,6 @@ void vibro_input_callback(InputEvent* input_event, void* ctx) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t application_vibro(void* p) { | int32_t application_vibro(void* p) { | ||||||
|     GpioPin* gpio = (GpioPin*)&vibro_gpio; |  | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(VibroEvent), NULL); |     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(VibroEvent), NULL); | ||||||
| 
 | 
 | ||||||
|     // Configure view port
 |     // Configure view port
 | ||||||
| @ -40,15 +40,16 @@ int32_t application_vibro(void* p) { | |||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     hal_gpio_init(gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); |     NotificationApp* notification = furi_record_open("notification"); | ||||||
|     hal_gpio_write(gpio, false); | 
 | ||||||
|     VibroEvent event; |     VibroEvent event; | ||||||
| 
 | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); |         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); | ||||||
|         if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { |         if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { | ||||||
|             hal_gpio_write(gpio, false); |             notification_message(notification, &sequence_reset_vibro); | ||||||
|             api_hal_light_set(LightGreen, 0); |             notification_message(notification, &sequence_reset_green); | ||||||
|  |             furi_record_close("notification"); | ||||||
|             view_port_enabled_set(view_port, false); |             view_port_enabled_set(view_port, false); | ||||||
|             gui_remove_view_port(gui, view_port); |             gui_remove_view_port(gui, view_port); | ||||||
|             view_port_free(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.key == InputKeyOk) { | ||||||
|             if(event.input.type == InputTypePress) { |             if(event.input.type == InputTypePress) { | ||||||
|                 hal_gpio_write(gpio, true); |                 notification_message(notification, &sequence_set_vibro_on); | ||||||
|                 api_hal_light_set(LightGreen, 255); |                 notification_message(notification, &sequence_set_green_255); | ||||||
|             } else if(event.input.type == InputTypeRelease) { |             } else if(event.input.type == InputTypeRelease) { | ||||||
|                 hal_gpio_write(gpio, false); |                 notification_message(notification, &sequence_reset_vibro); | ||||||
|                 api_hal_light_set(LightGreen, 0); |                 notification_message(notification, &sequence_reset_green); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     const char* name; |     const char* name; | ||||||
| @ -81,6 +82,8 @@ int32_t app_gpio_test(void* p) { | |||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|  |     NotificationApp* notification = furi_record_open("notification"); | ||||||
|  | 
 | ||||||
|     // configure pin
 |     // configure pin
 | ||||||
|     for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) { |     for(uint8_t i = 0; i < sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); i++) { | ||||||
|         hal_gpio_init( |         hal_gpio_init( | ||||||
| @ -97,8 +100,8 @@ int32_t app_gpio_test(void* p) { | |||||||
|                 if(event.value.input.type == InputTypeShort && |                 if(event.value.input.type == InputTypeShort && | ||||||
|                    event.value.input.key == InputKeyBack) { |                    event.value.input.key == InputKeyBack) { | ||||||
|                     printf("[gpio-tester] bye!\r\n"); |                     printf("[gpio-tester] bye!\r\n"); | ||||||
| 
 |                     notification_message(notification, &sequence_reset_green); | ||||||
|                     api_hal_light_set(LightGreen, 0x00); |                     furi_record_close("notification"); | ||||||
| 
 | 
 | ||||||
|                     view_port_enabled_set(view_port, false); |                     view_port_enabled_set(view_port, false); | ||||||
|                     gui_remove_view_port(gui, view_port); |                     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.key == InputKeyOk) { | ||||||
|                     if(event.value.input.type == InputTypePress) { |                     if(event.value.input.type == InputTypePress) { | ||||||
|                         hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, true); |                         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) { |                     } else if(event.value.input.type == InputTypeRelease) { | ||||||
|                         hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, false); |                         hal_gpio_write((GpioPin*)&GPIO_PINS[state->gpio_index].pin, false); | ||||||
|                         api_hal_light_set(LightGreen, 0x00); |                         notification_message(notification, &sequence_reset_green); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -61,6 +61,7 @@ bool KeyReader::read_key(iButtonKeyType* key_type, uint8_t* data, uint8_t data_s | |||||||
| 
 | 
 | ||||||
|     switch(read_mode) { |     switch(read_mode) { | ||||||
|     case ReadMode::DALLAS: |     case ReadMode::DALLAS: | ||||||
|  |         __disable_irq(); | ||||||
|         if(onewire_master->search(data)) { |         if(onewire_master->search(data)) { | ||||||
|             onewire_master->reset_search(); |             onewire_master->reset_search(); | ||||||
|             readed = true; |             readed = true; | ||||||
| @ -68,6 +69,7 @@ bool KeyReader::read_key(iButtonKeyType* key_type, uint8_t* data, uint8_t data_s | |||||||
|         } else { |         } else { | ||||||
|             onewire_master->reset_search(); |             onewire_master->reset_search(); | ||||||
|         } |         } | ||||||
|  |         __enable_irq(); | ||||||
|         break; |         break; | ||||||
|     case ReadMode::CYFRAL_METAKOM: |     case ReadMode::CYFRAL_METAKOM: | ||||||
|         if(cyfral_decoder.read(data, 2)) { |         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) { |     switch(key_type) { | ||||||
|     case iButtonKeyType::KeyDallas: |     case iButtonKeyType::KeyDallas: | ||||||
|         switch_to(ReadMode::DALLAS); |         switch_to(ReadMode::DALLAS); | ||||||
| 
 |         __disable_irq(); | ||||||
|         if(onewire_master->reset()) { |         if(onewire_master->reset()) { | ||||||
|             onewire_master->write(DS1990::CMD_READ_ROM); |             onewire_master->write(DS1990::CMD_READ_ROM); | ||||||
|             for(uint8_t i = 0; i < data_size; i++) { |             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; |             result = false; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 |         __enable_irq(); | ||||||
|         break; |         break; | ||||||
| 
 | 
 | ||||||
|     default: |     default: | ||||||
|  | |||||||
| @ -178,7 +178,6 @@ void iButtonApp::cli_send_event(iButtonApp::CliEvent scene) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| iButtonApp::iButtonApp() { | iButtonApp::iButtonApp() { | ||||||
|     notify_init(); |  | ||||||
|     api_hal_power_insomnia_enter(); |     api_hal_power_insomnia_enter(); | ||||||
| 
 | 
 | ||||||
|     cli_event_result = osMessageQueueNew(1, sizeof(iButtonApp::Scene), NULL); |     cli_event_result = osMessageQueueNew(1, sizeof(iButtonApp::Scene), NULL); | ||||||
| @ -186,6 +185,8 @@ iButtonApp::iButtonApp() { | |||||||
|     sd_ex_api = static_cast<SdCard_Api*>(furi_record_open("sdcard-ex")); |     sd_ex_api = static_cast<SdCard_Api*>(furi_record_open("sdcard-ex")); | ||||||
|     fs_api = static_cast<FS_Api*>(furi_record_open("sdcard")); |     fs_api = static_cast<FS_Api*>(furi_record_open("sdcard")); | ||||||
|     cli = static_cast<Cli*>(furi_record_open("cli")); |     cli = static_cast<Cli*>(furi_record_open("cli")); | ||||||
|  |     notification = static_cast<NotificationApp*>(furi_record_open("notification")); | ||||||
|  | 
 | ||||||
|     auto callback = cbc::obtain_connector(this, &iButtonApp::cli_cmd_callback); |     auto callback = cbc::obtain_connector(this, &iButtonApp::cli_cmd_callback); | ||||||
|     cli_add_command(cli, "tm", callback, cli); |     cli_add_command(cli, "tm", callback, cli); | ||||||
| 
 | 
 | ||||||
| @ -194,10 +195,13 @@ iButtonApp::iButtonApp() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| iButtonApp::~iButtonApp() { | iButtonApp::~iButtonApp() { | ||||||
|  |     cli_delete_command(cli, "tm"); | ||||||
|  | 
 | ||||||
|     furi_record_close("sdcard-ex"); |     furi_record_close("sdcard-ex"); | ||||||
|     furi_record_close("sdcard"); |     furi_record_close("sdcard"); | ||||||
|     cli_delete_command(cli, "tm"); |  | ||||||
|     furi_record_close("cli"); |     furi_record_close("cli"); | ||||||
|  |     furi_record_close("notification"); | ||||||
|  | 
 | ||||||
|     osMessageQueueDelete(cli_event_result); |     osMessageQueueDelete(cli_event_result); | ||||||
| 
 | 
 | ||||||
|     for(std::map<Scene, iButtonScene*>::iterator it = scenes.begin(); it != scenes.end(); ++it) { |     for(std::map<Scene, iButtonScene*>::iterator it = scenes.begin(); it != scenes.end(); ++it) { | ||||||
| @ -294,73 +298,40 @@ uint8_t iButtonApp::get_file_name_size() { | |||||||
|     return 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() { | void iButtonApp::notify_green_blink() { | ||||||
|     notify_green_on(); |     notification_message(notification, &sequence_blink_green_10); | ||||||
|     delay(10); |  | ||||||
|     notify_green_off(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::notify_yellow_blink() { | void iButtonApp::notify_yellow_blink() { | ||||||
|     notify_red_on(); |     notification_message(notification, &sequence_blink_yellow_10); | ||||||
|     notify_green_on(); |  | ||||||
|     delay(10); |  | ||||||
|     notify_green_off(); |  | ||||||
|     notify_red_off(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::notify_red_blink() { | void iButtonApp::notify_red_blink() { | ||||||
|     notify_red_on(); |     notification_message(notification, &sequence_blink_red_10); | ||||||
|     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); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::notify_error() { | void iButtonApp::notify_error() { | ||||||
|     notify_vibro_on(); |     notification_message(notification, &sequence_error); | ||||||
|     delay(50); |  | ||||||
|     notify_vibro_off(); |  | ||||||
|     delay(100); |  | ||||||
|     notify_vibro_on(); |  | ||||||
|     delay(50); |  | ||||||
|     notify_vibro_off(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::notify_success() { | void iButtonApp::notify_success() { | ||||||
|     notify_vibro_on(); |     notification_message(notification, &sequence_success); | ||||||
|     hal_pwm_set(0.5, 1760, &SPEAKER_TIM, SPEAKER_CH); |  | ||||||
|     delay(50); |  | ||||||
|     hal_pwm_stop(&SPEAKER_TIM, SPEAKER_CH); |  | ||||||
|     notify_vibro_off(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::notify_vibro_on() { | void iButtonApp::notify_green_on() { | ||||||
|     hal_gpio_write(&vibro_gpio, true); |     notification_message_block(notification, &sequence_set_green_255); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonApp::notify_vibro_off() { | void iButtonApp::notify_green_off() { | ||||||
|     hal_gpio_write(&vibro_gpio, false); |     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...) { | void iButtonApp::set_text_store(const char* text...) { | ||||||
|  | |||||||
| @ -36,6 +36,8 @@ | |||||||
| #include "maxim_crc.h" | #include "maxim_crc.h" | ||||||
| #include "ibutton-key.h" | #include "ibutton-key.h" | ||||||
| 
 | 
 | ||||||
|  | #include <notification/notification-messages.h> | ||||||
|  | 
 | ||||||
| class iButtonApp { | class iButtonApp { | ||||||
| public: | public: | ||||||
|     void run(void); |     void run(void); | ||||||
| @ -92,17 +94,13 @@ public: | |||||||
|     void notify_yellow_blink(); |     void notify_yellow_blink(); | ||||||
|     void notify_red_blink(); |     void notify_red_blink(); | ||||||
| 
 | 
 | ||||||
|  |     void notify_error(); | ||||||
|  |     void notify_success(); | ||||||
|     void notify_green_on(); |     void notify_green_on(); | ||||||
|     void notify_green_off(); |     void notify_green_off(); | ||||||
|     void notify_red_on(); |     void notify_red_on(); | ||||||
|     void notify_red_off(); |     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...); |     void set_text_store(const char* text...); | ||||||
|     char* get_text_store(); |     char* get_text_store(); | ||||||
|     uint8_t get_text_store_size(); |     uint8_t get_text_store_size(); | ||||||
| @ -160,7 +158,8 @@ private: | |||||||
|     static const uint8_t text_store_size = 128; |     static const uint8_t text_store_size = 128; | ||||||
|     char text_store[text_store_size + 1]; |     char text_store[text_store_size + 1]; | ||||||
| 
 | 
 | ||||||
|     void notify_init(); |     NotificationApp* notification; | ||||||
|  | 
 | ||||||
|     bool read_hex_byte(string_t arg, uint8_t* byte); |     bool read_hex_byte(string_t arg, uint8_t* byte); | ||||||
|     void print_key_data(void); |     void print_key_data(void); | ||||||
| }; | }; | ||||||
| @ -33,6 +33,7 @@ void iButtonSceneReadCRCError::on_enter(iButtonApp* app) { | |||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); | ||||||
|     app->notify_error(); |     app->notify_error(); | ||||||
|  |     app->notify_red_on(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool iButtonSceneReadCRCError::on_event(iButtonApp* app, iButtonEvent* event) { | 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_left_button_text(dialog_ex, NULL); | ||||||
|     dialog_ex_set_result_callback(dialog_ex, NULL); |     dialog_ex_set_result_callback(dialog_ex, NULL); | ||||||
|     dialog_ex_set_context(dialog_ex, NULL); |     dialog_ex_set_context(dialog_ex, NULL); | ||||||
|  | 
 | ||||||
|  |     app->notify_red_off(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonSceneReadCRCError::dialog_ex_callback(DialogExResult result, void* context) { | void iButtonSceneReadCRCError::dialog_ex_callback(DialogExResult result, void* context) { | ||||||
|  | |||||||
| @ -33,6 +33,7 @@ void iButtonSceneReadNotKeyError::on_enter(iButtonApp* app) { | |||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); | ||||||
|     app->notify_error(); |     app->notify_error(); | ||||||
|  |     app->notify_red_on(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool iButtonSceneReadNotKeyError::on_event(iButtonApp* app, iButtonEvent* event) { | 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_left_button_text(dialog_ex, NULL); | ||||||
|     dialog_ex_set_result_callback(dialog_ex, NULL); |     dialog_ex_set_result_callback(dialog_ex, NULL); | ||||||
|     dialog_ex_set_context(dialog_ex, NULL); |     dialog_ex_set_context(dialog_ex, NULL); | ||||||
|  | 
 | ||||||
|  |     app->notify_red_off(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonSceneReadNotKeyError::dialog_ex_callback(DialogExResult result, void* context) { | void iButtonSceneReadNotKeyError::dialog_ex_callback(DialogExResult result, void* context) { | ||||||
|  | |||||||
| @ -42,8 +42,9 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { | |||||||
|     dialog_ex_set_context(dialog_ex, app); |     dialog_ex_set_context(dialog_ex, app); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); | ||||||
|     app->notify_green_on(); | 
 | ||||||
|     app->notify_success(); |     app->notify_success(); | ||||||
|  |     app->notify_green_on(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool iButtonSceneReadSuccess::on_event(iButtonApp* app, iButtonEvent* event) { | 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_result_callback(dialog_ex, NULL); | ||||||
|     dialog_ex_set_context(dialog_ex, NULL); |     dialog_ex_set_context(dialog_ex, NULL); | ||||||
|     dialog_ex_set_icon(dialog_ex, -1, -1, I_ButtonCenter_7x7); |     dialog_ex_set_icon(dialog_ex, -1, -1, I_ButtonCenter_7x7); | ||||||
|  | 
 | ||||||
|     app->notify_green_off(); |     app->notify_green_off(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,8 +19,9 @@ void iButtonSceneWriteSuccess::on_enter(iButtonApp* app) { | |||||||
|     popup_enable_timeout(popup); |     popup_enable_timeout(popup); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); | ||||||
|     app->notify_green_on(); | 
 | ||||||
|     app->notify_success(); |     app->notify_success(); | ||||||
|  |     app->notify_green_on(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool iButtonSceneWriteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { | bool iButtonSceneWriteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { | ||||||
| @ -44,7 +45,6 @@ void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { | |||||||
|     popup_disable_timeout(popup); |     popup_disable_timeout(popup); | ||||||
|     popup_set_context(popup, NULL); |     popup_set_context(popup, NULL); | ||||||
|     popup_set_callback(popup, NULL); |     popup_set_callback(popup, NULL); | ||||||
|     app->notify_green_off(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void iButtonSceneWriteSuccess::popup_callback(void* context) { | void iButtonSceneWriteSuccess::popup_callback(void* context) { | ||||||
| @ -52,4 +52,5 @@ void iButtonSceneWriteSuccess::popup_callback(void* context) { | |||||||
|     iButtonEvent event; |     iButtonEvent event; | ||||||
|     event.type = iButtonEvent::Type::EventTypeBack; |     event.type = iButtonEvent::Type::EventTypeBack; | ||||||
|     app->get_view_manager()->send_event(&event); |     app->get_view_manager()->send_event(&event); | ||||||
|  |     app->notify_green_off(); | ||||||
| } | } | ||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| #include <cli/cli.h> | #include <cli/cli.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| #include <api-hal-irda.h> | #include <api-hal-irda.h> | ||||||
| #include "irda.h" | #include "irda.h" | ||||||
| @ -284,7 +285,8 @@ void irda_rx_callback(void* ctx, bool level, uint32_t duration) { | |||||||
| 
 | 
 | ||||||
|     if(message) { |     if(message) { | ||||||
|         event.value.rx = *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_ir_rx_queue = osMessageQueueNew(1, sizeof(IrDAPacket), NULL); | ||||||
|     irda_app.cli_cmd_is_active = false; |     irda_app.cli_cmd_is_active = false; | ||||||
| 
 | 
 | ||||||
|  |     NotificationApp* notification = furi_record_open("notification"); | ||||||
|  | 
 | ||||||
|     for(uint8_t i = 0; i < IRDA_PACKET_COUNT; i++) { |     for(uint8_t i = 0; i < IRDA_PACKET_COUNT; i++) { | ||||||
|         init_packet(&_state, i, 0, 0, 0); |         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_rx"); | ||||||
|                     cli_delete_command(irda_app.cli, "ir_tx"); |                     cli_delete_command(irda_app.cli, "ir_tx"); | ||||||
|                     furi_record_close("cli"); |                     furi_record_close("cli"); | ||||||
|  |                     furi_record_close("notification"); | ||||||
|                     api_hal_irda_rx_irq_deinit(); |                     api_hal_irda_rx_irq_deinit(); | ||||||
|                     irda_free_decoder(isr_context.handler); |                     irda_free_decoder(isr_context.handler); | ||||||
| 
 | 
 | ||||||
| @ -394,9 +399,7 @@ int32_t irda(void* p) { | |||||||
|                 view_port_update(view_port); |                 view_port_update(view_port); | ||||||
| 
 | 
 | ||||||
|             } else if(event.type == EventTypeRX) { |             } else if(event.type == EventTypeRX) { | ||||||
|                 api_hal_light_set(LightRed, 0xFF); |                 notification_message(notification, &sequence_blink_red_10); | ||||||
|                 delay(60); |  | ||||||
|                 api_hal_light_set(LightRed, 0xFF); |  | ||||||
| 
 | 
 | ||||||
|                 // save only if we in packet mode
 |                 // save only if we in packet mode
 | ||||||
|                 State* state = (State*)acquire_mutex_block(&state_mutex); |                 State* state = (State*)acquire_mutex_block(&state_mutex); | ||||||
| @ -422,8 +425,7 @@ int32_t irda(void* p) { | |||||||
|                 view_port_update(view_port); |                 view_port_update(view_port); | ||||||
| 
 | 
 | ||||||
|                 // blink anyway
 |                 // blink anyway
 | ||||||
|                 api_hal_light_set(LightGreen, 0xFF); |                 notification_message(notification, &sequence_blink_green_10); | ||||||
|                 api_hal_light_set(LightGreen, 0x00); |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal-irda.h> | #include <api-hal-irda.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| #define IRDA_TIMINGS_SIZE 2000 | #define IRDA_TIMINGS_SIZE 2000 | ||||||
| 
 | 
 | ||||||
| @ -30,6 +31,7 @@ int32_t irda_monitor_app(void* p) { | |||||||
|     static uint32_t counter = 0; |     static uint32_t counter = 0; | ||||||
| 
 | 
 | ||||||
|     IrdaDelaysArray* delays = furi_alloc(sizeof(IrdaDelaysArray)); |     IrdaDelaysArray* delays = furi_alloc(sizeof(IrdaDelaysArray)); | ||||||
|  |     NotificationApp* notification = furi_record_open("notification"); | ||||||
| 
 | 
 | ||||||
|     api_hal_irda_rx_irq_init(); |     api_hal_irda_rx_irq_init(); | ||||||
|     api_hal_irda_rx_irq_set_callback(irda_rx_callback, delays); |     api_hal_irda_rx_irq_set_callback(irda_rx_callback, delays); | ||||||
| @ -38,13 +40,8 @@ int32_t irda_monitor_app(void* p) { | |||||||
|         delay(20); |         delay(20); | ||||||
| 
 | 
 | ||||||
|         if(counter != delays->timing_cnt) { |         if(counter != delays->timing_cnt) { | ||||||
|             api_hal_light_set(LightRed, 0x00); |             notification_message(notification, &sequence_blink_blue_100); | ||||||
|             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); |  | ||||||
|             counter = delays->timing_cnt; |             counter = delays->timing_cnt; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ void LfrfidApp::run(void) { | |||||||
| 
 | 
 | ||||||
| LfrfidApp::LfrfidApp() { | LfrfidApp::LfrfidApp() { | ||||||
|     api_hal_power_insomnia_enter(); |     api_hal_power_insomnia_enter(); | ||||||
|  |     notification = static_cast<NotificationApp*>(furi_record_open("notification")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LfrfidApp::~LfrfidApp() { | LfrfidApp::~LfrfidApp() { | ||||||
| @ -35,6 +36,8 @@ LfrfidApp::~LfrfidApp() { | |||||||
|         scenes.erase(it); |         scenes.erase(it); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     furi_record_close("notification"); | ||||||
|  | 
 | ||||||
|     api_hal_power_insomnia_exit(); |     api_hal_power_insomnia_exit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -97,25 +100,12 @@ LfrfidApp::Scene LfrfidApp::get_previous_scene() { | |||||||
| 
 | 
 | ||||||
| /***************************** NOTIFY *******************************/ | /***************************** 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() { | void LfrfidApp::notify_green_blink() { | ||||||
|     api_hal_light_set(LightGreen, 0xFF); |     notification_message(notification, &sequence_blink_green_10); | ||||||
|     delay(10); |  | ||||||
|     api_hal_light_set(LightGreen, 0x00); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfrfidApp::notify_green_on() { | void LfrfidApp::notify_success() { | ||||||
|     api_hal_light_set(LightGreen, 0xFF); |     notification_message(notification, &sequence_success); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::notify_green_off() { |  | ||||||
|     api_hal_light_set(LightGreen, 0x00); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*************************** TEXT STORE *****************************/ | /*************************** TEXT STORE *****************************/ | ||||||
|  | |||||||
| @ -15,6 +15,8 @@ | |||||||
| #include "helpers/rfid-reader.h" | #include "helpers/rfid-reader.h" | ||||||
| #include "helpers/rfid-timer-emulator.h" | #include "helpers/rfid-timer-emulator.h" | ||||||
| 
 | 
 | ||||||
|  | #include <notification/notification-messages.h> | ||||||
|  | 
 | ||||||
| class LfrfidApp { | class LfrfidApp { | ||||||
| public: | public: | ||||||
|     void run(void); |     void run(void); | ||||||
| @ -40,10 +42,8 @@ public: | |||||||
|     bool switch_to_previous_scene(uint8_t count = 1); |     bool switch_to_previous_scene(uint8_t count = 1); | ||||||
|     Scene get_previous_scene(); |     Scene get_previous_scene(); | ||||||
| 
 | 
 | ||||||
|     void notify_init(); |  | ||||||
|     void notify_green_blink(); |     void notify_green_blink(); | ||||||
|     void notify_green_on(); |     void notify_success(); | ||||||
|     void notify_green_off(); |  | ||||||
| 
 | 
 | ||||||
|     char* get_text_store(); |     char* get_text_store(); | ||||||
|     uint8_t get_text_store_size(); |     uint8_t get_text_store_size(); | ||||||
| @ -72,6 +72,7 @@ private: | |||||||
|     static const uint8_t text_store_size = 128; |     static const uint8_t text_store_size = 128; | ||||||
|     char text_store[text_store_size + 1]; |     char text_store[text_store_size + 1]; | ||||||
| 
 | 
 | ||||||
|  |     NotificationApp* notification; | ||||||
|     RfidReader reader; |     RfidReader reader; | ||||||
|     RfidTimerEmulator emulator; |     RfidTimerEmulator emulator; | ||||||
|     RfidWriter writer; |     RfidWriter writer; | ||||||
|  | |||||||
| @ -25,13 +25,13 @@ bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { | |||||||
|         LfrfidKeyType type; |         LfrfidKeyType type; | ||||||
| 
 | 
 | ||||||
|         if(app->get_reader()->read(&type, data, data_size)) { |         if(app->get_reader()->read(&type, data, data_size)) { | ||||||
|             app->notify_green_blink(); |  | ||||||
| 
 |  | ||||||
|             if(memcmp(last_data, data, data_size) == 0) { |             if(memcmp(last_data, data, data_size) == 0) { | ||||||
|                 success_reads++; |                 success_reads++; | ||||||
|  |                 app->notify_green_blink(); | ||||||
|             } else { |             } else { | ||||||
|                 success_reads = 1; |                 success_reads = 1; | ||||||
|                 memcpy(last_data, data, data_size); |                 memcpy(last_data, data, data_size); | ||||||
|  |                 app->notify_success(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             switch(type) { |             switch(type) { | ||||||
|  | |||||||
| @ -31,7 +31,7 @@ bool LfrfidSceneWrite::on_event(LfrfidApp* app, LfrfidEvent* event) { | |||||||
|         app->get_writer()->start(); |         app->get_writer()->start(); | ||||||
|         app->get_writer()->write_em(em_data); |         app->get_writer()->write_em(em_data); | ||||||
|         app->get_writer()->stop(); |         app->get_writer()->stop(); | ||||||
|         delay(100); |         delay(200); | ||||||
|         app->get_reader()->start(RfidReader::Type::Normal); |         app->get_reader()->start(RfidReader::Type::Normal); | ||||||
|     } else { |     } else { | ||||||
|         uint8_t data[LFRFID_KEY_SIZE]; |         uint8_t data[LFRFID_KEY_SIZE]; | ||||||
|  | |||||||
							
								
								
									
										37
									
								
								applications/notification/notification-app-api.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								applications/notification/notification-app-api.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | #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); | ||||||
|  | }; | ||||||
							
								
								
									
										371
									
								
								applications/notification/notification-app.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								applications/notification/notification-app.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,371 @@ | |||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | #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; | ||||||
|  | }; | ||||||
							
								
								
									
										46
									
								
								applications/notification/notification-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								applications/notification/notification-app.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | #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; | ||||||
|  | }; | ||||||
							
								
								
									
										568
									
								
								applications/notification/notification-messages-notes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										568
									
								
								applications/notification/notification-messages-notes.c
									
									
									
									
									
										Normal file
									
								
							| @ -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, | ||||||
|  | }; | ||||||
							
								
								
									
										119
									
								
								applications/notification/notification-messages-notes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								applications/notification/notification-messages-notes.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										323
									
								
								applications/notification/notification-messages.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								applications/notification/notification-messages.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,323 @@ | |||||||
|  | #include "notification.h" | ||||||
|  | #include "notification-messages-notes.h" | ||||||
|  | #include <stddef.h> | ||||||
|  | 
 | ||||||
|  | /*********************************** 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, | ||||||
|  | }; | ||||||
							
								
								
									
										94
									
								
								applications/notification/notification-messages.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								applications/notification/notification-messages.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										76
									
								
								applications/notification/notification.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								applications/notification/notification.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
| @ -16,8 +16,16 @@ | |||||||
| #include <assets_icons.h> | #include <assets_icons.h> | ||||||
| #include <stm32wbxx.h> | #include <stm32wbxx.h> | ||||||
| 
 | 
 | ||||||
|  | #include <notification/notification-messages.h> | ||||||
|  | 
 | ||||||
| #define POWER_OFF_TIMEOUT 30 | #define POWER_OFF_TIMEOUT 30 | ||||||
| 
 | 
 | ||||||
|  | typedef enum { | ||||||
|  |     PowerStateNotCharging, | ||||||
|  |     PowerStateCharging, | ||||||
|  |     PowerStateCharged, | ||||||
|  | } PowerState; | ||||||
|  | 
 | ||||||
| struct Power { | struct Power { | ||||||
|     ViewDispatcher* view_dispatcher; |     ViewDispatcher* view_dispatcher; | ||||||
|     View* info_view; |     View* info_view; | ||||||
| @ -32,6 +40,8 @@ struct Power { | |||||||
|     ValueMutex* menu_vm; |     ValueMutex* menu_vm; | ||||||
|     Cli* cli; |     Cli* cli; | ||||||
|     MenuItem* menu; |     MenuItem* menu; | ||||||
|  | 
 | ||||||
|  |     PowerState state; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void power_draw_battery_callback(Canvas* canvas, void* context) { | 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_alloc() { | ||||||
|     Power* power = furi_alloc(sizeof(Power)); |     Power* power = furi_alloc(sizeof(Power)); | ||||||
| 
 | 
 | ||||||
|  |     power->state = PowerStateNotCharging; | ||||||
|  | 
 | ||||||
|     power->menu_vm = furi_record_open("menu"); |     power->menu_vm = furi_record_open("menu"); | ||||||
| 
 | 
 | ||||||
|     power->cli = furi_record_open("cli"); |     power->cli = furi_record_open("cli"); | ||||||
| @ -159,20 +171,26 @@ void power_reset(Power* power, PowerBootMode mode) { | |||||||
|     api_hal_power_reset(); |     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_is_charging()) { | ||||||
|         if(api_hal_power_get_pct() == 100) { |         if(api_hal_power_get_pct() == 100) { | ||||||
|             api_hal_light_set(LightRed, 0x00); |             if(power->state != PowerStateCharged) { | ||||||
|             api_hal_light_set(LightGreen, 0xFF); |                 notification_internal_message(notifications, &sequence_charged); | ||||||
|  |                 power->state = PowerStateCharged; | ||||||
|  |             } | ||||||
|         } else { |         } else { | ||||||
|             api_hal_light_set(LightGreen, 0x00); |             if(power->state != PowerStateCharging) { | ||||||
|             api_hal_light_set(LightRed, 0xFF); |                 notification_internal_message(notifications, &sequence_charging); | ||||||
|  |                 power->state = PowerStateCharging; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(!api_hal_power_is_charging()) { |     if(!api_hal_power_is_charging()) { | ||||||
|         api_hal_light_set(LightRed, 0x00); |         if(power->state != PowerStateNotCharging) { | ||||||
|         api_hal_light_set(LightGreen, 0x00); |             notification_internal_message(notifications, &sequence_not_charging); | ||||||
|  |             power->state = PowerStateNotCharging; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -180,6 +198,7 @@ int32_t power_task(void* p) { | |||||||
|     (void)p; |     (void)p; | ||||||
|     Power* power = power_alloc(); |     Power* power = power_alloc(); | ||||||
| 
 | 
 | ||||||
|  |     NotificationApp* notifications = furi_record_open("notification"); | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|     gui_add_view_port(gui, power->battery_view_port, GuiLayerStatusBarRight); |     gui_add_view_port(gui, power->battery_view_port, GuiLayerStatusBarRight); | ||||||
|     view_dispatcher_attach_to_gui(power->view_dispatcher, gui, ViewDispatcherTypeFullscreen); |     view_dispatcher_attach_to_gui(power->view_dispatcher, gui, ViewDispatcherTypeFullscreen); | ||||||
| @ -238,7 +257,7 @@ int32_t power_task(void* p) { | |||||||
|                 return true; |                 return true; | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|         power_charging_indication_handler(); |         power_charging_indication_handler(power, notifications); | ||||||
| 
 | 
 | ||||||
|         view_port_update(power->battery_view_port); |         view_port_update(power->battery_view_port); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
| #include "filesystem-api.h" | #include "filesystem-api.h" | ||||||
| #include "cli/cli.h" | #include "cli/cli.h" | ||||||
| #include "callback-connector.h" | #include "callback-connector.h" | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| // event enumeration type
 | // event enumeration type
 | ||||||
| typedef uint8_t event_t; | typedef uint8_t event_t; | ||||||
| @ -46,6 +47,7 @@ public: | |||||||
|     const uint32_t benchmark_data_size = 4096; |     const uint32_t benchmark_data_size = 4096; | ||||||
|     uint8_t* benchmark_data; |     uint8_t* benchmark_data; | ||||||
|     FS_Api* fs_api; |     FS_Api* fs_api; | ||||||
|  |     NotificationApp* notification; | ||||||
| 
 | 
 | ||||||
|     // consts
 |     // consts
 | ||||||
|     static const uint32_t BENCHMARK_ERROR = UINT_MAX; |     static const uint32_t BENCHMARK_ERROR = UINT_MAX; | ||||||
| @ -58,7 +60,6 @@ public: | |||||||
|     void wait_for_button(InputKey input_button); |     void wait_for_button(InputKey input_button); | ||||||
|     bool ask(InputKey input_button_cancel, InputKey input_button_ok); |     bool ask(InputKey input_button_cancel, InputKey input_button_ok); | ||||||
|     void blink_red(); |     void blink_red(); | ||||||
|     void set_red(); |  | ||||||
|     void blink_green(); |     void blink_green(); | ||||||
| 
 | 
 | ||||||
|     // "tests"
 |     // "tests"
 | ||||||
| @ -91,6 +92,7 @@ void SdTest::run() { | |||||||
|     app_ready(); |     app_ready(); | ||||||
| 
 | 
 | ||||||
|     fs_api = static_cast<FS_Api*>(furi_record_open("sdcard")); |     fs_api = static_cast<FS_Api*>(furi_record_open("sdcard")); | ||||||
|  |     notification = static_cast<NotificationApp*>(furi_record_open("notification")); | ||||||
| 
 | 
 | ||||||
|     if(fs_api == NULL) { |     if(fs_api == NULL) { | ||||||
|         set_error({"cannot get sdcard api"}); |         set_error({"cannot get sdcard api"}); | ||||||
| @ -132,6 +134,8 @@ void SdTest::run() { | |||||||
|         "press BACK to exit", |         "press BACK to exit", | ||||||
|     }); |     }); | ||||||
|     wait_for_button(InputKeyBack); |     wait_for_button(InputKeyBack); | ||||||
|  | 
 | ||||||
|  |     furi_record_close("notification"); | ||||||
|     exit(); |     exit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -830,27 +834,18 @@ bool SdTest::ask(InputKey input_button_cancel, InputKey input_button_ok) { | |||||||
| 
 | 
 | ||||||
| // blink red led
 | // blink red led
 | ||||||
| void SdTest::blink_red() { | void SdTest::blink_red() { | ||||||
|     api_hal_light_set(LightRed, 0xFF); |     notification_message(notification, &sequence_blink_red_100); | ||||||
|     delay(50); |  | ||||||
|     api_hal_light_set(LightRed, 0x00); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // light up red led
 |  | ||||||
| void SdTest::set_red() { |  | ||||||
|     api_hal_light_set(LightRed, 0x00); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // blink green led
 | // blink green led
 | ||||||
| void SdTest::blink_green() { | void SdTest::blink_green() { | ||||||
|     api_hal_light_set(LightGreen, 0xFF); |     notification_message(notification, &sequence_blink_green_100); | ||||||
|     delay(50); |  | ||||||
|     api_hal_light_set(LightGreen, 0x00); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // set text, but with infinite loop
 | // set text, but with infinite loop
 | ||||||
| template <class T> void SdTest::set_error(std::initializer_list<T> list) { | template <class T> void SdTest::set_error(std::initializer_list<T> list) { | ||||||
|     set_text(list); |     set_text(list); | ||||||
|     set_red(); |     blink_red(); | ||||||
|     wait_for_button(InputKeyBack); |     wait_for_button(InputKeyBack); | ||||||
|     exit(); |     exit(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -206,41 +206,85 @@ void app_sd_format_internal(SdApp* sd_app) { | |||||||
|     _fs_unlock(&sd_app->info); |     _fs_unlock(&sd_app->info); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void app_sd_notify_wait_on() { | const NotificationSequence sd_sequence_success = { | ||||||
|     api_hal_light_set(LightRed, 0xFF); |     &message_green_255, | ||||||
|     api_hal_light_set(LightBlue, 0xFF); |     &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() { | void app_sd_notify_wait_off(SdApp* sd_app) { | ||||||
|     api_hal_light_set(LightRed, 0x00); |     notification_message(sd_app->notifications, &sd_sequence_wait_off); | ||||||
|     api_hal_light_set(LightBlue, 0x00); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void app_sd_notify_success() { | void app_sd_notify_success(SdApp* sd_app) { | ||||||
|     for(uint8_t i = 0; i < 3; i++) { |     notification_message(sd_app->notifications, &sd_sequence_success); | ||||||
|         delay(50); |  | ||||||
|         api_hal_light_set(LightGreen, 0xFF); |  | ||||||
|         delay(50); |  | ||||||
|         api_hal_light_set(LightGreen, 0x00); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void app_sd_notify_eject() { | void app_sd_notify_eject(SdApp* sd_app) { | ||||||
|     for(uint8_t i = 0; i < 3; i++) { |     notification_message(sd_app->notifications, &sd_sequence_eject); | ||||||
|         delay(50); |  | ||||||
|         api_hal_light_set(LightBlue, 0xFF); |  | ||||||
|         delay(50); |  | ||||||
|         api_hal_light_set(LightBlue, 0x00); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void app_sd_notify_error() { | void app_sd_notify_error(SdApp* sd_app) { | ||||||
|     for(uint8_t i = 0; i < 3; i++) { |     notification_message(sd_app->notifications, &sd_sequence_error); | ||||||
|         delay(50); |  | ||||||
|         api_hal_light_set(LightRed, 0xFF); |  | ||||||
|         delay(50); |  | ||||||
|         api_hal_light_set(LightRed, 0x00); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool app_sd_mount_card(SdApp* sd_app) { | 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); |     _fs_lock(&sd_app->info); | ||||||
| 
 | 
 | ||||||
|     while(result == false && counter > 0 && hal_sd_detect()) { |     while(result == false && counter > 0 && hal_sd_detect()) { | ||||||
|         app_sd_notify_wait_on(); |         app_sd_notify_wait(sd_app); | ||||||
| 
 | 
 | ||||||
|         if((counter % 10) == 0) { |         if((counter % 10) == 0) { | ||||||
|             // power reset sd card
 |             // 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) { |         if(!result) { | ||||||
|             delay(1000); |             delay(1000); | ||||||
| @ -586,6 +630,7 @@ int32_t sd_filesystem(void* p) { | |||||||
| 
 | 
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|     Cli* cli = furi_record_open("cli"); |     Cli* cli = furi_record_open("cli"); | ||||||
|  |     sd_app->notifications = furi_record_open("notification"); | ||||||
|     ValueMutex* menu_vm = furi_record_open("menu"); |     ValueMutex* menu_vm = furi_record_open("menu"); | ||||||
| 
 | 
 | ||||||
|     gui_add_view_port(gui, sd_app->icon.view_port, GuiLayerStatusBarLeft); |     gui_add_view_port(gui, sd_app->icon.view_port, GuiLayerStatusBarLeft); | ||||||
| @ -637,10 +682,10 @@ int32_t sd_filesystem(void* p) { | |||||||
|                         "SD FILESYSTEM", |                         "SD FILESYSTEM", | ||||||
|                         "sd init error: %s", |                         "sd init error: %s", | ||||||
|                         fs_error_get_internal_desc(sd_app->info.status)); |                         fs_error_get_internal_desc(sd_app->info.status)); | ||||||
|                     app_sd_notify_error(); |                     app_sd_notify_error(sd_app); | ||||||
|                 } else { |                 } else { | ||||||
|                     FURI_LOG_I("SD FILESYSTEM", "sd init ok"); |                     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); |                 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); |                 view_port_enabled_set(sd_app->icon.view_port, false); | ||||||
|                 app_sd_unmount_card(sd_app); |                 app_sd_unmount_card(sd_app); | ||||||
|                 sd_was_present = true; |                 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; |                     sd_app->sd_app_state = SdAppStateFormatInProgress; | ||||||
|                     delay(100); |                     delay(100); | ||||||
|                     app_sd_format_internal(sd_app); |                     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_left_button_text(dialog, "Back"); | ||||||
|                     dialog_ex_set_header( |                     dialog_ex_set_header( | ||||||
|                         dialog, "SD card formatted", 64, 10, AlignCenter, AlignCenter); |                         dialog, "SD card formatted", 64, 10, AlignCenter, AlignCenter); | ||||||
| @ -708,7 +753,7 @@ int32_t sd_filesystem(void* p) { | |||||||
|                         AlignCenter); |                         AlignCenter); | ||||||
|                     sd_app->sd_app_state = SdAppStateEjected; |                     sd_app->sd_app_state = SdAppStateEjected; | ||||||
|                     app_sd_unmount_card(sd_app); |                     app_sd_unmount_card(sd_app); | ||||||
|                     app_sd_notify_eject(); |                     app_sd_notify_eject(sd_app); | ||||||
|                 }; break; |                 }; break; | ||||||
|                 case SdAppStateFileSelect: { |                 case SdAppStateFileSelect: { | ||||||
|                     SdAppFileSelectResultEvent retval = {.result = true}; |                     SdAppFileSelectResultEvent retval = {.result = true}; | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ | |||||||
| #include <m-string.h> | #include <m-string.h> | ||||||
| #include "sd-card-api.h" | #include "sd-card-api.h" | ||||||
| #include "view_holder.h" | #include "view_holder.h" | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| #define SD_FS_MAX_FILES _FS_LOCK | #define SD_FS_MAX_FILES _FS_LOCK | ||||||
| #define SD_STATE_LINES_COUNT 6 | #define SD_STATE_LINES_COUNT 6 | ||||||
| @ -100,6 +101,8 @@ struct SdApp { | |||||||
| 
 | 
 | ||||||
|     osMessageQueueId_t event_queue; |     osMessageQueueId_t event_queue; | ||||||
|     string_t text_holder; |     string_t text_holder; | ||||||
|  | 
 | ||||||
|  |     NotificationApp* notifications; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* core api fns */ | /* core api fns */ | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| static const uint8_t subghz_static_keys[][4] = { | static const uint8_t subghz_static_keys[][4] = { | ||||||
|     {0x74, 0xBA, 0xDE}, |     {0x74, 0xBA, 0xDE}, | ||||||
| @ -105,7 +106,8 @@ bool subghz_static_input(InputEvent* event, void* context) { | |||||||
|                 if(event->type == InputTypePress) { |                 if(event->type == InputTypePress) { | ||||||
|                     const uint8_t* key = subghz_static_keys[model->button]; |                     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(); |                     __disable_irq(); | ||||||
|                     for(uint8_t r = 0; r < 20; r++) { |                     for(uint8_t r = 0; r < 20; r++) { | ||||||
|                         //Payload
 |                         //Payload
 | ||||||
| @ -127,7 +129,8 @@ bool subghz_static_input(InputEvent* event, void* context) { | |||||||
|                         delay_us(10600); |                         delay_us(10600); | ||||||
|                     } |                     } | ||||||
|                     __enable_irq(); |                     __enable_irq(); | ||||||
|                     api_hal_light_set(LightRed, 0x00); |                     notification_message(notification, &sequence_reset_red); | ||||||
|  |                     furi_record_close("notification"); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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}; | 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[] = { | const IrdaMessage test_nec_expected1[] = { | ||||||
|     {IrdaProtocolNEC,     0,      0,  false}, |     {IrdaProtocolNEC,     0xFF00,      0,  false}, | ||||||
|     {IrdaProtocolNEC,     0,      0,  true}, |     {IrdaProtocolNEC,     0xFF00,      0,  true}, | ||||||
|     {IrdaProtocolNEC,     0,      0,  false}, |     {IrdaProtocolNEC,     0xFF00,      0,  false}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const uint32_t test_nec_input2[] = { | const uint32_t test_nec_input2[] = { | ||||||
| @ -124,57 +124,57 @@ const uint32_t test_nec_input2[] = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const IrdaMessage test_nec_expected2[] = { | const IrdaMessage test_nec_expected2[] = { | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x02,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x02,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x06,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x06,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x06,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x06,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x04,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x04,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x04,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x04,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x09,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x09,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x09,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x09,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x09,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x09,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x0A,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x0A,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   true}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x0A,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x0A,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x08,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x08,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x0A,   false}, |     {IrdaProtocolNEC,     0xFF00,      0x0A,   false}, | ||||||
|     {IrdaProtocolNEC,     0,      0x0A,   true}, |     {IrdaProtocolNEC,     0xFF00,      0x0A,   true}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include "minunit_vars.h" | #include "minunit_vars.h" | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| int run_minunit(); | int run_minunit(); | ||||||
| int run_minunit_test_irda_decoder(); | int run_minunit_test_irda_decoder(); | ||||||
| @ -9,28 +10,24 @@ int run_minunit_test_irda_decoder(); | |||||||
| int32_t flipper_test_app(void* p) { | int32_t flipper_test_app(void* p) { | ||||||
|     uint32_t test_result = 0; |     uint32_t test_result = 0; | ||||||
| 
 | 
 | ||||||
|     api_hal_light_set(LightRed, 0x00); |     NotificationApp* notification = furi_record_open("notification"); | ||||||
|     api_hal_light_set(LightGreen, 0x00); | 
 | ||||||
|     api_hal_light_set(LightBlue, 0xFF); |     notification_message_block(notification, &sequence_set_only_blue_255); | ||||||
| 
 | 
 | ||||||
|     test_result |= run_minunit(); |     test_result |= run_minunit(); | ||||||
|     test_result |= run_minunit_test_irda_decoder(); |     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) { |     if(test_result == 0) { | ||||||
|         // test passed
 |         // test passed
 | ||||||
|             api_hal_light_set(LightRed, 0x00); |         notification_message(notification, &sequence_success); | ||||||
|             api_hal_light_set(LightGreen, 0xFF); |         notification_message(notification, &sequence_set_only_green_255); | ||||||
|             api_hal_light_set(LightBlue, 0x00); |  | ||||||
|     } else { |     } else { | ||||||
|         // test failed
 |         // test failed
 | ||||||
|             api_hal_light_set(LightRed, 0xFF); |         notification_message(notification, &sequence_error); | ||||||
|             api_hal_light_set(LightGreen, 0x00); |         notification_message(notification, &sequence_set_only_red_255); | ||||||
|             api_hal_light_set(LightBlue, 0x00); |  | ||||||
|         } |  | ||||||
|         delay(1); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     furi_record_close("notification"); | ||||||
|  | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -29,11 +29,6 @@ void platformUnprotectST25RComm(); | |||||||
| #define ST25R_INT_PIN NFC_IRQ_Pin | #define ST25R_INT_PIN NFC_IRQ_Pin | ||||||
| #define ST25R_INT_PORT NFC_IRQ_GPIO_Port | #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_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_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                        */ | #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 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 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 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 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                      */ | #define platformGpioToogle( port, pin )             HAL_GPIO_TogglePin(port, pin)                       /*!< Toogles the given GPIO                      */ | ||||||
|  | |||||||
| @ -3,11 +3,9 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include "../irda_i.h" | #include "../irda_i.h" | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static bool interpret_nec(IrdaCommonDecoder* decoder); | static bool interpret_nec(IrdaCommonDecoder* decoder); | ||||||
| static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder); | static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static const IrdaCommonProtocolSpec protocol_nec = { | static const IrdaCommonProtocolSpec protocol_nec = { | ||||||
|     { |     { | ||||||
|         IRDA_NEC_PREAMBULE_MARK, |         IRDA_NEC_PREAMBULE_MARK, | ||||||
| @ -25,17 +23,15 @@ static const IrdaCommonProtocolSpec protocol_nec = { | |||||||
|     decode_repeat_nec, |     decode_repeat_nec, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| static bool interpret_nec(IrdaCommonDecoder* decoder) { | static bool interpret_nec(IrdaCommonDecoder* decoder) { | ||||||
|     furi_assert(decoder); |     furi_assert(decoder); | ||||||
| 
 | 
 | ||||||
|     bool result = false; |     bool result = false; | ||||||
|     uint8_t address = decoder->data[0]; |     uint16_t address = decoder->data[0] | (decoder->data[1] << 8); | ||||||
|     uint8_t address_inverse = decoder->data[1]; |  | ||||||
|     uint8_t command = decoder->data[2]; |     uint8_t command = decoder->data[2]; | ||||||
|     uint8_t command_inverse = decoder->data[3]; |     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.command = command; | ||||||
|         decoder->message.address = address; |         decoder->message.address = address; | ||||||
|         decoder->message.repeat = false; |         decoder->message.repeat = false; | ||||||
| @ -53,14 +49,13 @@ static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder) { | |||||||
|     uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; |     uint32_t bit_tolerance = decoder->protocol->timings.bit_tolerance; | ||||||
|     DecodeStatus status = DecodeStatusError; |     DecodeStatus status = DecodeStatusError; | ||||||
| 
 | 
 | ||||||
|     if (decoder->timings_cnt < 4) |     if(decoder->timings_cnt < 4) return DecodeStatusOk; | ||||||
|         return DecodeStatusOk; |  | ||||||
| 
 | 
 | ||||||
|     if ((decoder->timings[0] > IRDA_NEC_REPEAT_PAUSE_MIN) |     if((decoder->timings[0] > IRDA_NEC_REPEAT_PAUSE_MIN) && | ||||||
|         && (decoder->timings[0] < IRDA_NEC_REPEAT_PAUSE_MAX) |        (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[1], IRDA_NEC_REPEAT_MARK, preamble_tolerance) && | ||||||
|         && MATCH_PREAMBLE_TIMING(decoder->timings[2], IRDA_NEC_REPEAT_SPACE, 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)) { |        MATCH_BIT_TIMING(decoder->timings[3], decoder->protocol->timings.bit1_mark, bit_tolerance)) { | ||||||
|         status = DecodeStatusReady; |         status = DecodeStatusReady; | ||||||
|         decoder->timings_cnt = 0; |         decoder->timings_cnt = 0; | ||||||
|     } else { |     } else { | ||||||
| @ -81,4 +76,3 @@ IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duratio | |||||||
| void irda_decoder_nec_free(void* decoder) { | void irda_decoder_nec_free(void* decoder) { | ||||||
|     irda_common_decoder_free(decoder); |     irda_common_decoder_free(decoder); | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG