diff --git a/CHANGELOG.md b/CHANGELOG.md index f37e582ea..c896911bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,29 @@ ### Added: -- Nothing +- Apps: + - Games: Pinball0 (by @rdefeo) + - NFC: Metroflip (by @luu176) ### Updated: - Apps: - - FlipLibrary: Added dog facts and random quotes, bug fixes (by @jblanked), connectivity and progress improvements (by @jamisonderek) + - BT/USB Remote: Add PTT support for Gather (by @SapphicCode) + - ESP Flasher: Add c3 and c6 to s3 option (by @jaylikesbunda) + - FlipLibrary: Added Wikipedia, dog facts and random quotes, bug fixes (by @jblanked), connectivity and progress improvements (by @jamisonderek) - FlipSocial: Improved authentication (by @jblanked) - FlipStore: Many bugfixes, support ESP32 firmware downloads, allow deleting apps (by @jblanked) - - FlipWeather: Stability improvements (by @jblanked) - - FlipWiFi: Improved error handling (by @jblanked) + - FlipTrader: Improved progress display, added connectivity check on startup (by @jamisonderek) + - FlipWeather: Stability improvements (by @jblanked), improved progress display, added connectivity check on startup (by @jamisonderek) + - FlipWiFi: Improved error handling, updated scan loading and parsing (by @jblanked), added connectivity check on startup (by @jamisonderek) - FlipBIP: Refactor to make adding coins easier (by @xtruan) - uPython: Enabled extra functions for the `random` module (by @ofabel) - Pokemon Trade Tool: Update to gblink v0.63 which includes saving/loading of pin configurations for the EXT link interface (by @kbembedded) - Snake 2.0: Progress saving, endless mode, game timer, fruit positioning bugfixes (by @Willzvul) + - WebCrawler: Improved progress display, added connectivity check on startup (by @jamisonderek) - UL: NFC Magic: Added possibility to write 7b MFC to Gen1 tags (by @mishamyte) + - UL: Fixed apps for firmware USB CDC callback changes (by @xMasterX) ### Fixed: -- Nothing +- Desktop: Fixed Wardriving animation design (by @Davim09) +- OFW: GPIO: Merged gsurkov/vcp_break_support branch for usb uart bridge (WIP!!!) ### Removed: - Nothing diff --git a/SConstruct b/SConstruct index 722713a28..7f9fef8ba 100644 --- a/SConstruct +++ b/SConstruct @@ -346,6 +346,8 @@ black_commandline = [ black_base_args = [ "--include", '"(\\.scons|\\.py|SConscript|SConstruct|\\.fam)$"', + "--exclude", + '"(mp_flipper/flipperzero/random\\.py)$"', ] distenv.PhonyTarget( diff --git a/applications/external b/applications/external index f09acb4b3..1163b5839 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit f09acb4b3ae13a8a43f38a042483836776b37ebb +Subproject commit 1163b5839883072526c029f9f636507b7f318f14 diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index f6e68b109..0d2c63b3c 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -35,12 +35,12 @@ typedef enum { WorkerEvtLineCfgSet = (1 << 6), WorkerEvtCtrlLineSet = (1 << 7), - + WorkerEvtSendBreak = (1 << 8), } WorkerEvtFlags; #define WORKER_ALL_RX_EVENTS \ (WorkerEvtStop | WorkerEvtRxDone | WorkerEvtCfgChange | WorkerEvtLineCfgSet | \ - WorkerEvtCtrlLineSet | WorkerEvtCdcTxComplete) + WorkerEvtCtrlLineSet | WorkerEvtCdcTxComplete | WorkerEvtSendBreak) #define WORKER_ALL_TX_EVENTS (WorkerEvtTxStop | WorkerEvtCdcRx) struct UsbUartBridge { @@ -69,6 +69,7 @@ static void vcp_on_cdc_rx(void* context); static void vcp_state_callback(void* context, uint8_t state); static void vcp_on_cdc_control_line(void* context, uint8_t state); static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config); +static void vcp_on_cdc_break(void* context, uint16_t duration); static const CdcCallbacks cdc_cb = { vcp_on_cdc_tx_complete, @@ -76,6 +77,7 @@ static const CdcCallbacks cdc_cb = { vcp_state_callback, vcp_on_cdc_control_line, vcp_on_line_config, + vcp_on_cdc_break, }; /* USB UART worker */ @@ -287,6 +289,9 @@ static int32_t usb_uart_worker(void* context) { if(events & WorkerEvtCtrlLineSet) { usb_uart_update_ctrl_lines(usb_uart); } + if(events & WorkerEvtSendBreak) { + furi_hal_serial_send_break(usb_uart->serial_handle); + } } usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); usb_uart_serial_deinit(usb_uart); @@ -377,6 +382,12 @@ static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtLineCfgSet); } +static void vcp_on_cdc_break(void* context, uint16_t duration) { + UNUSED(duration); + UsbUartBridge* usb_uart = (UsbUartBridge*)context; + furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtSendBreak); +} + UsbUartBridge* usb_uart_enable(UsbUartConfig* cfg) { UsbUartBridge* usb_uart = malloc(sizeof(UsbUartBridge)); diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index cdabaaa05..83f4f8214 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -57,6 +57,7 @@ static CdcCallbacks cdc_cb = { vcp_state_callback, vcp_on_cdc_control_line, NULL, + NULL, }; static CliVcp* vcp = NULL; diff --git a/applications/system/hid_app/views/hid_ptt.c b/applications/system/hid_app/views/hid_ptt.c index 59643abac..58599eb51 100644 --- a/applications/system/hid_app/views/hid_ptt.c +++ b/applications/system/hid_app/views/hid_ptt.c @@ -42,6 +42,7 @@ typedef struct { enum HidPushToTalkAppIndex { HidPushToTalkAppIndexDiscord, HidPushToTalkAppIndexFaceTime, + HidPushToTalkAppIndexGather, HidPushToTalkAppIndexGoogleMeet, HidPushToTalkAppIndexGoogleHangouts, HidPushToTalkAppIndexJamulus, @@ -308,7 +309,6 @@ static void hid_ptt_trigger_mute_jamulus(HidPushToTalk* hid_ptt) { } // webex - static void hid_ptt_trigger_camera_webex(HidPushToTalk* hid_ptt) { hid_hal_keyboard_press(hid_ptt->hid, KEY_MOD_LEFT_CTRL | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_V); hid_hal_keyboard_release( @@ -325,6 +325,30 @@ static void hid_ptt_trigger_hand_linux_webex(HidPushToTalk* hid_ptt) { hid_ptt->hid, KEY_MOD_LEFT_CTRL | KEY_MOD_RIGHT_SHIFT | HID_KEYBOARD_R); } +// Gather +static void hid_ptt_trigger_hand_gather(HidPushToTalk* hid_ptt) { + hid_hal_keyboard_press(hid_ptt->hid, HID_KEYBOARD_H); + hid_hal_keyboard_release(hid_ptt->hid, HID_KEYBOARD_H); +} +static void hid_ptt_trigger_camera_macos_gather(HidPushToTalk* hid_ptt) { + hid_hal_keyboard_press(hid_ptt->hid, KEY_MOD_LEFT_GUI | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_V); + hid_hal_keyboard_release(hid_ptt->hid, KEY_MOD_LEFT_GUI | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_V); +} +static void hid_ptt_trigger_mute_macos_gather(HidPushToTalk* hid_ptt) { + hid_hal_keyboard_press(hid_ptt->hid, KEY_MOD_LEFT_GUI | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_A); + hid_hal_keyboard_release(hid_ptt->hid, KEY_MOD_LEFT_GUI | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_A); +} +static void hid_ptt_trigger_camera_linux_gather(HidPushToTalk* hid_ptt) { + hid_hal_keyboard_press(hid_ptt->hid, KEY_MOD_LEFT_CTRL | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_V); + hid_hal_keyboard_release( + hid_ptt->hid, KEY_MOD_LEFT_CTRL | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_V); +} +static void hid_ptt_trigger_mute_linux_gather(HidPushToTalk* hid_ptt) { + hid_hal_keyboard_press(hid_ptt->hid, KEY_MOD_LEFT_CTRL | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_A); + hid_hal_keyboard_release( + hid_ptt->hid, KEY_MOD_LEFT_CTRL | KEY_MOD_LEFT_SHIFT | HID_KEYBOARD_A); +} + static void hid_ptt_menu_callback( void* context, uint32_t osIndex, @@ -359,6 +383,13 @@ static void hid_ptt_menu_callback( model->callback_start_ptt = hid_ptt_trigger_cmd_shift_m; model->callback_stop_ptt = hid_ptt_trigger_cmd_shift_m; break; + case HidPushToTalkAppIndexGather: + model->callback_trigger_mute = hid_ptt_trigger_mute_macos_gather; + model->callback_trigger_camera = hid_ptt_trigger_camera_macos_gather; + model->callback_trigger_hand = hid_ptt_trigger_hand_gather; + model->callback_start_ptt = hid_ptt_trigger_mute_macos_gather; + model->callback_stop_ptt = hid_ptt_trigger_mute_macos_gather; + break; case HidPushToTalkAppIndexGoogleHangouts: model->callback_trigger_mute = hid_ptt_trigger_mute_macos_hangouts; model->callback_trigger_camera = hid_ptt_trigger_camera_macos_hangouts; @@ -434,6 +465,13 @@ static void hid_ptt_menu_callback( model->callback_start_ptt = hid_ptt_start_ptt_linux_discord; model->callback_stop_ptt = hid_ptt_stop_ptt_linux_discord; break; + case HidPushToTalkAppIndexGather: + model->callback_trigger_mute = hid_ptt_trigger_mute_linux_gather; + model->callback_trigger_camera = hid_ptt_trigger_camera_linux_gather; + model->callback_trigger_hand = hid_ptt_trigger_hand_gather; + model->callback_start_ptt = hid_ptt_trigger_mute_linux_gather; + model->callback_stop_ptt = hid_ptt_trigger_mute_linux_gather; + break; case HidPushToTalkAppIndexGoogleHangouts: model->callback_trigger_mute = hid_ptt_trigger_mute_linux_hangouts; model->callback_trigger_camera = hid_ptt_trigger_camera_linux_hangouts; @@ -873,6 +911,20 @@ HidPushToTalk* hid_ptt_alloc(Hid* hid) { HidPushToTalkAppIndexFaceTime, hid_ptt_menu_callback, hid_ptt); + ptt_menu_add_item_to_list( + hid->hid_ptt_menu, + HidPushToTalkMacOS, + "Gather", + HidPushToTalkAppIndexGather, + hid_ptt_menu_callback, + hid_ptt); + ptt_menu_add_item_to_list( + hid->hid_ptt_menu, + HidPushToTalkLinux, + "Gather", + HidPushToTalkAppIndexGather, + hid_ptt_menu_callback, + hid_ptt); ptt_menu_add_item_to_list( hid->hid_ptt_menu, HidPushToTalkMacOS, @@ -932,14 +984,14 @@ HidPushToTalk* hid_ptt_alloc(Hid* hid) { ptt_menu_add_item_to_list( hid->hid_ptt_menu, HidPushToTalkMacOS, - "Slack Hubble", + "Slack Huddle", HidPushToTalkAppIndexSlackHubble, hid_ptt_menu_callback, hid_ptt); ptt_menu_add_item_to_list( hid->hid_ptt_menu, HidPushToTalkLinux, - "Slack Hubble", + "Slack Huddle", HidPushToTalkAppIndexSlackHubble, hid_ptt_menu_callback, hid_ptt); diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_0.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_0.png index 888a40b0d..c06aa2562 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_0.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_0.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_1.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_1.png index d467d4aef..838b68a99 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_1.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_1.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_2.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_2.png index 3dd633bc1..a39d6d04a 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_2.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_2.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_3.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_3.png index dc0883451..28181d5b0 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_3.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_3.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_4.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_4.png index 30792c8f2..e05debb38 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_4.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_4.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_5.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_5.png index 152b2b53d..1658287d8 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_5.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_5.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_6.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_6.png index b79bd23d7..4fb2ae191 100644 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_6.png and b/assets/dolphin/external/L1_Wardriving_128x64/frame_6.png differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/frame_7.png b/assets/dolphin/external/L1_Wardriving_128x64/frame_7.png deleted file mode 100644 index 1cd7bfdba..000000000 Binary files a/assets/dolphin/external/L1_Wardriving_128x64/frame_7.png and /dev/null differ diff --git a/assets/dolphin/external/L1_Wardriving_128x64/meta.txt b/assets/dolphin/external/L1_Wardriving_128x64/meta.txt index 5a492afc6..93ab92696 100644 --- a/assets/dolphin/external/L1_Wardriving_128x64/meta.txt +++ b/assets/dolphin/external/L1_Wardriving_128x64/meta.txt @@ -3,12 +3,12 @@ Version: 1 Width: 128 Height: 64 -Passive frames: 9 +Passive frames: 8 Active frames: 0 -Frames order: 0 1 2 3 4 5 6 7 7 +Frames order: 0 1 2 3 4 5 6 6 Active cycles: 0 -Frame rate: 2 -Duration: 360 +Frame rate: 1 +Duration: 3600 Active cooldown: 0 Bubble slots: 1 @@ -19,5 +19,5 @@ Y: 14 Text: Pwned! AlignH: Left AlignV: Center -StartFrame: 7 -EndFrame: 8 +StartFrame: 6 +EndFrame: 7 diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index b5d51a0dd..c72569c64 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1446,6 +1446,7 @@ Function,+,furi_hal_serial_get_gpio_pin,const GpioPin*,"FuriHalSerialHandle*, Fu Function,+,furi_hal_serial_init,void,"FuriHalSerialHandle*, uint32_t" Function,+,furi_hal_serial_is_baud_rate_supported,_Bool,"FuriHalSerialHandle*, uint32_t" Function,+,furi_hal_serial_resume,void,FuriHalSerialHandle* +Function,+,furi_hal_serial_send_break,void,FuriHalSerialHandle* Function,+,furi_hal_serial_set_br,void,"FuriHalSerialHandle*, uint32_t" Function,+,furi_hal_serial_suspend,void,FuriHalSerialHandle* Function,+,furi_hal_serial_tx,void,"FuriHalSerialHandle*, const uint8_t*, size_t" diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 5f98152bb..f5e79d7ee 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1691,6 +1691,7 @@ Function,+,furi_hal_serial_get_gpio_pin,const GpioPin*,"FuriHalSerialHandle*, Fu Function,+,furi_hal_serial_init,void,"FuriHalSerialHandle*, uint32_t" Function,+,furi_hal_serial_is_baud_rate_supported,_Bool,"FuriHalSerialHandle*, uint32_t" Function,+,furi_hal_serial_resume,void,FuriHalSerialHandle* +Function,+,furi_hal_serial_send_break,void,FuriHalSerialHandle* Function,+,furi_hal_serial_set_br,void,"FuriHalSerialHandle*, uint32_t" Function,+,furi_hal_serial_suspend,void,FuriHalSerialHandle* Function,+,furi_hal_serial_tx,void,"FuriHalSerialHandle*, const uint8_t*, size_t" diff --git a/targets/f7/furi_hal/furi_hal_serial.c b/targets/f7/furi_hal/furi_hal_serial.c index 5ddb0785f..3f6b575a6 100644 --- a/targets/f7/furi_hal/furi_hal_serial.c +++ b/targets/f7/furi_hal/furi_hal_serial.c @@ -950,3 +950,13 @@ const GpioPin* return furi_hal_serial_config[handle->id].gpio[direction]; } + +void furi_hal_serial_send_break(FuriHalSerialHandle* handle) { + furi_check(handle); + + if(handle->id == FuriHalSerialIdUsart) { + LL_USART_RequestBreakSending(USART1); + } else { + LL_LPUART_RequestBreakSending(LPUART1); + } +} diff --git a/targets/f7/furi_hal/furi_hal_serial.h b/targets/f7/furi_hal/furi_hal_serial.h index 00010d83c..6dad8ec31 100644 --- a/targets/f7/furi_hal/furi_hal_serial.h +++ b/targets/f7/furi_hal/furi_hal_serial.h @@ -239,6 +239,12 @@ void furi_hal_serial_dma_rx_stop(FuriHalSerialHandle* handle); */ size_t furi_hal_serial_dma_rx(FuriHalSerialHandle* handle, uint8_t* data, size_t len); +/** Send a break sequence (low level for the whole character duration) + * + * @param handle Serial handle + */ +void furi_hal_serial_send_break(FuriHalSerialHandle* handle); + #ifdef __cplusplus } #endif diff --git a/targets/f7/furi_hal/furi_hal_usb_cdc.c b/targets/f7/furi_hal/furi_hal_usb_cdc.c index cfedb5e76..3408789dd 100644 --- a/targets/f7/furi_hal/furi_hal_usb_cdc.c +++ b/targets/f7/furi_hal/furi_hal_usb_cdc.c @@ -122,7 +122,7 @@ static const struct CdcConfigDescriptorSingle cdc_cfg_desc_single = { .bFunctionLength = sizeof(struct usb_cdc_acm_desc), .bDescriptorType = USB_DTYPE_CS_INTERFACE, .bDescriptorSubType = USB_DTYPE_CDC_ACM, - .bmCapabilities = 0, + .bmCapabilities = USB_CDC_CAP_BRK, }, .cdc_union = { @@ -235,7 +235,7 @@ static const struct CdcConfigDescriptorDual .bFunctionLength = sizeof(struct usb_cdc_acm_desc), .bDescriptorType = USB_DTYPE_CS_INTERFACE, .bDescriptorSubType = USB_DTYPE_CDC_ACM, - .bmCapabilities = 0, + .bmCapabilities = USB_CDC_CAP_BRK, }, .cdc_union = { @@ -330,7 +330,7 @@ static const struct CdcConfigDescriptorDual .bFunctionLength = sizeof(struct usb_cdc_acm_desc), .bDescriptorType = USB_DTYPE_CS_INTERFACE, .bDescriptorSubType = USB_DTYPE_CDC_ACM, - .bmCapabilities = 0, + .bmCapabilities = USB_CDC_CAP_BRK, }, .cdc_union = { @@ -680,6 +680,13 @@ static usbd_respond cdc_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_cal dev->status.data_ptr = &cdc_config[if_num]; dev->status.data_count = sizeof(cdc_config[0]); return usbd_ack; + case USB_CDC_SEND_BREAK: + if(callbacks[if_num] != NULL) { + if(callbacks[if_num]->break_callback != NULL) { + callbacks[if_num]->break_callback(cb_ctx[if_num], req->wValue); + } + } + return usbd_ack; default: return usbd_fail; } diff --git a/targets/f7/furi_hal/furi_hal_usb_cdc.h b/targets/f7/furi_hal/furi_hal_usb_cdc.h index 89b68991b..995e9009a 100644 --- a/targets/f7/furi_hal/furi_hal_usb_cdc.h +++ b/targets/f7/furi_hal/furi_hal_usb_cdc.h @@ -15,6 +15,7 @@ typedef struct { void (*state_callback)(void* context, uint8_t state); void (*ctrl_line_callback)(void* context, uint8_t state); void (*config_callback)(void* context, struct usb_cdc_line_coding* config); + void (*break_callback)(void* context, uint16_t duration); } CdcCallbacks; void furi_hal_cdc_set_callbacks(uint8_t if_num, CdcCallbacks* cb, void* context);