Hardware LED blinking (#1303)
* Hardware LED blinking notification messages * Blink: fix crash on exit, reset blinking on exit * Lib: remove unused UNUSED Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									41cf421234
								
							
						
					
					
						commit
						cfb1a0d01c
					
				| @ -1,3 +1,4 @@ | |||||||
|  | #include "furi/common_defines.h" | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <furi_hal.h> | #include <furi_hal.h> | ||||||
| 
 | 
 | ||||||
| @ -6,8 +7,6 @@ | |||||||
| 
 | 
 | ||||||
| #include <notification/notification_messages.h> | #include <notification/notification_messages.h> | ||||||
| 
 | 
 | ||||||
| #define BLINK_COLOR_COUNT 7 |  | ||||||
| 
 |  | ||||||
| typedef enum { | typedef enum { | ||||||
|     BlinkEventTypeTick, |     BlinkEventTypeTick, | ||||||
|     BlinkEventTypeInput, |     BlinkEventTypeInput, | ||||||
| @ -18,6 +17,42 @@ typedef struct { | |||||||
|     InputEvent input; |     InputEvent input; | ||||||
| } BlinkEvent; | } BlinkEvent; | ||||||
| 
 | 
 | ||||||
|  | static const NotificationSequence blink_test_sequence_hw_blink_start_red = { | ||||||
|  |     &message_blink_start_10, | ||||||
|  |     &message_blink_set_color_red, | ||||||
|  |     &message_do_not_reset, | ||||||
|  |     NULL, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const NotificationSequence blink_test_sequence_hw_blink_green = { | ||||||
|  |     &message_blink_set_color_green, | ||||||
|  |     NULL, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const NotificationSequence blink_test_sequence_hw_blink_blue = { | ||||||
|  |     &message_blink_set_color_blue, | ||||||
|  |     NULL, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const NotificationSequence blink_test_sequence_hw_blink_stop = { | ||||||
|  |     &message_blink_stop, | ||||||
|  |     NULL, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const NotificationSequence* blink_test_colors[] = { | ||||||
|  |     &sequence_blink_red_100, | ||||||
|  |     &sequence_blink_green_100, | ||||||
|  |     &sequence_blink_blue_100, | ||||||
|  |     &sequence_blink_yellow_100, | ||||||
|  |     &sequence_blink_cyan_100, | ||||||
|  |     &sequence_blink_magenta_100, | ||||||
|  |     &sequence_blink_white_100, | ||||||
|  |     &blink_test_sequence_hw_blink_start_red, | ||||||
|  |     &blink_test_sequence_hw_blink_green, | ||||||
|  |     &blink_test_sequence_hw_blink_blue, | ||||||
|  |     &blink_test_sequence_hw_blink_stop, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static void blink_test_update(void* ctx) { | static void blink_test_update(void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     osMessageQueueId_t event_queue = ctx; | ||||||
| @ -58,16 +93,6 @@ int32_t blink_test_app(void* p) { | |||||||
| 
 | 
 | ||||||
|     NotificationApp* notifications = furi_record_open("notification"); |     NotificationApp* notifications = furi_record_open("notification"); | ||||||
| 
 | 
 | ||||||
|     const NotificationSequence* colors[BLINK_COLOR_COUNT] = { |  | ||||||
|         &sequence_blink_red_100, |  | ||||||
|         &sequence_blink_green_100, |  | ||||||
|         &sequence_blink_blue_100, |  | ||||||
|         &sequence_blink_yellow_100, |  | ||||||
|         &sequence_blink_cyan_100, |  | ||||||
|         &sequence_blink_magenta_100, |  | ||||||
|         &sequence_blink_white_100, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     uint8_t state = 0; |     uint8_t state = 0; | ||||||
|     BlinkEvent event; |     BlinkEvent event; | ||||||
| 
 | 
 | ||||||
| @ -78,14 +103,16 @@ int32_t blink_test_app(void* p) { | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             notification_message(notifications, colors[state]); |             notification_message(notifications, blink_test_colors[state]); | ||||||
|             state++; |             state++; | ||||||
|             if(state >= BLINK_COLOR_COUNT) { |             if(state >= COUNT_OF(blink_test_colors)) { | ||||||
|                 state = 0; |                 state = 0; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     notification_message(notifications, &blink_test_sequence_hw_blink_stop); | ||||||
|  | 
 | ||||||
|     osTimerDelete(timer); |     osTimerDelete(timer); | ||||||
| 
 | 
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include "stdint.h" | #include "stdint.h" | ||||||
| #include "stdbool.h" | #include "stdbool.h" | ||||||
|  | #include <furi_hal_resources.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| @ -30,9 +31,16 @@ typedef struct { | |||||||
|     float display_brightness; |     float display_brightness; | ||||||
| } NotificationMessageDataForcedSettings; | } NotificationMessageDataForcedSettings; | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint16_t on_time; | ||||||
|  |     uint16_t period; | ||||||
|  |     Light color; | ||||||
|  | } NotificationMessageDataLedBlink; | ||||||
|  | 
 | ||||||
| typedef union { | typedef union { | ||||||
|     NotificationMessageDataSound sound; |     NotificationMessageDataSound sound; | ||||||
|     NotificationMessageDataLed led; |     NotificationMessageDataLed led; | ||||||
|  |     NotificationMessageDataLedBlink led_blink; | ||||||
|     NotificationMessageDataVibro vibro; |     NotificationMessageDataVibro vibro; | ||||||
|     NotificationMessageDataDelay delay; |     NotificationMessageDataDelay delay; | ||||||
|     NotificationMessageDataForcedSettings forced_settings; |     NotificationMessageDataForcedSettings forced_settings; | ||||||
| @ -48,6 +56,10 @@ typedef enum { | |||||||
|     NotificationMessageTypeLedGreen, |     NotificationMessageTypeLedGreen, | ||||||
|     NotificationMessageTypeLedBlue, |     NotificationMessageTypeLedBlue, | ||||||
| 
 | 
 | ||||||
|  |     NotificationMessageTypeLedBlinkStart, | ||||||
|  |     NotificationMessageTypeLedBlinkStop, | ||||||
|  |     NotificationMessageTypeLedBlinkColor, | ||||||
|  | 
 | ||||||
|     NotificationMessageTypeDelay, |     NotificationMessageTypeDelay, | ||||||
| 
 | 
 | ||||||
|     NotificationMessageTypeLedDisplayBacklight, |     NotificationMessageTypeLedDisplayBacklight, | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | #include "furi_hal_light.h" | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <furi_hal.h> | #include <furi_hal.h> | ||||||
| #include <storage/storage.h> | #include <storage/storage.h> | ||||||
| @ -17,6 +18,7 @@ static const uint8_t reset_blue_mask = 1 << 2; | |||||||
| static const uint8_t reset_vibro_mask = 1 << 3; | static const uint8_t reset_vibro_mask = 1 << 3; | ||||||
| static const uint8_t reset_sound_mask = 1 << 4; | static const uint8_t reset_sound_mask = 1 << 4; | ||||||
| static const uint8_t reset_display_mask = 1 << 5; | static const uint8_t reset_display_mask = 1 << 5; | ||||||
|  | static const uint8_t reset_blink_mask = 1 << 6; | ||||||
| 
 | 
 | ||||||
| void notification_vibro_on(); | void notification_vibro_on(); | ||||||
| void notification_vibro_off(); | void notification_vibro_off(); | ||||||
| @ -100,6 +102,9 @@ void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_m | |||||||
|     if(reset_mask & reset_blue_mask) { |     if(reset_mask & reset_blue_mask) { | ||||||
|         notification_reset_notification_led_layer(&app->led[2]); |         notification_reset_notification_led_layer(&app->led[2]); | ||||||
|     } |     } | ||||||
|  |     if(reset_mask & reset_blink_mask) { | ||||||
|  |         furi_hal_light_blink_stop(); | ||||||
|  |     } | ||||||
|     if(reset_mask & reset_vibro_mask) { |     if(reset_mask & reset_vibro_mask) { | ||||||
|         notification_vibro_off(); |         notification_vibro_off(); | ||||||
|     } |     } | ||||||
| @ -229,6 +234,24 @@ void notification_process_notification_message( | |||||||
|             app->led[2].value_last[LayerNotification] = led_values[2]; |             app->led[2].value_last[LayerNotification] = led_values[2]; | ||||||
|             reset_mask |= reset_blue_mask; |             reset_mask |= reset_blue_mask; | ||||||
|             break; |             break; | ||||||
|  |         case NotificationMessageTypeLedBlinkStart: | ||||||
|  |             // store and send on delay or after seq
 | ||||||
|  |             led_active = true; | ||||||
|  |             furi_hal_light_blink_start( | ||||||
|  |                 notification_message->data.led_blink.color, | ||||||
|  |                 app->settings.led_brightness * 255, | ||||||
|  |                 notification_message->data.led_blink.on_time, | ||||||
|  |                 notification_message->data.led_blink.period); | ||||||
|  |             reset_mask |= reset_blink_mask; | ||||||
|  |             break; | ||||||
|  |         case NotificationMessageTypeLedBlinkColor: | ||||||
|  |             led_active = true; | ||||||
|  |             furi_hal_light_blink_set_color(notification_message->data.led_blink.color); | ||||||
|  |             break; | ||||||
|  |         case NotificationMessageTypeLedBlinkStop: | ||||||
|  |             furi_hal_light_blink_stop(); | ||||||
|  |             reset_mask &= ~reset_blink_mask; | ||||||
|  |             break; | ||||||
|         case NotificationMessageTypeVibro: |         case NotificationMessageTypeVibro: | ||||||
|             if(notification_message->data.vibro.on) { |             if(notification_message->data.vibro.on) { | ||||||
|                 if(vibro_setting) notification_vibro_on(); |                 if(vibro_setting) notification_vibro_on(); | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | #include "furi_hal_resources.h" | ||||||
| #include "notification.h" | #include "notification.h" | ||||||
| #include "notification_messages_notes.h" | #include "notification_messages_notes.h" | ||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| @ -60,6 +61,59 @@ const NotificationMessage message_blue_0 = { | |||||||
|     .data.led.value = 0x00, |     .data.led.value = 0x00, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const NotificationMessage message_blink_start_10 = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkStart, | ||||||
|  |     .data.led_blink.color = 0, | ||||||
|  |     .data.led_blink.on_time = 10, | ||||||
|  |     .data.led_blink.period = 100, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_start_100 = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkStart, | ||||||
|  |     .data.led_blink.color = 0, | ||||||
|  |     .data.led_blink.on_time = 100, | ||||||
|  |     .data.led_blink.period = 1000, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_stop = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkStop, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_red = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightRed, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_green = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightGreen, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_blue = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightBlue, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_cyan = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightBlue | LightGreen, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_magenta = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightBlue | LightRed, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_yellow = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightGreen | LightRed, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const NotificationMessage message_blink_set_color_white = { | ||||||
|  |     .type = NotificationMessageTypeLedBlinkColor, | ||||||
|  |     .data.led_blink.color = LightRed | LightGreen | LightBlue, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| // Delay
 | // Delay
 | ||||||
| const NotificationMessage message_delay_1 = { | const NotificationMessage message_delay_1 = { | ||||||
|     .type = NotificationMessageTypeDelay, |     .type = NotificationMessageTypeDelay, | ||||||
|  | |||||||
| @ -24,6 +24,19 @@ extern const NotificationMessage message_red_0; | |||||||
| extern const NotificationMessage message_green_0; | extern const NotificationMessage message_green_0; | ||||||
| extern const NotificationMessage message_blue_0; | extern const NotificationMessage message_blue_0; | ||||||
| 
 | 
 | ||||||
|  | // Led hardware blink control
 | ||||||
|  | extern const NotificationMessage message_blink_start_10; | ||||||
|  | extern const NotificationMessage message_blink_start_100; | ||||||
|  | extern const NotificationMessage message_blink_stop; | ||||||
|  | 
 | ||||||
|  | extern const NotificationMessage message_blink_set_color_red; | ||||||
|  | extern const NotificationMessage message_blink_set_color_green; | ||||||
|  | extern const NotificationMessage message_blink_set_color_blue; | ||||||
|  | extern const NotificationMessage message_blink_set_color_cyan; | ||||||
|  | extern const NotificationMessage message_blink_set_color_magenta; | ||||||
|  | extern const NotificationMessage message_blink_set_color_yellow; | ||||||
|  | extern const NotificationMessage message_blink_set_color_white; | ||||||
|  | 
 | ||||||
| // Delay
 | // Delay
 | ||||||
| extern const NotificationMessage message_delay_1; | extern const NotificationMessage message_delay_1; | ||||||
| extern const NotificationMessage message_delay_10; | extern const NotificationMessage message_delay_10; | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
|  | #include "furi/common_defines.h" | ||||||
|  | #include "furi_hal_resources.h" | ||||||
| #include <furi_hal_light.h> | #include <furi_hal_light.h> | ||||||
| #include <furi_hal_delay.h> | #include <furi_hal_delay.h> | ||||||
| #include <lp5562.h> | #include <lp5562.h> | ||||||
|  | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| #define LED_CURRENT_RED 50 | #define LED_CURRENT_RED 50 | ||||||
| #define LED_CURRENT_GREEN 50 | #define LED_CURRENT_GREEN 50 | ||||||
| @ -29,29 +32,63 @@ void furi_hal_light_init() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_hal_light_set(Light light, uint8_t value) { | void furi_hal_light_set(Light light, uint8_t value) { | ||||||
|     uint8_t prev = 0; |  | ||||||
|     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); |     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); | ||||||
|     switch(light) { |     if(light & LightRed) { | ||||||
|     case LightRed: |  | ||||||
|         lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); |         lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); | ||||||
|         break; |     } | ||||||
|     case LightGreen: |     if(light & LightGreen) { | ||||||
|         lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); |         lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); | ||||||
|         break; |     } | ||||||
|     case LightBlue: |     if(light & LightBlue) { | ||||||
|         lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); |         lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); | ||||||
|         break; |     } | ||||||
|     case LightBacklight: |     if(light & LightBacklight) { | ||||||
|         prev = lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite); |         uint8_t prev = lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite); | ||||||
|         lp5562_execute_ramp( |         lp5562_execute_ramp( | ||||||
|             &furi_hal_i2c_handle_power, LP5562Engine1, LP5562ChannelWhite, prev, value, 100); |             &furi_hal_i2c_handle_power, LP5562Engine1, LP5562ChannelWhite, prev, value, 100); | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         break; |  | ||||||
|     } |     } | ||||||
|     furi_hal_i2c_release(&furi_hal_i2c_handle_power); |     furi_hal_i2c_release(&furi_hal_i2c_handle_power); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void furi_hal_light_blink_start(Light light, uint8_t brightness, uint16_t on_time, uint16_t period) { | ||||||
|  |     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); | ||||||
|  |     lp5562_set_channel_src( | ||||||
|  |         &furi_hal_i2c_handle_power, | ||||||
|  |         LP5562ChannelRed | LP5562ChannelGreen | LP5562ChannelBlue, | ||||||
|  |         LP5562Direct); | ||||||
|  |     LP5562Channel led_ch = 0; | ||||||
|  |     if(light & LightRed) led_ch |= LP5562ChannelRed; | ||||||
|  |     if(light & LightGreen) led_ch |= LP5562ChannelGreen; | ||||||
|  |     if(light & LightBlue) led_ch |= LP5562ChannelBlue; | ||||||
|  |     lp5562_execute_blink( | ||||||
|  |         &furi_hal_i2c_handle_power, LP5562Engine2, led_ch, on_time, period, brightness); | ||||||
|  |     furi_hal_i2c_release(&furi_hal_i2c_handle_power); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void furi_hal_light_blink_stop() { | ||||||
|  |     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); | ||||||
|  |     lp5562_set_channel_src( | ||||||
|  |         &furi_hal_i2c_handle_power, | ||||||
|  |         LP5562ChannelRed | LP5562ChannelGreen | LP5562ChannelBlue, | ||||||
|  |         LP5562Direct); | ||||||
|  |     lp5562_stop_program(&furi_hal_i2c_handle_power, LP5562Engine2); | ||||||
|  |     furi_hal_i2c_release(&furi_hal_i2c_handle_power); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void furi_hal_light_blink_set_color(Light light) { | ||||||
|  |     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); | ||||||
|  |     LP5562Channel led_ch = 0; | ||||||
|  |     lp5562_set_channel_src( | ||||||
|  |         &furi_hal_i2c_handle_power, | ||||||
|  |         LP5562ChannelRed | LP5562ChannelGreen | LP5562ChannelBlue, | ||||||
|  |         LP5562Direct); | ||||||
|  |     if(light & LightRed) led_ch |= LP5562ChannelRed; | ||||||
|  |     if(light & LightGreen) led_ch |= LP5562ChannelGreen; | ||||||
|  |     if(light & LightBlue) led_ch |= LP5562ChannelBlue; | ||||||
|  |     lp5562_set_channel_src(&furi_hal_i2c_handle_power, led_ch, LP5562Engine2); | ||||||
|  |     furi_hal_i2c_release(&furi_hal_i2c_handle_power); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void furi_hal_light_sequence(const char* sequence) { | void furi_hal_light_sequence(const char* sequence) { | ||||||
|     do { |     do { | ||||||
|         if(*sequence == 'R') { |         if(*sequence == 'R') { | ||||||
|  | |||||||
| @ -24,10 +24,10 @@ typedef enum { | |||||||
| 
 | 
 | ||||||
| /* Light */ | /* Light */ | ||||||
| typedef enum { | typedef enum { | ||||||
|     LightRed, |     LightRed = (1 << 0), | ||||||
|     LightGreen, |     LightGreen = (1 << 1), | ||||||
|     LightBlue, |     LightBlue = (1 << 2), | ||||||
|     LightBacklight, |     LightBacklight = (1 << 3), | ||||||
| } Light; | } Light; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  | |||||||
| @ -24,6 +24,25 @@ void furi_hal_light_init(); | |||||||
|  */ |  */ | ||||||
| void furi_hal_light_set(Light light, uint8_t value); | void furi_hal_light_set(Light light, uint8_t value); | ||||||
| 
 | 
 | ||||||
|  | /** Start hardware LED blinking mode
 | ||||||
|  |  * | ||||||
|  |  * @param      light  Light | ||||||
|  |  * @param      brightness  light brightness [0-255] | ||||||
|  |  * @param      on_time  LED on time in ms | ||||||
|  |  * @param      period  LED blink period in ms | ||||||
|  |  */ | ||||||
|  | void furi_hal_light_blink_start(Light light, uint8_t brightness, uint16_t on_time, uint16_t period); | ||||||
|  | 
 | ||||||
|  | /** Stop hardware LED blinking mode
 | ||||||
|  |  */ | ||||||
|  | void furi_hal_light_blink_stop(); | ||||||
|  | 
 | ||||||
|  | /** Set color in hardware LED blinking mode
 | ||||||
|  |  * | ||||||
|  |  * @param      light  Light | ||||||
|  |  */ | ||||||
|  | void furi_hal_light_blink_set_color(Light light); | ||||||
|  | 
 | ||||||
| /** Execute sequence
 | /** Execute sequence
 | ||||||
|  * |  * | ||||||
|  * @param      sequence  Sequence to execute |  * @param      sequence  Sequence to execute | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "lp5562.h" | #include "lp5562.h" | ||||||
|  | #include "furi/common_defines.h" | ||||||
| #include "lp5562_reg.h" | #include "lp5562_reg.h" | ||||||
| #include <furi_hal.h> | #include <furi_hal.h> | ||||||
| 
 | 
 | ||||||
| @ -79,19 +80,23 @@ uint8_t lp5562_get_channel_value(FuriHalI2cBusHandle* handle, LP5562Channel chan | |||||||
|     return value; |     return value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | void lp5562_set_channel_src(FuriHalI2cBusHandle* handle, LP5562Channel channel, LP5562Engine src) { | ||||||
|     lp5562_set_channel_src(FuriHalI2cBusHandle* handle, LP5562Channel channel, LP5562Engine src) { |  | ||||||
|     uint8_t reg_val = 0; |     uint8_t reg_val = 0; | ||||||
|     uint8_t bit_offset = 0; |     uint8_t bit_offset = 0; | ||||||
| 
 | 
 | ||||||
|     if(channel == LP5562ChannelRed) { |     do { | ||||||
|  |         if(channel & LP5562ChannelRed) { | ||||||
|             bit_offset = 4; |             bit_offset = 4; | ||||||
|     } else if(channel == LP5562ChannelGreen) { |             channel &= ~LP5562ChannelRed; | ||||||
|  |         } else if(channel & LP5562ChannelGreen) { | ||||||
|             bit_offset = 2; |             bit_offset = 2; | ||||||
|     } else if(channel == LP5562ChannelBlue) { |             channel &= ~LP5562ChannelGreen; | ||||||
|  |         } else if(channel & LP5562ChannelBlue) { | ||||||
|             bit_offset = 0; |             bit_offset = 0; | ||||||
|     } else if(channel == LP5562ChannelWhite) { |             channel &= ~LP5562ChannelBlue; | ||||||
|  |         } else if(channel & LP5562ChannelWhite) { | ||||||
|             bit_offset = 6; |             bit_offset = 6; | ||||||
|  |             channel &= ~LP5562ChannelWhite; | ||||||
|         } else { |         } else { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @ -100,6 +105,7 @@ static void | |||||||
|         reg_val &= ~(0x3 << bit_offset); |         reg_val &= ~(0x3 << bit_offset); | ||||||
|         reg_val |= ((src & 0x03) << bit_offset); |         reg_val |= ((src & 0x03) << bit_offset); | ||||||
|         furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x70, reg_val, LP5562_I2C_TIMEOUT); |         furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x70, reg_val, LP5562_I2C_TIMEOUT); | ||||||
|  |     } while(channel); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void lp5562_execute_program( | void lp5562_execute_program( | ||||||
| @ -151,6 +157,19 @@ void lp5562_execute_program( | |||||||
|     furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x00, enable_reg, LP5562_I2C_TIMEOUT); |     furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x00, enable_reg, LP5562_I2C_TIMEOUT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void lp5562_stop_program(FuriHalI2cBusHandle* handle, LP5562Engine eng) { | ||||||
|  |     if((eng < LP5562Engine1) || (eng > LP5562Engine3)) return; | ||||||
|  |     uint8_t reg_val = 0; | ||||||
|  |     uint8_t bit_offset = 0; | ||||||
|  | 
 | ||||||
|  |     // Engine configuration
 | ||||||
|  |     bit_offset = (3 - eng) * 2; | ||||||
|  |     furi_hal_i2c_read_reg_8(handle, LP5562_ADDRESS, 0x01, ®_val, LP5562_I2C_TIMEOUT); | ||||||
|  |     reg_val &= ~(0x3 << bit_offset); | ||||||
|  |     reg_val |= (0x00 << bit_offset); // Disabled
 | ||||||
|  |     furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x01, reg_val, LP5562_I2C_TIMEOUT); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void lp5562_execute_ramp( | void lp5562_execute_ramp( | ||||||
|     FuriHalI2cBusHandle* handle, |     FuriHalI2cBusHandle* handle, | ||||||
|     LP5562Engine eng, |     LP5562Engine eng, | ||||||
| @ -194,3 +213,54 @@ void lp5562_execute_ramp( | |||||||
|     // Write end value to register
 |     // Write end value to register
 | ||||||
|     lp5562_set_channel_value(handle, ch, val_end); |     lp5562_set_channel_value(handle, ch, val_end); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void lp5562_execute_blink( | ||||||
|  |     FuriHalI2cBusHandle* handle, | ||||||
|  |     LP5562Engine eng, | ||||||
|  |     LP5562Channel ch, | ||||||
|  |     uint16_t on_time, | ||||||
|  |     uint16_t period, | ||||||
|  |     uint8_t brightness) { | ||||||
|  |     // Temporary switch to constant value from register
 | ||||||
|  |     lp5562_set_channel_src(handle, ch, LP5562Direct); | ||||||
|  | 
 | ||||||
|  |     // Prepare command sequence
 | ||||||
|  |     uint16_t program[16]; | ||||||
|  |     uint16_t time_step = 0; | ||||||
|  |     uint8_t prescaller = 0; | ||||||
|  | 
 | ||||||
|  |     program[0] = 0x4000 | brightness; // Set PWM
 | ||||||
|  | 
 | ||||||
|  |     time_step = on_time * 2; | ||||||
|  |     if(time_step > 0x3F) { | ||||||
|  |         time_step /= 32; | ||||||
|  |         prescaller = 1; | ||||||
|  |     } else { | ||||||
|  |         prescaller = 0; | ||||||
|  |     } | ||||||
|  |     if(time_step == 0) { | ||||||
|  |         time_step = 1; | ||||||
|  |     } else if(time_step > 0x3F) | ||||||
|  |         time_step = 0x3F; | ||||||
|  |     program[1] = (prescaller << 14) | (time_step << 8); // Delay
 | ||||||
|  | 
 | ||||||
|  |     program[2] = 0x4000 | 0; // Set PWM
 | ||||||
|  | 
 | ||||||
|  |     time_step = (period - on_time) * 2; | ||||||
|  |     if(time_step > 0x3F) { | ||||||
|  |         time_step /= 32; | ||||||
|  |         prescaller = 1; | ||||||
|  |     } else { | ||||||
|  |         prescaller = 0; | ||||||
|  |     } | ||||||
|  |     if(time_step == 0) { | ||||||
|  |         time_step = 1; | ||||||
|  |     } else if(time_step > 0x3F) | ||||||
|  |         time_step = 0x3F; | ||||||
|  |     program[3] = (prescaller << 14) | (time_step << 8); // Delay
 | ||||||
|  | 
 | ||||||
|  |     program[4] = 0x0000; // Go to start
 | ||||||
|  | 
 | ||||||
|  |     // Execute program
 | ||||||
|  |     lp5562_execute_program(handle, eng, ch, program); | ||||||
|  | } | ||||||
|  | |||||||
| @ -6,10 +6,10 @@ | |||||||
| 
 | 
 | ||||||
| /** Channel types */ | /** Channel types */ | ||||||
| typedef enum { | typedef enum { | ||||||
|     LP5562ChannelRed, |     LP5562ChannelRed = (1 << 0), | ||||||
|     LP5562ChannelGreen, |     LP5562ChannelGreen = (1 << 1), | ||||||
|     LP5562ChannelBlue, |     LP5562ChannelBlue = (1 << 2), | ||||||
|     LP5562ChannelWhite, |     LP5562ChannelWhite = (1 << 3), | ||||||
| } LP5562Channel; | } LP5562Channel; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| @ -37,6 +37,9 @@ void lp5562_set_channel_value(FuriHalI2cBusHandle* handle, LP5562Channel channel | |||||||
| /** Get channel PWM value */ | /** Get channel PWM value */ | ||||||
| uint8_t lp5562_get_channel_value(FuriHalI2cBusHandle* handle, LP5562Channel channel); | uint8_t lp5562_get_channel_value(FuriHalI2cBusHandle* handle, LP5562Channel channel); | ||||||
| 
 | 
 | ||||||
|  | /** Set channel source */ | ||||||
|  | void lp5562_set_channel_src(FuriHalI2cBusHandle* handle, LP5562Channel channel, LP5562Engine src); | ||||||
|  | 
 | ||||||
| /** Execute program sequence */ | /** Execute program sequence */ | ||||||
| void lp5562_execute_program( | void lp5562_execute_program( | ||||||
|     FuriHalI2cBusHandle* handle, |     FuriHalI2cBusHandle* handle, | ||||||
| @ -44,6 +47,9 @@ void lp5562_execute_program( | |||||||
|     LP5562Channel ch, |     LP5562Channel ch, | ||||||
|     uint16_t* program); |     uint16_t* program); | ||||||
| 
 | 
 | ||||||
|  | /** Stop program sequence */ | ||||||
|  | void lp5562_stop_program(FuriHalI2cBusHandle* handle, LP5562Engine eng); | ||||||
|  | 
 | ||||||
| /** Execute ramp program sequence */ | /** Execute ramp program sequence */ | ||||||
| void lp5562_execute_ramp( | void lp5562_execute_ramp( | ||||||
|     FuriHalI2cBusHandle* handle, |     FuriHalI2cBusHandle* handle, | ||||||
| @ -52,3 +58,12 @@ void lp5562_execute_ramp( | |||||||
|     uint8_t val_start, |     uint8_t val_start, | ||||||
|     uint8_t val_end, |     uint8_t val_end, | ||||||
|     uint16_t time); |     uint16_t time); | ||||||
|  | 
 | ||||||
|  | /** Start blink program sequence */ | ||||||
|  | void lp5562_execute_blink( | ||||||
|  |     FuriHalI2cBusHandle* handle, | ||||||
|  |     LP5562Engine eng, | ||||||
|  |     LP5562Channel ch, | ||||||
|  |     uint16_t on_time, | ||||||
|  |     uint16_t period, | ||||||
|  |     uint8_t brightness); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikolay Minaylov
						Nikolay Minaylov