diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c index 6100a162..c7ffd784 100644 --- a/applications/app-loader/app-loader.c +++ b/applications/app-loader/app-loader.c @@ -60,7 +60,7 @@ static void handle_menu(void* _ctx) { ctx->state->app_thread_attr.cb_mem = NULL; ctx->state->app_thread_attr.cb_size = 0; ctx->state->app_thread_attr.stack_mem = NULL; - ctx->state->app_thread_attr.stack_size = 1024; + ctx->state->app_thread_attr.stack_size = ctx->app->stack_size; ctx->state->app_thread_attr.priority = osPriorityNormal; ctx->state->app_thread_attr.tz_module = 0; ctx->state->app_thread_attr.reserved = 0; @@ -72,7 +72,7 @@ static void handle_cli(string_t args, void* _ctx) { if(ctx->app->app == NULL) return; - cli_print("Starting furi application\r\n"); + printf("Starting furi application\r\n"); ctx->state->current_app = ctx->app; ctx->state->app_thread_attr.name = ctx->app->name; @@ -80,13 +80,13 @@ static void handle_cli(string_t args, void* _ctx) { ctx->state->app_thread_attr.cb_mem = NULL; ctx->state->app_thread_attr.cb_size = 0; ctx->state->app_thread_attr.stack_mem = NULL; - ctx->state->app_thread_attr.stack_size = 1024; + ctx->state->app_thread_attr.stack_size = ctx->app->stack_size; ctx->state->app_thread_attr.priority = osPriorityNormal; ctx->state->app_thread_attr.tz_module = 0; ctx->state->app_thread_attr.reserved = 0; ctx->state->app_thread_id = osThreadNew(ctx->app->app, NULL, &ctx->state->app_thread_attr); - cli_print("Press any key to kill application"); + printf("Press any key to kill application"); char c; cli_read(&c, 1); @@ -184,7 +184,7 @@ void app_loader(void* p) { menu_item_add(menu, menu_plugins); }); - printf("[app loader] start\n"); + printf("[app loader] start\r\n"); osThreadSuspend(self_id); } diff --git a/applications/applications.c b/applications/applications.c index fa552e09..b9eab9f7 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -38,114 +38,129 @@ void sd_filesystem(void* p); const FuriApplication FLIPPER_SERVICES[] = { #ifdef APP_DISPLAY - {.app = display_u8g2, .name = "display_u8g2", .icon = A_Plugins_14}, + {.app = display_u8g2, .name = "display_u8g2", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_CLI - {.app = cli_task, .name = "cli_task", .icon = A_Plugins_14}, + {.app = cli_task, .name = "cli_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_EXAMPLE_BLINK - {.app = application_blink, .name = "blink", .icon = A_Plugins_14}, + {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_INPUT - {.app = input_task, .name = "input_task", .icon = A_Plugins_14}, + {.app = input_task, .name = "input_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_EXAMPLE_INPUT_DUMP - {.app = application_input_dump, .name = "input dump", .icon = A_Plugins_14}, + {.app = application_input_dump, .name = "input dump", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_GUI - {.app = backlight_control, .name = "backlight_control", .icon = A_Plugins_14}, - {.app = gui_task, .name = "gui_task", .icon = A_Plugins_14}, + {.app = backlight_control, + .name = "backlight_control", + .stack_size = 1024, + .icon = A_Plugins_14}, + {.app = gui_task, .name = "gui_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_MENU - {.app = menu_task, .name = "menu_task", .icon = A_Plugins_14}, - {.app = app_loader, .name = "app_loader", .icon = A_Plugins_14}, + {.app = menu_task, .name = "menu_task", .stack_size = 1024, .icon = A_Plugins_14}, + {.app = app_loader, .name = "app_loader", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_SD_FILESYSTEM - {.app = sd_filesystem, .name = "sd_filesystem", .icon = A_Plugins_14}, + {.app = sd_filesystem, .name = "sd_filesystem", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_DOLPHIN - {.app = dolphin_task, .name = "dolphin_task", .icon = A_Plugins_14}, + {.app = dolphin_task, .name = "dolphin_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_POWER - {.app = power_task, .name = "power_task", .icon = A_Plugins_14}, + {.app = power_task, .name = "power_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_BT - {.app = bt_task, .name = "bt_task", .icon = A_Plugins_14}, + {.app = bt_task, .name = "bt_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_CC1101 - {.app = cc1101_workaround, .name = "cc1101 workaround", .icon = A_Plugins_14}, + {.app = cc1101_workaround, + .name = "cc1101 workaround", + .stack_size = 1024, + .icon = A_Plugins_14}, #endif #ifdef APP_LF_RFID - {.app = lf_rfid_workaround, .name = "lf rfid workaround", .icon = A_Plugins_14}, + {.app = lf_rfid_workaround, + .name = "lf rfid workaround", + .stack_size = 1024, + .icon = A_Plugins_14}, #endif #ifdef APP_IRDA - {.app = irda, .name = "irda", .icon = A_Plugins_14}, + {.app = irda, .name = "irda", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_NFC - {.app = nfc_task, .name = "nfc_task", .icon = A_Plugins_14}, + {.app = nfc_task, .name = "nfc_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_TEST - {.app = flipper_test_app, .name = "test app", .icon = A_Plugins_14}, + {.app = flipper_test_app, .name = "test app", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_EXAMPLE_IPC - {.app = application_ipc_display, .name = "ipc display", .icon = A_Plugins_14}, - {.app = application_ipc_widget, .name = "ipc widget", .icon = A_Plugins_14}, + {.app = application_ipc_display, + .name = "ipc display", + .stack_size = 1024, + .icon = A_Plugins_14}, + {.app = application_ipc_widget, .name = "ipc widget", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_EXAMPLE_QRCODE - {.app = u8g2_qrcode, .name = "u8g2_qrcode", .icon = A_Plugins_14}, + {.app = u8g2_qrcode, .name = "u8g2_qrcode", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_EXAMPLE_FATFS - {.app = fatfs_list, .name = "fatfs_list", .icon = A_Plugins_14}, + {.app = fatfs_list, .name = "fatfs_list", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_EXAMPLE_DISPLAY - {.app = u8g2_example, .name = "u8g2_example", .icon = A_Plugins_14}, + {.app = u8g2_example, .name = "u8g2_example", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_SPEAKER_DEMO - {.app = coreglitch_demo_0, .name = "coreglitch_demo_0", .icon = A_Plugins_14}, + {.app = coreglitch_demo_0, + .name = "coreglitch_demo_0", + .stack_size = 1024, + .icon = A_Plugins_14}, #endif #ifdef APP_SD_TEST - {.app = sd_card_test, .name = "sd_card_test", .icon = A_Plugins_14}, + {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = A_Plugins_14}, #endif #ifdef APP_MUSIC_PLAYER - {.app = music_player, .name = "music player", .icon = A_Plugins_14}, + {.app = music_player, .name = "music player", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_IBUTTON - {.app = app_ibutton, .name = "ibutton", .icon = A_Plugins_14}, + {.app = app_ibutton, .name = "ibutton", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_GPIO_DEMO - {.app = app_gpio_test, .name = "gpio test", .icon = A_Plugins_14}, + {.app = app_gpio_test, .name = "gpio test", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef APP_FLOOPPER_BLOOPPER - {.app = floopper_bloopper, .name = "Floopper Bloopper", .icon = A_Games_14}, + {.app = floopper_bloopper, .name = "Floopper Bloopper", .stack_size = 1024, .icon = A_Games_14}, #endif #ifdef APP_SDNFC - {.app = sdnfc, .name = "sdnfc", .icon = A_Plugins_14}, + {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = A_Plugins_14}, #endif }; @@ -156,23 +171,23 @@ size_t FLIPPER_SERVICES_size() { // Main menu APP const FuriApplication FLIPPER_APPS[] = { #ifdef BUILD_CC1101 - {.app = cc1101_workaround, .name = "Sub-1 GHz", .icon = A_Sub1ghz_14}, + {.app = cc1101_workaround, .name = "Sub-1 GHz", .stack_size = 1024, .icon = A_Sub1ghz_14}, #endif #ifdef BUILD_LF_RFID - {.app = lf_rfid_workaround, .name = "125 kHz RFID", .icon = A_125khz_14}, + {.app = lf_rfid_workaround, .name = "125 kHz RFID", .stack_size = 1024, .icon = A_125khz_14}, #endif #ifdef BUILD_IRDA - {.app = irda, .name = "Infrared", .icon = A_Infrared_14}, + {.app = irda, .name = "Infrared", .stack_size = 1024, .icon = A_Infrared_14}, #endif #ifdef BUILD_IBUTTON - {.app = app_ibutton, .name = "iButton", .icon = A_iButton_14}, + {.app = app_ibutton, .name = "iButton", .stack_size = 1024, .icon = A_iButton_14}, #endif #ifdef BUILD_GPIO_DEMO - {.app = app_gpio_test, .name = "GPIO", .icon = A_GPIO_14}, + {.app = app_gpio_test, .name = "GPIO", .stack_size = 1024, .icon = A_GPIO_14}, #endif }; @@ -183,35 +198,41 @@ size_t FLIPPER_APPS_size() { // Plugin menu const FuriApplication FLIPPER_PLUGINS[] = { #ifdef BUILD_EXAMPLE_BLINK - {.app = application_blink, .name = "blink", .icon = A_Plugins_14}, + {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef BUILD_EXAMPLE_INPUT_DUMP - {.app = application_input_dump, .name = "input dump", .icon = A_Plugins_14}, + {.app = application_input_dump, .name = "input dump", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef BUILD_SPEAKER_DEMO - {.app = coreglitch_demo_0, .name = "coreglitch_demo_0", .icon = A_Plugins_14}, + {.app = coreglitch_demo_0, + .name = "coreglitch_demo_0", + .stack_size = 1024, + .icon = A_Plugins_14}, #endif #ifdef BUILD_SD_TEST - {.app = sd_card_test, .name = "sd_card_test", .icon = A_Plugins_14}, + {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = A_Plugins_14}, #endif #ifdef BUILD_VIBRO_DEMO - {.app = application_vibro, .name = "application_vibro", .icon = A_Plugins_14}, + {.app = application_vibro, + .name = "application_vibro", + .stack_size = 1024, + .icon = A_Plugins_14}, #endif #ifdef BUILD_MUSIC_PLAYER - {.app = music_player, .name = "music player", .icon = A_Plugins_14}, + {.app = music_player, .name = "music player", .stack_size = 1024, .icon = A_Plugins_14}, #endif #ifdef BUILD_FLOOPPER_BLOOPPER - {.app = floopper_bloopper, .name = "Floopper Bloopper", .icon = A_Games_14}, + {.app = floopper_bloopper, .name = "Floopper Bloopper", .stack_size = 1024, .icon = A_Games_14}, #endif #ifdef BUILD_SDNFC - {.app = sdnfc, .name = "sdnfc", .icon = A_Plugins_14}, + {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = A_Plugins_14}, #endif }; diff --git a/applications/applications.h b/applications/applications.h index 44c25acd..bf60b7f3 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -8,6 +8,7 @@ typedef void (*FlipperApplication)(void*); typedef struct { const FlipperApplication app; const char* name; + const size_t stack_size; const IconName icon; } FuriApplication; diff --git a/applications/bt/bt.c b/applications/bt/bt.c index bc2a4cb0..d3af0dfe 100644 --- a/applications/bt/bt.c +++ b/applications/bt/bt.c @@ -33,7 +33,7 @@ void bt_cli_info(string_t args, void* context) { string_t buffer; string_init(buffer); api_hal_bt_dump_state(buffer); - cli_print(string_get_cstr(buffer)); + printf(string_get_cstr(buffer)); string_clear(buffer); } diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index baefe9ee..fab6e76e 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -3,8 +3,6 @@ #include #include -extern "C" void cli_print(const char* str); - #define RSSI_DELAY 5000 //rssi delay in micro second #define CHAN_SPA 0.05 // channel spacing @@ -81,9 +79,9 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { /* char buf[256]; sprintf(buf, "status: %d -> %d, rssi: %d\n", rx_status, cc1101->SpiReadStatus(CC1101_MARCSTATE), rssi_dBm); - cli_print(buf); + printf(buf); sprintf(buf, "begin: %d, end: %d\n", begin_size, end_size); - cli_print(buf); + printf(buf); */ // uint8_t rx_data[64]; @@ -101,7 +99,7 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { } printf(" "); } - printf("\n"); + printf("\r\n"); * for(uint8_t i = 0; i < fifo_length; i++) { @@ -111,7 +109,7 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { } } } else { - cli_print("fifo size over\n"); + printf("fifo size over\r\n"); } */ @@ -158,12 +156,12 @@ void flp_config(CC1101* cc1101) { // bandwidth 50-100 kHz if(!cc1101->setRxBandwidth(75.0)) { - printf("wrong rx bw\n"); + printf("wrong rx bw\r\n"); } // datarate ~30 kbps if(!cc1101->setBitRate(100.)) { - printf("wrong bitrate\n"); + printf("wrong bitrate\r\n"); } // mod @@ -361,7 +359,7 @@ extern "C" void cc1101_workaround(void* p) { ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("[cc1101] cannot create mutex\n"); + printf("[cc1101] cannot create mutex\r\n"); furiac_exit(NULL); } @@ -373,7 +371,7 @@ extern "C" void cc1101_workaround(void* p) { // Open GUI and register widget Gui* gui = (Gui*)furi_record_open("gui"); if(gui == NULL) { - printf("[cc1101] gui is not available\n"); + printf("[cc1101] gui is not available\r\n"); furiac_exit(NULL); } gui_add_widget(gui, widget, GuiLayerFullscreen); @@ -381,7 +379,7 @@ extern "C" void cc1101_workaround(void* p) { gpio_init(&debug_0, GpioModeOutputPushPull); gpio_write((GpioPin*)&debug_0, false); - printf("[cc1101] creating device\n"); + printf("[cc1101] creating device\r\n"); GpioPin cs_pin = {CC1101_CS_GPIO_Port, CC1101_CS_Pin}; gpio_init(&cc1101_g0_gpio, GpioModeInput); @@ -389,13 +387,13 @@ extern "C" void cc1101_workaround(void* p) { // TODO open record GpioPin* cs_pin_record = &cs_pin; CC1101 cc1101(cs_pin_record); - printf("[cc1101] init device\n"); + printf("[cc1101] init device\r\n"); uint8_t address = cc1101.Init(); if(address > 0) { - printf("[cc1101] init done: %d\n", address); + printf("[cc1101] init done: %d\r\n", address); } else { - printf("[cc1101] init fail\n"); + printf("[cc1101] init fail\r\n"); furiac_exit(NULL); } @@ -406,7 +404,7 @@ extern "C" void cc1101_workaround(void* p) { // setup_freq(&cc1101, &FREQ_LIST[4]); // enable_cc1101_irq(); - printf("init ok\n"); + printf("init ok\r\n"); // TODO open record GpioPin* led_record = (GpioPin*)&led_gpio[1]; @@ -428,12 +426,12 @@ extern "C" void cc1101_workaround(void* p) { if(event_status == osOK) { if(event.type == EventTypeKey) { if(event.value.input.state && event.value.input.input == InputBack) { - printf("[cc1101] bye!\n"); - cli_print("[cc1101] bye!\n"); + printf("[cc1101] bye!\r\n"); cc1101.SpiStrobe(CC1101_SIDLE); cc1101.SpiStrobe(CC1101_SPWD); - cli_print("[cc1101] go to power down\n"); + + printf("[cc1101] go to power down\r\n"); // TODO remove all widgets create by app widget_enabled_set(widget, false); diff --git a/applications/cc1101-workaround/cc1101.cpp b/applications/cc1101-workaround/cc1101.cpp index 2ef2930e..c53e3936 100644 --- a/applications/cc1101-workaround/cc1101.cpp +++ b/applications/cc1101-workaround/cc1101.cpp @@ -227,14 +227,14 @@ bool CC1101::SpiSetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb ****************************************************************/ uint8_t CC1101::Init(void) { #ifdef CC1101_DEBUG - printf("Init SPI...\n"); + printf("Init SPI...\r\n"); #endif SpiInit(); //spi initialization gpio_write(ss_pin, true); // gpio_write(SCK_PIN, true); // gpio_write(MOSI_PIN, false); #ifdef CC1101_DEBUG - printf("Reset CC1101...\n"); + printf("Reset CC1101...\r\n"); #endif Reset(); // CC1101 reset @@ -256,7 +256,7 @@ uint8_t CC1101::Init(void) { // RegConfigSettings(); //CC1101 register config #ifdef CC1101_DEBUG - printf("Done!\n"); + printf("Done!\r\n"); #endif return version; @@ -308,7 +308,7 @@ void CC1101::SetMod(uint8_t mode) { } } - printf("\n"); + printf("\r\n"); #endif } /**************************************************************** @@ -394,7 +394,7 @@ void CC1101::SetReceive(void) { SpiStrobe(CC1101_SRX); while(SpiReadStatus(CC1101_MARCSTATE) ^ CC1101_STATUS_RX) { // delay(1); - // printf("wait status\n"); + // printf("wait status\r\n"); } } /**************************************************************** diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 3d587dfe..6220c73d 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -27,32 +27,42 @@ void cli_putc(char c) { api_hal_vcp_tx((uint8_t*)&c, 1); } +char cli_getc(Cli* cli) { + furi_assert(cli); + char c; + if(api_hal_vcp_rx((uint8_t*)&c, 1) == 0) { + cli_reset_state(cli); + } + return c; +} + +void cli_stdout_callback(void* _cookie, const char* data, size_t size) { + api_hal_vcp_tx((const uint8_t*)data, size); +} + void cli_read(char* buffer, size_t size) { api_hal_vcp_rx((uint8_t*)buffer, size); } -void cli_print(const char* str) { - api_hal_vcp_tx((uint8_t*)str, strlen(str)); -} - void cli_print_version() { - cli_print("Build date:" BUILD_DATE ". " - "Git Commit:" GIT_COMMIT ". " - "Git Branch:" GIT_BRANCH ". " - "Commit Number:" GIT_BRANCH_NUM "."); + printf("Build date:" BUILD_DATE ". " + "Git Commit:" GIT_COMMIT ". " + "Git Branch:" GIT_BRANCH ". " + "Commit Number:" GIT_BRANCH_NUM "."); } void cli_motd() { - cli_print("Flipper cli.\r\n"); + printf("Flipper cli.\r\n"); cli_print_version(); } void cli_nl() { - cli_print("\r\n"); + printf("\r\n"); } void cli_prompt() { - cli_print("\r\n>: "); + printf("\r\n>: "); + fflush(stdout); } void cli_backspace(Cli* cli) { @@ -100,8 +110,8 @@ void cli_enter(Cli* cli) { cli_prompt(); } else { cli_nl(); - cli_print("Command not found: "); - cli_print(string_get_cstr(command)); + printf("Command not found: "); + printf(string_get_cstr(command)); cli_prompt(); cli_putc(CliSymbolAsciiBell); } @@ -112,14 +122,9 @@ void cli_enter(Cli* cli) { } void cli_process_input(Cli* cli) { - char c; + char c = cli_getc(cli); size_t r; - r = api_hal_vcp_rx((uint8_t*)&c, 1); - if(r == 0) { - cli_reset_state(cli); - } - if(c == CliSymbolAsciiTab) { cli_putc(CliSymbolAsciiBell); } else if(c == CliSymbolAsciiSOH) { @@ -175,6 +180,7 @@ void cli_task(void* p) { furi_record_create("cli", cli); + furi_stdglue_set_thread_stdout_callback(cli_stdout_callback); while(1) { cli_process_input(cli); } diff --git a/applications/cli/cli.h b/applications/cli/cli.h index 60f1589f..0b6a787a 100644 --- a/applications/cli/cli.h +++ b/applications/cli/cli.h @@ -34,12 +34,6 @@ void cli_add_command(Cli* cli, const char* name, CliCallback callback, void* con */ void cli_read(char* buffer, size_t size); -/* Print to terminal - * Do it only from inside of callback. - * @param buffer - pointer to null terminated string to print. - */ -void cli_print(const char* buffer); - /* New line * Send new ine sequence */ diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index f845bc10..fab9f556 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -5,22 +5,22 @@ void cli_command_help(string_t args, void* context) { (void)args; Cli* cli = context; - cli_print("Commands we have:"); + printf("Commands we have:"); furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); CliCommandDict_it_t it; for(CliCommandDict_it(it, cli->commands); !CliCommandDict_end_p(it); CliCommandDict_next(it)) { CliCommandDict_itref_t* ref = CliCommandDict_ref(it); - cli_print(" "); - cli_print(string_get_cstr(ref->key)); + printf(" "); + printf(string_get_cstr(ref->key)); }; furi_check(osMutexRelease(cli->mutex) == osOK); if(string_size(args) > 0) { cli_nl(); - cli_print("Also I have no clue what '"); - cli_print(string_get_cstr(args)); - cli_print("' is."); + printf("Also I have no clue what '"); + printf(string_get_cstr(args)); + printf("' is."); } } @@ -43,7 +43,7 @@ void cli_command_uuid(string_t args, void* context) { uint8_t uid_byte = uid[i]; string_cat_printf(byte_str, "%02X", uid_byte); } - cli_print(string_get_cstr(byte_str)); + printf(string_get_cstr(byte_str)); } void cli_command_date(string_t args, void* context) { @@ -61,11 +61,19 @@ void cli_command_date(string_t args, void* context) { string_cat_printf(datetime_str, "%.2d:%.2d:%.2d ", time.Hours, time.Minutes, time.Seconds); string_cat_printf(datetime_str, "%.2d-%.2d-%.2d", date.Month, date.Date, 2000 + date.Year); - cli_print(string_get_cstr(datetime_str)); + printf(string_get_cstr(datetime_str)); string_clear(datetime_str); } +void cli_command_log(string_t args, void* context) { + Cli* cli = context; + furi_stdglue_set_global_stdout_callback(cli_stdout_callback); + printf("Press any key to stop...\r\n"); + cli_getc(cli); + furi_stdglue_set_global_stdout_callback(NULL); +} + void cli_commands_init(Cli* cli) { cli_add_command(cli, "help", cli_command_help, cli); cli_add_command(cli, "?", cli_command_help, cli); @@ -73,4 +81,5 @@ void cli_commands_init(Cli* cli) { cli_add_command(cli, "!", cli_command_version, cli); cli_add_command(cli, "uid", cli_command_uuid, cli); cli_add_command(cli, "date", cli_command_date, cli); + cli_add_command(cli, "log", cli_command_log, cli); } diff --git a/applications/cli/cli_i.h b/applications/cli/cli_i.h index 9873c398..5ed2b6df 100644 --- a/applications/cli/cli_i.h +++ b/applications/cli/cli_i.h @@ -38,4 +38,6 @@ Cli* cli_alloc(); void cli_free(Cli* cli); void cli_reset_state(Cli* cli); void cli_print_version(); +char cli_getc(Cli* cli); void cli_putc(char c); +void cli_stdout_callback(void* _cookie, const char* data, size_t size); diff --git a/applications/coreglitch_demo_0/coreglitch_demo_0.c b/applications/coreglitch_demo_0/coreglitch_demo_0.c index 3e9debc1..caf33405 100644 --- a/applications/coreglitch_demo_0/coreglitch_demo_0.c +++ b/applications/coreglitch_demo_0/coreglitch_demo_0.c @@ -4,7 +4,7 @@ extern TIM_HandleTypeDef SPEAKER_TIM; void coreglitch_demo_0(void* p) { - printf("coreglitch demo!\n"); + printf("coreglitch demo!\r\n"); float notes[] = { 0.0, diff --git a/applications/examples/input_dump.c b/applications/examples/input_dump.c index a1482d74..80645171 100644 --- a/applications/examples/input_dump.c +++ b/applications/examples/input_dump.c @@ -11,13 +11,13 @@ static void state_cb(const void* value, void* ctx) { InputDump dump = {.packed = 0}; dump.state = *(InputState*)value; - printf("state: %02x\n", dump.packed); + printf("state: %02x\r\n", dump.packed); } static void event_cb(const void* value, void* ctx) { const InputEvent* event = value; - printf("event: %02x %s\n", event->input, event->state ? "pressed" : "released"); + printf("event: %02x %s\r\n", event->input, event->state ? "pressed" : "released"); } void application_input_dump(void* p) { @@ -28,7 +28,7 @@ void application_input_dump(void* p) { PubSub* event_record = furi_record_open("input_events"); subscribe_pubsub(event_record, event_cb, NULL); - printf("Example app [input dump]\n"); + printf("Example app [input dump]\r\n"); for(;;) { delay(100); diff --git a/applications/examples/u8g2_qrcode.c b/applications/examples/u8g2_qrcode.c index 92f5a359..69461792 100644 --- a/applications/examples/u8g2_qrcode.c +++ b/applications/examples/u8g2_qrcode.c @@ -37,7 +37,7 @@ void u8g2_qrcode(void* p) { qrcode_initText(&qrcode, qrcodeBytes, qr_version, qr_error_correction, "HELLO FLIPPER"); if(fb_record == NULL) { - printf("[widget] cannot create fb record\n"); + printf("[widget] cannot create fb record\r\n"); furiac_exit(NULL); } diff --git a/applications/floopper-bloopper b/applications/floopper-bloopper index 62104425..7ba50ef9 160000 --- a/applications/floopper-bloopper +++ b/applications/floopper-bloopper @@ -1 +1 @@ -Subproject commit 621044255a8be4d2c3f342e2b22178a342ccbfe8 +Subproject commit 7ba50ef912566c78d2ddd37ab5912a8cada5c35d diff --git a/applications/gpio-tester/gpio-tester.c b/applications/gpio-tester/gpio-tester.c index 695fbdf9..bb8293a7 100644 --- a/applications/gpio-tester/gpio-tester.c +++ b/applications/gpio-tester/gpio-tester.c @@ -66,7 +66,7 @@ void app_gpio_test(void* p) { ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("[gpio-tester] cannot create mutex\n"); + printf("[gpio-tester] cannot create mutex\r\n"); furiac_exit(NULL); } @@ -94,7 +94,7 @@ void app_gpio_test(void* p) { if(event_status == osOK) { if(event.type == EventTypeKey) { if(event.value.input.state && event.value.input.input == InputBack) { - printf("[gpio-tester] bye!\n"); + printf("[gpio-tester] bye!\r\n"); // TODO remove all widgets create by app widget_enabled_set(widget, false); furiac_exit(NULL); diff --git a/applications/gui/u8g2_periphery.c b/applications/gui/u8g2_periphery.c index b6739977..f4b5cf6b 100644 --- a/applications/gui/u8g2_periphery.c +++ b/applications/gui/u8g2_periphery.c @@ -76,7 +76,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ case U8X8_MSG_BYTE_INIT: #ifdef DEBUG - printf("[u8g2] init\n"); + printf("[u8g2] init\r\n"); #endif // TODO change it to FuriRecord pin @@ -85,7 +85,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ case U8X8_MSG_BYTE_START_TRANSFER: #ifdef DEBUG - printf("[u8g2] start\n"); + printf("[u8g2] start\r\n"); #endif // TODO: SPI manager @@ -98,7 +98,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ case U8X8_MSG_BYTE_END_TRANSFER: #ifdef DEBUG - printf("[u8g2] end\n"); + printf("[u8g2] end\r\n"); #endif asm("nop"); diff --git a/applications/input/input.c b/applications/input/input.c index 00e0f7b8..658412cc 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -25,15 +25,15 @@ void input_task(void* p) { uint8_t debounce_counters[INPUT_COUNT]; if(!init_managed(&input_state_record, &input_state, sizeof(input_state))) { - printf("[input_task] cannot initialize ValueManager for input_state\n"); + printf("[input_task] cannot initialize ValueManager for input_state\r\n"); furiac_exit(NULL); } if(!init_pubsub(&input_events_record)) { - printf("[input_task] cannot initialize PubSub for input_events\n"); + printf("[input_task] cannot initialize PubSub for input_events\r\n"); furiac_exit(NULL); } if(!init_event(&event)) { - printf("[input_task] cannot initialize Event\n"); + printf("[input_task] cannot initialize Event\r\n"); furiac_exit(NULL); } diff --git a/applications/irda/irda.c b/applications/irda/irda.c index 522a7a50..a60d4018 100644 --- a/applications/irda/irda.c +++ b/applications/irda/irda.c @@ -263,7 +263,7 @@ void irda(void* p) { ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("cannot create mutex\n"); + printf("cannot create mutex\r\n"); furiac_exit(NULL); } diff --git a/applications/lf-rfid/em4100.c b/applications/lf-rfid/em4100.c index 9f3ff915..313b8699 100644 --- a/applications/lf-rfid/em4100.c +++ b/applications/lf-rfid/em4100.c @@ -48,7 +48,7 @@ void prepare_data(uint32_t ID, uint32_t VENDOR, uint8_t* data) { for(uint8_t i = 0; i < 64; i++) { printf("%d ", data[i]); } - printf("\n"); + printf("\r\n"); */ } diff --git a/applications/lf-rfid/lf-rfid.c b/applications/lf-rfid/lf-rfid.c index 26bb1d1f..1e913e88 100644 --- a/applications/lf-rfid/lf-rfid.c +++ b/applications/lf-rfid/lf-rfid.c @@ -106,7 +106,7 @@ static bool even_check(uint8_t* buf) { buf[line * (ROW_SIZE + 1) + ROW_SIZE]); return false; } - printf("\n"); + printf("\r\n"); } for(uint8_t col = 0; col < ROW_SIZE; col++) { @@ -138,7 +138,7 @@ static void extract_data(uint8_t* buf, uint8_t* customer, uint32_t* em_data) { offset++; } } - printf("\n"); + printf("\r\n"); *customer = data; @@ -155,7 +155,7 @@ static void extract_data(uint8_t* buf, uint8_t* customer, uint32_t* em_data) { offset++; } } - printf("\n"); + printf("\r\n"); *em_data = data; } @@ -194,7 +194,7 @@ void lf_rfid_workaround(void* p) { ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("cannot create mutex\n"); + printf("cannot create mutex\r\n"); furiac_exit(NULL); } diff --git a/applications/menu/menu.c b/applications/menu/menu.c index 4a0ae266..39dccdbc 100644 --- a/applications/menu/menu.c +++ b/applications/menu/menu.c @@ -33,7 +33,7 @@ ValueMutex* menu_init() { ValueMutex* menu_mutex = furi_alloc(sizeof(ValueMutex)); if(menu_mutex == NULL || !init_mutex(menu_mutex, menu, sizeof(Menu))) { - printf("[menu_task] cannot create menu mutex\n"); + printf("[menu_task] cannot create menu mutex\r\n"); furiac_exit(NULL); } diff --git a/applications/music-player/music-player.c b/applications/music-player/music-player.c index 3e8b4406..5b96cb61 100644 --- a/applications/music-player/music-player.c +++ b/applications/music-player/music-player.c @@ -369,7 +369,7 @@ void music_player(void* p) { ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("cannot create mutex\n"); + printf("cannot create mutex\r\n"); furiac_exit(NULL); } @@ -393,7 +393,7 @@ void music_player(void* p) { osThreadId_t player = osThreadNew(music_player_thread, &context, &player_attr); if(player == NULL) { - printf("cannot create player thread\n"); + printf("cannot create player thread\r\n"); furiac_exit(NULL); } diff --git a/applications/power/power.c b/applications/power/power.c index a451cd1f..04c7ecd7 100644 --- a/applications/power/power.c +++ b/applications/power/power.c @@ -142,19 +142,19 @@ void power_free(Power* power) { } void power_cli_poweroff(string_t args, void* context) { - cli_print("Poweroff in 3 seconds"); + printf("Poweroff in 3 seconds"); osDelay(3000); api_hal_power_off(); } void power_cli_reset(string_t args, void* context) { - cli_print("NVIC System Reset in 3 seconds"); + printf("NVIC System Reset in 3 seconds"); osDelay(3000); NVIC_SystemReset(); } void power_cli_dfu(string_t args, void* context) { - cli_print("NVIC System Reset to DFU mode in 3 seconds"); + printf("NVIC System Reset to DFU mode in 3 seconds"); api_hal_boot_set_mode(ApiHalBootModeDFU); osDelay(3000); NVIC_SystemReset(); @@ -164,7 +164,7 @@ void power_cli_test(string_t args, void* context) { string_t buffer; string_init(buffer); api_hal_power_dump_state(buffer); - cli_print(string_get_cstr(buffer)); + printf(string_get_cstr(buffer)); string_clear(buffer); } diff --git a/applications/sd-card-test/sd-card-test.cpp b/applications/sd-card-test/sd-card-test.cpp index 28dd5abb..e2e73668 100644 --- a/applications/sd-card-test/sd-card-test.cpp +++ b/applications/sd-card-test/sd-card-test.cpp @@ -610,99 +610,99 @@ void SdTest::cli_read_benchmark(string_t args, void* _ctx) { const uint8_t str_buffer_size = 64; char str_buffer[str_buffer_size]; - cli_print("preparing benchmark data\r\n"); + printf("preparing benchmark data\r\n"); bool data_prepared = _this->prepare_benchmark_data(); if(data_prepared) { - cli_print("benchmark data prepared\r\n"); + printf("benchmark data prepared\r\n"); } else { - cli_print("error: cannot allocate buffer for benchmark data\r\n"); + printf("error: cannot allocate buffer for benchmark data\r\n"); } // prepare data for read test - cli_print("prepare data for read speed test, procedure can be lengthy, please wait\r\n"); + printf("prepare data for read speed test, procedure can be lengthy, please wait\r\n"); if(!_this->fs_api->file.open(&file, "read.test", FSAM_WRITE, FSOM_OPEN_ALWAYS)) { - cli_print("error: cannot open file in prepare read\r\n"); + printf("error: cannot open file in prepare read\r\n"); } for(size_t i = 0; i < benchmark_data_size / b4096_size; i++) { bytes_written = _this->fs_api->file.write(&file, benchmark_data, b4096_size); if(bytes_written != b4096_size || file.error_id != FSE_OK) { - cli_print("error: cannot write to file in prepare read\r\n"); + printf("error: cannot write to file in prepare read\r\n"); } } if(!_this->fs_api->file.close(&file)) { - cli_print("error: cannot close file in prepare read\r\n"); + printf("error: cannot close file in prepare read\r\n"); } // test start - cli_print("read speed test, procedure can be lengthy, please wait\r\n"); + printf("read speed test, procedure can be lengthy, please wait\r\n"); // open file if(!_this->fs_api->file.open(&file, "read.test", FSAM_READ, FSOM_OPEN_EXISTING)) { - cli_print("error: cannot open file in read benchmark\r\n"); + printf("error: cannot open file in read benchmark\r\n"); } // 1b test benchmark_bps = _this->read_benchmark_internal(b1_size, benchmark_data_size / b1_size, &file, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 1-byte read test\r\n"); + printf("error: in 1-byte read test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "1-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 8b test benchmark_bps = _this->read_benchmark_internal(b8_size, benchmark_data_size / b8_size, &file, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 8-byte read test\r\n"); + printf("error: in 8-byte read test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "8-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 32b test benchmark_bps = _this->read_benchmark_internal(b32_size, benchmark_data_size / b32_size, &file, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 32-byte read test\r\n"); + printf("error: in 32-byte read test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "32-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 256b test benchmark_bps = _this->read_benchmark_internal(b256_size, benchmark_data_size / b256_size, &file, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 256-byte read test\r\n"); + printf("error: in 256-byte read test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "256-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 4096b test benchmark_bps = _this->read_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, &file, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 4096-byte read test\r\n"); + printf("error: in 4096-byte read test\r\n"); } else { snprintf( str_buffer, str_buffer_size, "4096-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // close file if(!_this->fs_api->file.close(&file)) { - cli_print("error: cannot close file\r\n"); + printf("error: cannot close file\r\n"); } _this->free_benchmark_data(); - cli_print("test completed\r\n"); + printf("test completed\r\n"); } void SdTest::cli_write_benchmark(string_t args, void* _ctx) { @@ -721,68 +721,68 @@ void SdTest::cli_write_benchmark(string_t args, void* _ctx) { const uint8_t str_buffer_size = 64; char str_buffer[str_buffer_size]; - cli_print("preparing benchmark data\r\n"); + printf("preparing benchmark data\r\n"); bool data_prepared = _this->prepare_benchmark_data(); if(data_prepared) { - cli_print("benchmark data prepared\r\n"); + printf("benchmark data prepared\r\n"); } else { - cli_print("error: cannot allocate buffer for benchmark data\r\n"); + printf("error: cannot allocate buffer for benchmark data\r\n"); } - cli_print("write speed test, procedure can be lengthy, please wait\r\n"); + printf("write speed test, procedure can be lengthy, please wait\r\n"); // 1b test benchmark_bps = _this->write_benchmark_internal(b1_size, benchmark_data_size / b1_size, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 1-byte write test\r\n"); + printf("error: in 1-byte write test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "1-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 8b test benchmark_bps = _this->write_benchmark_internal(b8_size, benchmark_data_size / b8_size, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 8-byte write test\r\n"); + printf("error: in 8-byte write test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "8-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 32b test benchmark_bps = _this->write_benchmark_internal(b32_size, benchmark_data_size / b32_size, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 32-byte write test\r\n"); + printf("error: in 32-byte write test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "32-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 256b test benchmark_bps = _this->write_benchmark_internal(b256_size, benchmark_data_size / b256_size, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 256-byte write test\r\n"); + printf("error: in 256-byte write test\r\n"); } else { snprintf(str_buffer, str_buffer_size, "256-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } // 4096b test benchmark_bps = _this->write_benchmark_internal(b4096_size, benchmark_data_size / b4096_size, true); if(benchmark_bps == BENCHMARK_ERROR) { - cli_print("error: in 4096-byte write test\r\n"); + printf("error: in 4096-byte write test\r\n"); } else { snprintf( str_buffer, str_buffer_size, "4096-byte: %lu bytes per second\r\n", benchmark_bps); - cli_print(str_buffer); + printf(str_buffer); } _this->free_benchmark_data(); - cli_print("test completed\r\n"); + printf("test completed\r\n"); } // wait for button press @@ -873,7 +873,7 @@ template void SdTest::set_error(std::initializer_list list) { template void SdTest::set_text(std::initializer_list list) { uint8_t line_position = 0; acquire_state(); - printf("------------------------\n"); + printf("------------------------\r\n"); // set line strings from args for(auto element : list) { @@ -886,10 +886,10 @@ template void SdTest::set_text(std::initializer_list list) { // set empty lines for(; line_position < state.lines_count; line_position++) { state.line[line_position] = ""; - printf("\n"); + printf("\r\n"); } - printf("------------------------\n"); + printf("------------------------\r\n"); release_state(); update_gui(); } diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c index bafa12ee..eafa20e1 100644 --- a/applications/sd-filesystem/sd-filesystem.c +++ b/applications/sd-filesystem/sd-filesystem.c @@ -174,7 +174,7 @@ void app_sd_info_callback(void* context) { if(str_buffer[i] == NULL) { memory_error = true; } else { - snprintf(str_buffer[i], str_buffer_size, ""); + str_buffer[i][0] = 0; } } @@ -365,25 +365,25 @@ void app_sd_eject_callback(void* context) { static void cli_sd_status(string_t args, void* _ctx) { SdApp* sd_app = (SdApp*)_ctx; - cli_print("SD status: "); - cli_print(fs_error_get_internal_desc(sd_app->info.status)); - cli_print("\r\n"); + printf("SD status: "); + printf(fs_error_get_internal_desc(sd_app->info.status)); + printf("\r\n"); } static void cli_sd_format(string_t args, void* _ctx) { SdApp* sd_app = (SdApp*)_ctx; - cli_print("formatting SD card, please wait\r\n"); + printf("formatting SD card, please wait\r\n"); // format card app_sd_format_internal(sd_app); if(sd_app->info.status != SD_OK) { - cli_print("SD card format error: "); - cli_print(fs_error_get_internal_desc(sd_app->info.status)); - cli_print("\r\n"); + printf("SD card format error: "); + printf(fs_error_get_internal_desc(sd_app->info.status)); + printf("\r\n"); } else { - cli_print("SD card formatted\r\n"); + printf("SD card formatted\r\n"); } } @@ -437,42 +437,42 @@ static void cli_sd_info(string_t args, void* _ctx) { } snprintf(str_buffer, str_buffer_size, "Label: %s\r\n", volume_label); - cli_print(str_buffer); + printf(str_buffer); snprintf(str_buffer, str_buffer_size, "%s, S/N: %lu\r\n", fs_type, serial_num); - cli_print(str_buffer); + printf(str_buffer); snprintf(str_buffer, str_buffer_size, "Cluster: %d sectors\r\n", fs->csize); - cli_print(str_buffer); + printf(str_buffer); snprintf(str_buffer, str_buffer_size, "Sector: %d bytes\r\n", sector_size); - cli_print(str_buffer); + printf(str_buffer); snprintf( str_buffer, str_buffer_size, "%lu KB total\r\n", total_sectors / 1024 * sector_size); - cli_print(str_buffer); + printf(str_buffer); snprintf( str_buffer, str_buffer_size, "%lu KB free\r\n", free_sectors / 1024 * sector_size); - cli_print(str_buffer); + printf(str_buffer); } else { - cli_print("SD status error: "); + printf("SD status error: "); snprintf( str_buffer, str_buffer_size, "%s\r\n", fs_error_get_internal_desc(_fs_status(&sd_app->info))); - cli_print(str_buffer); + printf(str_buffer); - cli_print("Label error: "); + printf("Label error: "); snprintf( str_buffer, str_buffer_size, "%s\r\n", fs_error_get_internal_desc(get_label_result)); - cli_print(str_buffer); + printf(str_buffer); - cli_print("Get free error: "); + printf("Get free error: "); snprintf( str_buffer, str_buffer_size, "%s\r\n", fs_error_get_internal_desc(get_free_result)); - cli_print(str_buffer); + printf(str_buffer); } } @@ -511,7 +511,7 @@ void sd_filesystem(void* p) { with_value_mutex( menu_vm, (Menu * menu) { menu_item_add(menu, menu_item); }); - printf("[sd_filesystem] start\n"); + printf("[sd_filesystem] start\r\n"); // add api record furi_record_create("sdcard", fs_api); @@ -522,7 +522,7 @@ void sd_filesystem(void* p) { while(true) { if(sd_was_present) { if(hal_gpio_read_sd_detect()) { - printf("[sd_filesystem] card detected\n"); + printf("[sd_filesystem] card detected\r\n"); uint8_t bsp_result = BSP_SD_Init(); @@ -530,13 +530,13 @@ void sd_filesystem(void* p) { sd_app->info.status = SD_LOW_LEVEL_ERR; printf("[sd_filesystem] bsp error: %x\n", bsp_result); } else { - printf("[sd_filesystem] bsp ok\n"); + printf("[sd_filesystem] bsp ok\r\n"); sd_app->info.status = f_mount(&sd_app->info.fat_fs, sd_app->info.path, 1); if(sd_app->info.status != SD_OK) { printf("[sd_filesystem] mount error: %d\n", sd_app->info.status); } else { - printf("[sd_filesystem] mount ok\n"); + printf("[sd_filesystem] mount ok\r\n"); } } @@ -545,7 +545,7 @@ void sd_filesystem(void* p) { } } else { if(!hal_gpio_read_sd_detect()) { - printf("[sd_filesystem] card removed\n"); + printf("[sd_filesystem] card removed\r\n"); widget_enabled_set(sd_app->icon.widget, false); app_sd_unmount_card(sd_app); diff --git a/applications/template/template.c.example b/applications/template/template.c.example index 8cbe3255..ad3d3790 100644 --- a/applications/template/template.c.example +++ b/applications/template/template.c.example @@ -44,7 +44,7 @@ void template_app(void* p) { /* init state here */ ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("cannot create mutex\n"); + printf("cannot create mutex\r\n"); furiac_exit(NULL); } @@ -56,7 +56,7 @@ void template_app(void* p) { // Open GUI and register widget Gui* gui = furi_record_open("gui"); if(gui == NULL) { - printf("gui is not available\n"); + printf("gui is not available\r\n"); furiac_exit(NULL); } gui_add_widget(gui, widget, /* specify UI layer */); diff --git a/applications/tests/furi_valuemutex_test.c b/applications/tests/furi_valuemutex_test.c index e9258a61..7ea5f638 100644 --- a/applications/tests/furi_valuemutex_test.c +++ b/applications/tests/furi_valuemutex_test.c @@ -59,7 +59,7 @@ typedef struct { void furi_concurent_app(void* p) { ValueMutex* mutex = (ValueMutex*)p; if(mutex == NULL) { - printf("cannot open mutex\n"); + printf("cannot open mutex\r\n"); furiac_exit(NULL); } @@ -67,7 +67,7 @@ void furi_concurent_app(void* p) { ConcurrentValue* value = (ConcurrentValue*)acquire_mutex_block(mutex); if(value == NULL) { - printf("cannot take record\n"); + printf("cannot take record\r\n"); release_mutex(mutex, value); furiac_exit(NULL); } @@ -103,7 +103,7 @@ void test_furi_concurrent_access() { if(value == NULL) { release_mutex(&mutex, value); - mu_fail("cannot take record\n"); + mu_fail("cannot take record\r\n"); } // emulate read-modify-write broken by context switching diff --git a/applications/tests/furiac_test.c b/applications/tests/furiac_test.c index c19e629a..64fef937 100644 --- a/applications/tests/furiac_test.c +++ b/applications/tests/furiac_test.c @@ -31,19 +31,19 @@ bool test_furi_ac_create_kill() { FuriApp* widget = furiac_start(create_kill_app, "create_kill_app", (void*)&counter); if(widget == NULL) { - printf("create widget fail\n"); + printf("create widget fail\r\n"); return false; } delay(10); if(!furiac_kill(widget)) { - printf("kill widget fail\n"); + printf("kill widget fail\r\n"); return false; } if(value_a == counter) { - printf("counter unchanged\n"); + printf("counter unchanged\r\n"); return false; } diff --git a/bootloader/targets/f4/target.mk b/bootloader/targets/f4/target.mk index 4aa77c68..3acf372f 100644 --- a/bootloader/targets/f4/target.mk +++ b/bootloader/targets/f4/target.mk @@ -5,12 +5,12 @@ FW_ADDRESS = 0x08008000 OS_OFFSET = 0x00008000 FLASH_ADDRESS = 0x08000000 -OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "init" +OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" -c "init" BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET) MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections -LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs +LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs CUBE_DIR = ../lib/STM32CubeWB diff --git a/core/api-hal/api-interrupt-mgr.c b/core/api-hal/api-interrupt-mgr.c index 30ce131e..83557d1a 100644 --- a/core/api-hal/api-interrupt-mgr.c +++ b/core/api-hal/api-interrupt-mgr.c @@ -120,4 +120,4 @@ void api_interrupt_call(InterruptType type, void* hw) { } } } -} \ No newline at end of file +} diff --git a/core/furi.c b/core/furi.c index aaaad400..2e04a468 100644 --- a/core/furi.c +++ b/core/furi.c @@ -17,20 +17,22 @@ void furi_init() { int systemd() { furi_init(); - + printf("[systemd] furi initialized\r\n"); // FURI startup for(size_t i = 0; i < FLIPPER_SERVICES_size(); i++) { + printf("[systemd] starting service %s\r\n", FLIPPER_SERVICES[i].name); osThreadAttr_t* attr = furi_alloc(sizeof(osThreadAttr_t)); attr->name = FLIPPER_SERVICES[i].name; - attr->stack_size = 1024; + attr->stack_size = FLIPPER_SERVICES[i].stack_size; osThreadNew(FLIPPER_SERVICES[i].app, NULL, attr); } + printf("[systemd] all services started\r\n"); while(1) { osThreadSuspend(osThreadGetId()); } - printf("\n=== Bye from Flipper Zero! ===\n\n"); + printf("[systemd] === Bye from Flipper Zero! ===\r\n"); return (int)exitcode; } \ No newline at end of file diff --git a/core/furi/pubsub.c b/core/furi/pubsub.c index 2cfb6141..0722d2a0 100644 --- a/core/furi/pubsub.c +++ b/core/furi/pubsub.c @@ -5,10 +5,7 @@ bool init_pubsub(PubSub* pubsub) { // mutex without name, // no attributes (unfortunatly robust mutex is not supported by FreeRTOS), // with dynamic memory allocation - const osMutexAttr_t value_mutex_attr = { - .name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U}; - - pubsub->mutex = osMutexNew(&value_mutex_attr); + pubsub->mutex = osMutexNew(NULL); if(pubsub->mutex == NULL) return false; // construct list diff --git a/core/furi/record.c b/core/furi/record.c index 23e35e07..facf48b4 100644 --- a/core/furi/record.c +++ b/core/furi/record.c @@ -1,5 +1,6 @@ #include "record.h" #include "check.h" +#include "memmgr.h" #include #include @@ -22,34 +23,38 @@ typedef struct { FuriRecordDict_t records; } FuriRecordData; -FuriRecordData furi_record_data; +static FuriRecordData* furi_record_data = NULL; void furi_record_init() { - furi_record_data.records_mutex = osMutexNew(NULL); - FuriRecordDict_init(furi_record_data.records); + furi_record_data = furi_alloc(sizeof(FuriRecordData)); + furi_record_data->records_mutex = osMutexNew(NULL); + furi_check(furi_record_data->records_mutex); + FuriRecordDict_init(furi_record_data->records); } FuriRecord* furi_record_get_or_create(string_t name_str) { - FuriRecord* record = FuriRecordDict_get(furi_record_data.records, name_str); + assert(furi_record_data); + FuriRecord* record = FuriRecordDict_get(furi_record_data->records, name_str); if(!record) { FuriRecord new_record; new_record.data = NULL; new_record.owner = NULL; osThreadIdSet_init(new_record.holders); - FuriRecordDict_set_at(furi_record_data.records, name_str, new_record); - record = FuriRecordDict_get(furi_record_data.records, name_str); + FuriRecordDict_set_at(furi_record_data->records, name_str, new_record); + record = FuriRecordDict_get(furi_record_data->records, name_str); } return record; } void furi_record_create(const char* name, void* data) { + assert(furi_record_data); osThreadId_t thread_id = osThreadGetId(); string_t name_str; string_init_set_str(name_str, name); // Acquire mutex - furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK); + furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK); FuriRecord* record = furi_record_get_or_create(name_str); record->data = data; record->owner = thread_id; @@ -60,31 +65,34 @@ void furi_record_create(const char* name, void* data) { osThreadFlagsSet((osThreadId_t)*osThreadIdSet_ref(it), FURI_RECORD_FLAG_UPDATED); } // Release mutex - furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK); + furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK); string_clear(name_str); } bool furi_record_destroy(const char* name) { + assert(furi_record_data); osThreadId_t thread_id = osThreadGetId(); string_t name_str; string_init_set_str(name_str, name); bool destroyed = false; - furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK); - FuriRecord* record = FuriRecordDict_get(furi_record_data.records, name_str); + furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK); + FuriRecord* record = FuriRecordDict_get(furi_record_data->records, name_str); if(record && record->owner == thread_id && osThreadIdSet_size(record->holders) == 0) { osThreadIdSet_clear(record->holders); - FuriRecordDict_erase(furi_record_data.records, name_str); + FuriRecordDict_erase(furi_record_data->records, name_str); + destroyed = true; } - furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK); + furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK); string_clear(name_str); return destroyed; } void* furi_record_open(const char* name) { + assert(furi_record_data); osThreadId_t thread_id = osThreadGetId(); string_t name_str; @@ -92,10 +100,10 @@ void* furi_record_open(const char* name) { FuriRecord* record = NULL; while(1) { - furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK); + furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK); record = furi_record_get_or_create(name_str); osThreadIdSet_push(record->holders, (uint32_t)thread_id); - furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK); + furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK); // Check if owner is already arrived if(record->owner) { break; @@ -109,15 +117,16 @@ void* furi_record_open(const char* name) { } void furi_record_close(const char* name) { + assert(furi_record_data); osThreadId_t thread_id = osThreadGetId(); string_t name_str; string_init_set_str(name_str, name); - furi_check(osMutexAcquire(furi_record_data.records_mutex, osWaitForever) == osOK); - FuriRecord* record = FuriRecordDict_get(furi_record_data.records, name_str); + furi_check(osMutexAcquire(furi_record_data->records_mutex, osWaitForever) == osOK); + FuriRecord* record = FuriRecordDict_get(furi_record_data->records, name_str); osThreadIdSet_erase(record->holders, (uint32_t)thread_id); - furi_check(osMutexRelease(furi_record_data.records_mutex) == osOK); + furi_check(osMutexRelease(furi_record_data->records_mutex) == osOK); string_clear(name_str); } diff --git a/core/furi/stdglue.c b/core/furi/stdglue.c index 13b8cd39..9c383179 100644 --- a/core/furi/stdglue.c +++ b/core/furi/stdglue.c @@ -1,12 +1,57 @@ #include "stdglue.h" -#include +#include "check.h" +#include "memmgr.h" +#include +#include #include #include +#include extern UART_HandleTypeDef DEBUG_UART; +DICT_DEF2( + FuriStdglueCallbackDict, + uint32_t, + M_DEFAULT_OPLIST, + FuriStdglueWriteCallback, + M_PTR_OPLIST) + +typedef struct { + osMutexId_t mutex; + FuriStdglueCallbackDict_t global_outputs; + FuriStdglueCallbackDict_t thread_outputs; +} FuriStdglue; + +static FuriStdglue* furi_stdglue = NULL; + static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { + assert(furi_stdglue); + osKernelState_t state = osKernelGetState(); + osThreadId_t thread_id = osThreadGetId(); + if(state == osKernelRunning && thread_id && + osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK) { + // We are in the thread context + // Handle global callbacks + FuriStdglueCallbackDict_it_t it; + for(FuriStdglueCallbackDict_it(it, furi_stdglue->global_outputs); + !FuriStdglueCallbackDict_end_p(it); + FuriStdglueCallbackDict_next(it)) { + osThreadId_t it_thread = (osThreadId_t)FuriStdglueCallbackDict_ref(it)->key; + FuriStdglueWriteCallback it_callback = FuriStdglueCallbackDict_ref(it)->value; + if(thread_id != it_thread) { + it_callback(_cookie, data, size); + } + } + // Handle thread callbacks + FuriStdglueWriteCallback* callback_ptr = + FuriStdglueCallbackDict_get(furi_stdglue->thread_outputs, (uint32_t)thread_id); + if(callback_ptr) { + (*callback_ptr)(_cookie, data, size); + } + furi_check(osMutexRelease(furi_stdglue->mutex) == osOK); + } + // Flush if(data == 0) { /* * This means that we should flush internal buffers. Since we @@ -15,13 +60,20 @@ static ssize_t stdout_write(void* _cookie, const char* data, size_t size) { */ return 0; } - + // Debug uart HAL_UART_Transmit(&DEBUG_UART, (uint8_t*)data, (uint16_t)size, HAL_MAX_DELAY); - + // All data consumed return size; } -bool furi_stdglue_init() { +void furi_stdglue_init() { + furi_stdglue = furi_alloc(sizeof(FuriStdglue)); + // Init outputs structures + furi_stdglue->mutex = osMutexNew(NULL); + furi_check(furi_stdglue->mutex); + FuriStdglueCallbackDict_init(furi_stdglue->global_outputs); + FuriStdglueCallbackDict_init(furi_stdglue->thread_outputs); + // Prepare and set stdout descriptor FILE* fp = fopencookie( NULL, "w", @@ -31,8 +83,42 @@ bool furi_stdglue_init() { .seek = NULL, .close = NULL, }); - setvbuf(fp, NULL, _IONBF, 0); + setvbuf(fp, NULL, _IOLBF, 0); stdout = fp; - - return true; +} + +bool furi_stdglue_set_global_stdout_callback(FuriStdglueWriteCallback callback) { + assert(furi_stdglue); + osThreadId_t thread_id = osThreadGetId(); + if(thread_id) { + furi_check(osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK); + if(callback) { + FuriStdglueCallbackDict_set_at( + furi_stdglue->global_outputs, (uint32_t)thread_id, callback); + } else { + FuriStdglueCallbackDict_erase(furi_stdglue->global_outputs, (uint32_t)thread_id); + } + furi_check(osMutexRelease(furi_stdglue->mutex) == osOK); + return true; + } else { + return false; + } +} + +bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback) { + assert(furi_stdglue); + osThreadId_t thread_id = osThreadGetId(); + if(thread_id) { + furi_check(osMutexAcquire(furi_stdglue->mutex, osWaitForever) == osOK); + if(callback) { + FuriStdglueCallbackDict_set_at( + furi_stdglue->thread_outputs, (uint32_t)thread_id, callback); + } else { + FuriStdglueCallbackDict_erase(furi_stdglue->thread_outputs, (uint32_t)thread_id); + } + furi_check(osMutexRelease(furi_stdglue->mutex) == osOK); + return true; + } else { + return false; + } } diff --git a/core/furi/stdglue.h b/core/furi/stdglue.h index d093d33d..16d9b917 100644 --- a/core/furi/stdglue.h +++ b/core/furi/stdglue.h @@ -1,12 +1,36 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { #endif -bool furi_stdglue_init(); +/* Write callback + * @param _cookie - pointer to cookie (see stdio gnu extension) + * @param data - pointer to data + * @param size - data size + * @warnign your handler must consume everything + */ +typedef void (*FuriStdglueWriteCallback)(void* _cookie, const char* data, size_t size); + +/* Initialized std library glue code */ +void furi_stdglue_init(); + +/* Set global STDOUT callback + * @param callback - callback or NULL to clear + * @return true on success, otherwise fail + * @warning function is thread aware, use this API from the same thread + */ +bool furi_stdglue_set_global_stdout_callback(FuriStdglueWriteCallback callback); + +/* Set STDOUT callback for your thread + * @param callback - callback or NULL to clear + * @return true on success, otherwise fail + * @warning function is thread aware, use this API from the same thread + */ +bool furi_stdglue_set_thread_stdout_callback(FuriStdglueWriteCallback callback); #ifdef __cplusplus } diff --git a/core/furi/value-expanders.c b/core/furi/value-expanders.c index 845ea4dc..d5e49b8c 100644 --- a/core/furi/value-expanders.c +++ b/core/furi/value-expanders.c @@ -10,10 +10,7 @@ bool init_composer(ValueComposer* composer, void* value) { // mutex without name, // no attributes (unfortunatly robust mutex is not supported by FreeRTOS), // with dynamic memory allocation - const osMutexAttr_t value_mutex_attr = { - .name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U}; - - composer->mutex = osMutexNew(&value_mutex_attr); + composer->mutex = osMutexNew(NULL); if(composer->mutex == NULL) return false; if(!init_event(&composer->request)) return false; diff --git a/core/furi/valuemutex.c b/core/furi/valuemutex.c index 2dbd0cc0..77a99937 100644 --- a/core/furi/valuemutex.c +++ b/core/furi/valuemutex.c @@ -6,10 +6,7 @@ bool init_mutex(ValueMutex* valuemutex, void* value, size_t size) { // mutex without name, // no attributes (unfortunatly robust mutex is not supported by FreeRTOS), // with dynamic memory allocation - const osMutexAttr_t value_mutext_attr = { - .name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U}; - - valuemutex->mutex = osMutexNew(&value_mutext_attr); + valuemutex->mutex = osMutexNew(NULL); if(valuemutex->mutex == NULL) return false; valuemutex->value = value; diff --git a/firmware/targets/api-hal-include/api-hal-power.h b/firmware/targets/api-hal-include/api-hal-power.h index 709c9718..454e9642 100644 --- a/firmware/targets/api-hal-include/api-hal-power.h +++ b/firmware/targets/api-hal-include/api-hal-power.h @@ -16,6 +16,9 @@ typedef enum { /* Initialize drivers */ void api_hal_power_init(); +/* Check if deep sleep availble */ +bool api_hal_power_deep_available(); + /* Go to deep sleep */ void api_hal_power_deep_sleep(); diff --git a/firmware/targets/api-hal-include/api-hal-vcp.h b/firmware/targets/api-hal-include/api-hal-vcp.h index 52703d75..3d6d53ab 100644 --- a/firmware/targets/api-hal-include/api-hal-vcp.h +++ b/firmware/targets/api-hal-include/api-hal-vcp.h @@ -25,7 +25,7 @@ size_t api_hal_vcp_rx(uint8_t* buffer, size_t size); * @param buffer - pointer to buffer * @param size - buffer size */ -void api_hal_vcp_tx(uint8_t* buffer, size_t size); +void api_hal_vcp_tx(const uint8_t* buffer, size_t size); #ifdef __cplusplus } diff --git a/firmware/targets/f4/Inc/FreeRTOSConfig.h b/firmware/targets/f4/Inc/FreeRTOSConfig.h index 9d317e97..2ae64e0b 100644 --- a/firmware/targets/f4/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f4/Inc/FreeRTOSConfig.h @@ -58,12 +58,12 @@ /* USER CODE END 0 */ #endif #define configENABLE_FPU 1 -#define configENABLE_MPU 0 +#define configENABLE_MPU 1 #define configUSE_PREEMPTION 1 #define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configUSE_IDLE_HOOK 1 +#define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ((TickType_t)1024) @@ -71,8 +71,8 @@ #define configMINIMAL_STACK_SIZE ((uint16_t)128) #define configTOTAL_HEAP_SIZE ((size_t)131072) #define configMAX_TASK_NAME_LEN ( 16 ) -#define configGENERATE_RUN_TIME_STATS 1 -#define configUSE_TRACE_FACILITY 1 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 8 @@ -83,6 +83,7 @@ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_TICKLESS_IDLE 2 #define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_NEWLIB_REENTRANT 0 /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ /* Defaults to size_t for backward compatibility, but can be changed if lengths will always be less than the number of bytes in a size_t. */ @@ -106,7 +107,6 @@ to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 @@ -142,15 +142,15 @@ PRIORITY THAN THIS! (higher priorities are lower numeric values. */ /* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ -#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Normal assert() semantics without relying on the provision of an assert.h header file. */ /* USER CODE BEGIN 1 */ -#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} +#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); asm("bkpt 1"); for( ;; );} /* USER CODE END 1 */ /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS @@ -163,14 +163,4 @@ standard names. */ /* #define xPortSysTickHandler SysTick_Handler */ -/* USER CODE BEGIN 2 */ -/* Definitions needed when configGENERATE_RUN_TIME_STATS is on */ -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats -#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue -/* USER CODE END 2 */ - -/* USER CODE BEGIN Defines */ -/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ -/* USER CODE END Defines */ - #endif /* FREERTOS_CONFIG_H */ diff --git a/firmware/targets/f4/Src/app_freertos.c b/firmware/targets/f4/Src/app_freertos.c index 9dd2fdfb..0eb71984 100644 --- a/firmware/targets/f4/Src/app_freertos.c +++ b/firmware/targets/f4/Src/app_freertos.c @@ -3,49 +3,23 @@ #include #include +void systemd(void *argument); + osThreadId_t systemdHandle; const osThreadAttr_t systemd_attributes = { .name = "systemd", .priority = (osPriority_t) osPriorityNormal, - .stack_size = 1024 * 4 + .stack_size = 1024 }; -void systemd(void *argument); - -void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ - -/* Hook prototypes */ -void configureTimerForRunTimeStats(void); -unsigned long getRunTimeCounterValue(void); -void vApplicationIdleHook(void); -void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName); - -__weak void configureTimerForRunTimeStats(void) { -} - -__weak unsigned long getRunTimeCounterValue(void) { - return 0; -} - -__weak void vApplicationIdleHook( void ) { - /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set - to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle - task. It is essential that code added to this hook function never attempts - to block in any way (for example, call xQueueReceive() with a block time - specified, or call vTaskDelay()). If the application makes use of the - vTaskDelete() API function (as this demo application does) then it is also - important that vApplicationIdleHook() is permitted to return to its calling - function, because it is the responsibility of the idle task to clean up - memory allocated by the kernel to any task that has since been deleted. */ -} - -__weak void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) { +void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) { /* Run time stack overflow checking is performed if configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is called if a stack overflow is detected. */ + asm("bkpt 1"); + while(1); } - void MX_FREERTOS_Init(void) { systemdHandle = osThreadNew(systemd, NULL, &systemd_attributes); } diff --git a/firmware/targets/f4/Src/stm32wbxx_it.c b/firmware/targets/f4/Src/stm32wbxx_it.c index 1e706611..452573db 100644 --- a/firmware/targets/f4/Src/stm32wbxx_it.c +++ b/firmware/targets/f4/Src/stm32wbxx_it.c @@ -111,7 +111,7 @@ void HardFault_Handler(void) void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ - + __asm("bkpt 1"); /* USER CODE END MemoryManagement_IRQn 0 */ while (1) { @@ -126,7 +126,7 @@ void MemManage_Handler(void) void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ - + __asm("bkpt 1"); /* USER CODE END BusFault_IRQn 0 */ while (1) { @@ -141,7 +141,7 @@ void BusFault_Handler(void) void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ - + __asm("bkpt 1"); /* USER CODE END UsageFault_IRQn 0 */ while (1) { @@ -399,7 +399,6 @@ extern void HW_TS_RTC_Wakeup_Handler(); extern void HW_IPCC_Tx_Handler(); extern void HW_IPCC_Rx_Handler(); - void RTC_WKUP_IRQHandler(void) { HW_TS_RTC_Wakeup_Handler(); @@ -408,14 +407,11 @@ void RTC_WKUP_IRQHandler(void) void IPCC_C1_TX_IRQHandler(void) { HW_IPCC_Tx_Handler(); - - return; } void IPCC_C1_RX_IRQHandler(void) { HW_IPCC_Rx_Handler(); - return; } /* USER CODE END 1 */ diff --git a/firmware/targets/f4/api-hal/api-hal-power.c b/firmware/targets/f4/api-hal/api-hal-power.c index 8316fb47..eec66dbb 100644 --- a/firmware/targets/f4/api-hal/api-hal-power.c +++ b/firmware/targets/f4/api-hal/api-hal-power.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -22,6 +23,10 @@ void api_hal_power_init() { bq25896_init(); } +bool api_hal_power_deep_available() { + return api_hal_bt_is_alive(); +} + void api_hal_power_deep_sleep() { while( LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)); diff --git a/firmware/targets/f4/api-hal/api-hal-timebase-timer.h b/firmware/targets/f4/api-hal/api-hal-timebase-timer.h index 5b471601..78922047 100644 --- a/firmware/targets/f4/api-hal/api-hal-timebase-timer.h +++ b/firmware/targets/f4/api-hal/api-hal-timebase-timer.h @@ -69,7 +69,7 @@ static inline bool api_hal_timebase_timer_cmp_is_ok() { } static inline uint32_t api_hal_timebase_timer_get_cmp() { - return LL_LPTIM_GetCompare(API_HAL_TIMEBASE_TIMER);; + return LL_LPTIM_GetCompare(API_HAL_TIMEBASE_TIMER); } static inline void api_hal_timebase_timer_set_cmp(uint32_t value) { diff --git a/firmware/targets/f4/api-hal/api-hal-timebase.c b/firmware/targets/f4/api-hal/api-hal-timebase.c index e1f35ff8..13ebbfcd 100644 --- a/firmware/targets/f4/api-hal/api-hal-timebase.c +++ b/firmware/targets/f4/api-hal/api-hal-timebase.c @@ -96,9 +96,12 @@ static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) { const uint16_t expected_cnt = (before_tick + expected_idle_ticks - 2) * API_HAL_TIMEBASE_CLK_PER_TICK; api_hal_timebase_timer_set_cmp(expected_cnt); + HAL_SuspendTick(); // Go to stop2 mode api_hal_power_deep_sleep(); + HAL_ResumeTick(); + // Spin till we are in timer safe zone while(!api_hal_timebase_timer_is_safe()) {} @@ -124,14 +127,15 @@ static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) { } void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { + if (!api_hal_power_deep_available() || api_hal_timebase.insomnia) { + return; + } + // Limit mount of ticks to maximum that timer can count if (expected_idle_ticks > API_HAL_TIMEBASE_MAX_SLEEP) { expected_idle_ticks = API_HAL_TIMEBASE_MAX_SLEEP; } - if (api_hal_timebase.insomnia) - return; - // Stop IRQ handling, no one should disturb us till we finish __disable_irq(); diff --git a/firmware/targets/f4/api-hal/api-hal-vcp.c b/firmware/targets/f4/api-hal/api-hal-vcp.c index 09e2bb44..e91b10dc 100644 --- a/firmware/targets/f4/api-hal/api-hal-vcp.c +++ b/firmware/targets/f4/api-hal/api-hal-vcp.c @@ -12,7 +12,7 @@ typedef struct { volatile bool underrun; } ApiHalVcp; -ApiHalVcp api_hal_vcp; +static ApiHalVcp* api_hal_vcp = NULL; static const uint8_t ascii_soh = 0x01; static const uint8_t ascii_eot = 0x04; @@ -24,19 +24,20 @@ void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size); void _api_hal_vcp_tx_complete(size_t size); void api_hal_vcp_init() { - api_hal_vcp.rx_stream = xStreamBufferCreate(API_HAL_VCP_RX_BUFFER_SIZE, 1); - api_hal_vcp.tx_semaphore = osSemaphoreNew(1, 1, NULL); - api_hal_vcp.alive = false; - api_hal_vcp.underrun = false; + api_hal_vcp = furi_alloc(sizeof(ApiHalVcp)); + api_hal_vcp->rx_stream = xStreamBufferCreate(API_HAL_VCP_RX_BUFFER_SIZE, 1); + api_hal_vcp->tx_semaphore = osSemaphoreNew(1, 1, NULL); + api_hal_vcp->alive = false; + api_hal_vcp->underrun = false; } void _api_hal_vcp_init() { - osSemaphoreRelease(api_hal_vcp.tx_semaphore); + osSemaphoreRelease(api_hal_vcp->tx_semaphore); } void _api_hal_vcp_deinit() { - api_hal_vcp.alive = false; - osSemaphoreRelease(api_hal_vcp.tx_semaphore); + api_hal_vcp->alive = false; + osSemaphoreRelease(api_hal_vcp->tx_semaphore); } void _api_hal_vcp_control_line(uint8_t state) { @@ -45,43 +46,46 @@ void _api_hal_vcp_control_line(uint8_t state) { bool rts = state & 0b10; if (rts) { - api_hal_vcp.alive = true; + api_hal_vcp->alive = true; _api_hal_vcp_rx_callback(&ascii_soh, 1); // SOH } else { - api_hal_vcp.alive = false; + api_hal_vcp->alive = false; _api_hal_vcp_rx_callback(&ascii_eot, 1); // EOT } - osSemaphoreRelease(api_hal_vcp.tx_semaphore); + osSemaphoreRelease(api_hal_vcp->tx_semaphore); } void _api_hal_vcp_rx_callback(const uint8_t* buffer, size_t size) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - size_t ret = xStreamBufferSendFromISR(api_hal_vcp.rx_stream, buffer, size, &xHigherPriorityTaskWoken); + size_t ret = xStreamBufferSendFromISR(api_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken); if (ret != size) { - api_hal_vcp.underrun = true; + api_hal_vcp->underrun = true; } portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } void _api_hal_vcp_tx_complete(size_t size) { - osSemaphoreRelease(api_hal_vcp.tx_semaphore); + osSemaphoreRelease(api_hal_vcp->tx_semaphore); } size_t api_hal_vcp_rx(uint8_t* buffer, size_t size) { - return xStreamBufferReceive(api_hal_vcp.rx_stream, buffer, size, portMAX_DELAY); + furi_assert(api_hal_vcp); + return xStreamBufferReceive(api_hal_vcp->rx_stream, buffer, size, portMAX_DELAY); } -void api_hal_vcp_tx(uint8_t* buffer, size_t size) { - while (size > 0 && api_hal_vcp.alive) { - furi_check(osSemaphoreAcquire(api_hal_vcp.tx_semaphore, osWaitForever) == osOK); +void api_hal_vcp_tx(const uint8_t* buffer, size_t size) { + furi_assert(api_hal_vcp); + + while (size > 0 && api_hal_vcp->alive) { + furi_check(osSemaphoreAcquire(api_hal_vcp->tx_semaphore, osWaitForever) == osOK); size_t batch_size = size; if (batch_size > APP_TX_DATA_SIZE) { batch_size = APP_TX_DATA_SIZE; } - if (CDC_Transmit_FS(buffer, batch_size) == USBD_OK) { + if (CDC_Transmit_FS((uint8_t*)buffer, batch_size) == USBD_OK) { size -= batch_size; buffer += batch_size; } else { diff --git a/firmware/targets/f4/ble-glue/app_ble.c b/firmware/targets/f4/ble-glue/app_ble.c index 45eb2971..910a5a28 100644 --- a/firmware/targets/f4/ble-glue/app_ble.c +++ b/firmware/targets/f4/ble-glue/app_ble.c @@ -1,7 +1,6 @@ #include "main.h" #include "app_common.h" - #include "dbg_trace.h" #include "ble.h" #include "tl.h" @@ -14,6 +13,8 @@ #include "dis_app.h" #include "hrs_app.h" +#include + typedef struct _tSecurityParams { uint8_t ioCapability; uint8_t mitm_mode; @@ -214,10 +215,11 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) if (disconnection_complete_event->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle) { BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0; BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE; - APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \n"); + APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \r\n"); } /* restart advertising */ Adv_Request(APP_BLE_FAST_ADV); + api_hal_timebase_insomnia_exit(); } break; /* EVT_DISCONN_COMPLETE */ @@ -227,45 +229,46 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) switch (meta_evt->subevent) { case EVT_LE_CONN_UPDATE_COMPLETE: - APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \n"); + APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \r\n"); /* USER CODE BEGIN EVT_LE_CONN_UPDATE_COMPLETE */ /* USER CODE END EVT_LE_CONN_UPDATE_COMPLETE */ break; case EVT_LE_PHY_UPDATE_COMPLETE: - APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE \n"); + APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE \r\n"); evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data; if (evt_le_phy_update_complete->Status == 0) { - APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status ok \n"); + APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status ok \r\n"); } else { - APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status nok \n"); + APP_DBG_MSG("EVT_UPDATE_PHY_COMPLETE, status nok \r\n"); } ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY); if (ret == BLE_STATUS_SUCCESS) { - APP_DBG_MSG("Read_PHY success \n"); + APP_DBG_MSG("Read_PHY success \r\n"); if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M)) { - APP_DBG_MSG("PHY Param TX= %d, RX= %d \n", TX_PHY, RX_PHY); + APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY); } else { - APP_DBG_MSG("PHY Param TX= %d, RX= %d \n", TX_PHY, RX_PHY); + APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY); } } else { - APP_DBG_MSG("Read conf not succeess \n"); + APP_DBG_MSG("Read conf not succeess \r\n"); } break; case EVT_LE_CONN_COMPLETE: { + api_hal_timebase_insomnia_enter(); hci_le_connection_complete_event_rp0 *connection_complete_event; /** @@ -275,7 +278,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id); - APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\n", connection_complete_event->Connection_Handle); + APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\r\n", connection_complete_event->Connection_Handle); if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING) { /* Connection as client */ @@ -301,71 +304,71 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) aci_gap_pairing_complete_event_rp0 *pairing_complete; case EVT_BLUE_GAP_LIMITED_DISCOVERABLE: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_LIMITED_DISCOVERABLE \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_LIMITED_DISCOVERABLE \r\n"); break; /* EVT_BLUE_GAP_LIMITED_DISCOVERABLE */ case EVT_BLUE_GAP_PASS_KEY_REQUEST: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PASS_KEY_REQUEST \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PASS_KEY_REQUEST \r\n"); aci_gap_pass_key_resp(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,123456); - APP_DBG_MSG("\r\n\r** aci_gap_pass_key_resp \n"); + APP_DBG_MSG("\r\n\r** aci_gap_pass_key_resp \r\n"); break; /* EVT_BLUE_GAP_PASS_KEY_REQUEST */ case EVT_BLUE_GAP_AUTHORIZATION_REQUEST: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_AUTHORIZATION_REQUEST \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_AUTHORIZATION_REQUEST \r\n"); break; /* EVT_BLUE_GAP_AUTHORIZATION_REQUEST */ case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED \r\n"); break; /* EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED */ case EVT_BLUE_GAP_BOND_LOST: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_BOND_LOST \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_BOND_LOST \r\n"); aci_gap_allow_rebond(BleApplicationContext.BleApplicationContext_legacy.connectionHandle); - APP_DBG_MSG("\r\n\r** Send allow rebond \n"); + APP_DBG_MSG("\r\n\r** Send allow rebond \r\n"); break; /* EVT_BLUE_GAP_BOND_LOST */ case EVT_BLUE_GAP_DEVICE_FOUND: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n"); break; /* EVT_BLUE_GAP_DEVICE_FOUND */ case EVT_BLUE_GAP_ADDR_NOT_RESOLVED: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_DEVICE_FOUND \r\n"); break; /* EVT_BLUE_GAP_DEVICE_FOUND */ case (EVT_BLUE_GAP_KEYPRESS_NOTIFICATION): - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_KEYPRESS_NOTIFICATION \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_KEYPRESS_NOTIFICATION \r\n"); break; /* EVT_BLUE_GAP_KEY_PRESS_NOTIFICATION */ case (EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE): - APP_DBG_MSG("numeric_value = %ld\n", + APP_DBG_MSG("numeric_value = %ld\r\n", ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); - APP_DBG_MSG("Hex_value = %lx\n", + APP_DBG_MSG("Hex_value = %lx\r\n", ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); aci_gap_numeric_comparison_value_confirm_yesno(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 1); /* CONFIRM_YES = 1 */ - APP_DBG_MSG("\r\n\r** aci_gap_numeric_comparison_value_confirm_yesno-->YES \n"); + APP_DBG_MSG("\r\n\r** aci_gap_numeric_comparison_value_confirm_yesno-->YES \r\n"); break; case (EVT_BLUE_GAP_PAIRING_CMPLT): { pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; - APP_DBG_MSG("BLE_CTRL_App_Notification: EVT_BLUE_GAP_PAIRING_CMPLT, pairing_complete->Status = %d\n",pairing_complete->Status); + APP_DBG_MSG("BLE_CTRL_App_Notification: EVT_BLUE_GAP_PAIRING_CMPLT, pairing_complete->Status = %d\r\n",pairing_complete->Status); if (pairing_complete->Status == 0) { - APP_DBG_MSG("\r\n\r** Pairing OK \n"); + APP_DBG_MSG("\r\n\r** Pairing OK \r\n"); } else { - APP_DBG_MSG("\r\n\r** Pairing KO \n"); + APP_DBG_MSG("\r\n\r** Pairing KO \r\n"); } } break; /* USER CODE END ecode */ case EVT_BLUE_GAP_PROCEDURE_COMPLETE: - APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PROCEDURE_COMPLETE \n"); + APP_DBG_MSG("\r\n\r** EVT_BLUE_GAP_PROCEDURE_COMPLETE \r\n"); break; } break; /* EVT_VENDOR */ @@ -385,9 +388,9 @@ void APP_BLE_Key_Button1_Action() { tBleStatus ret = BLE_STATUS_INVALID_PARAMS; ret = aci_gap_clear_security_db(); if (ret == BLE_STATUS_SUCCESS) { - APP_DBG_MSG("Successfully aci_gap_clear_security_db()\n"); + APP_DBG_MSG("Successfully aci_gap_clear_security_db()\r\n"); } else { - APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \n", ret); + APP_DBG_MSG("aci_gap_clear_security_db() Failed , result: %d \r\n", ret); } } @@ -397,7 +400,7 @@ void APP_BLE_Key_Button2_Action() { if (ret == BLE_STATUS_SUCCESS) { APP_DBG_MSG("Successfully aci_gap_slave_security_req()"); } else { - APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \n", ret); + APP_DBG_MSG("aci_gap_slave_security_req() Failed , result: %d \r\n", ret); } } @@ -406,23 +409,23 @@ void APP_BLE_Key_Button3_Action() { tBleStatus ret = BLE_STATUS_INVALID_PARAMS; ret = hci_le_read_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,&TX_PHY,&RX_PHY); if (ret == BLE_STATUS_SUCCESS) { - APP_DBG_MSG("Read_PHY success \n"); - APP_DBG_MSG("PHY Param TX= %d, RX= %d \n", TX_PHY, RX_PHY); + APP_DBG_MSG("Read_PHY success \r\n"); + APP_DBG_MSG("PHY Param TX= %d, RX= %d \r\n", TX_PHY, RX_PHY); if ((TX_PHY == TX_2M) && (RX_PHY == RX_2M)) { - APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \n", TX_1M, RX_1M); + APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_1M, RX_1M); ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_1M,RX_1M,0); } else { - APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \n", TX_2M_PREFERRED, RX_2M_PREFERRED); + APP_DBG_MSG("hci_le_set_phy PHY Param TX= %d, RX= %d \r\n", TX_2M_PREFERRED, RX_2M_PREFERRED); ret = hci_le_set_phy(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,ALL_PHYS_PREFERENCE,TX_2M_PREFERRED,RX_2M_PREFERRED,0); } } else { - APP_DBG_MSG("Read conf not succeess \n"); + APP_DBG_MSG("Read conf not succeess \r\n"); } if (ret == BLE_STATUS_SUCCESS) { - APP_DBG_MSG("set PHY cmd ok\n"); + APP_DBG_MSG("set PHY cmd ok\r\n"); } else { - APP_DBG_MSG("set PHY cmd NOK\n"); + APP_DBG_MSG("set PHY cmd NOK\r\n"); } } @@ -538,7 +541,7 @@ static void Ble_Hci_Gap_Gatt_Init() { if (aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name)) { - BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\n"); + BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\r\n"); } } @@ -548,7 +551,7 @@ static void Ble_Hci_Gap_Gatt_Init() { 2, (uint8_t *)&appearance)) { - BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\n"); + BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\r\n"); } /** * Initialize Default PHY @@ -613,7 +616,7 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status) */ HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id); - APP_DBG_MSG("First index in %d state \n", BleApplicationContext.Device_Connection_Status); + APP_DBG_MSG("First index in %d state \r\n", BleApplicationContext.Device_Connection_Status); if ((New_Status == APP_BLE_LP_ADV) && ((BleApplicationContext.Device_Connection_Status == APP_BLE_FAST_ADV) @@ -623,11 +626,11 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status) ret = aci_gap_set_non_discoverable(); if (ret == BLE_STATUS_SUCCESS) { - APP_DBG_MSG("Successfully Stopped Advertising \n"); + APP_DBG_MSG("Successfully Stopped Advertising \r\n"); } else { - APP_DBG_MSG("Stop Advertising Failed , result: %d \n", ret); + APP_DBG_MSG("Stop Advertising Failed , result: %d \r\n", ret); } } @@ -650,17 +653,17 @@ static void Adv_Request(APP_BLE_ConnStatus_t New_Status) ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t*) manuf_data); if (ret == BLE_STATUS_SUCCESS) { if (New_Status == APP_BLE_FAST_ADV) { - APP_DBG_MSG("Successfully Start Fast Advertising \n" ); + APP_DBG_MSG("Successfully Start Fast Advertising \r\n" ); /* Start Timer to STOP ADV - TIMEOUT */ HW_TS_Start(BleApplicationContext.Advertising_mgr_timer_Id, INITIAL_ADV_TIMEOUT); } else { - APP_DBG_MSG("Successfully Start Low Power Advertising \n"); + APP_DBG_MSG("Successfully Start Low Power Advertising \r\n"); } } else { if (New_Status == APP_BLE_FAST_ADV) { - APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n", ret); + APP_DBG_MSG("Start Fast Advertising Failed , result: %d \r\n", ret); } else { - APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \n", ret); + APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \r\n", ret); } } } diff --git a/firmware/targets/f4/ble-glue/app_conf.h b/firmware/targets/f4/ble-glue/app_conf.h index 222f0cfe..43599c06 100644 --- a/firmware/targets/f4/ble-glue/app_conf.h +++ b/firmware/targets/f4/ble-glue/app_conf.h @@ -5,7 +5,7 @@ #include "hw_if.h" #include "ble_bufsize.h" -#define CFG_TX_POWER (0x18) /* -0.15dBm */ +#define CFG_TX_POWER (0x1F) /* +6dBm */ /** * Define Advertising parameters @@ -21,7 +21,7 @@ */ #define CFG_BONDING_MODE (1) #define CFG_FIXED_PIN (111111) -#define CFG_USED_FIXED_PIN (0) +#define CFG_USED_FIXED_PIN (1) #define CFG_ENCRYPTION_KEY_SIZE_MAX (16) #define CFG_ENCRYPTION_KEY_SIZE_MIN (8) @@ -367,12 +367,12 @@ typedef enum /** * When set to 1, the traces are enabled in the BLE services */ -#define CFG_DEBUG_BLE_TRACE 0 +#define CFG_DEBUG_BLE_TRACE 1 /** * Enable or Disable traces in application */ -#define CFG_DEBUG_APP_TRACE 0 +#define CFG_DEBUG_APP_TRACE 1 #if (CFG_DEBUG_APP_TRACE != 0) #define APP_DBG_MSG PRINT_MESG_DBG diff --git a/firmware/targets/f4/ble-glue/app_debug.c b/firmware/targets/f4/ble-glue/app_debug.c index f9f11b70..c982447e 100644 --- a/firmware/targets/f4/ble-glue/app_debug.c +++ b/firmware/targets/f4/ble-glue/app_debug.c @@ -393,7 +393,7 @@ void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) ) /* USER CODE END DbgOutputTraces */ // HW_UART_Transmit_DMA(CFG_DEBUG_TRACE_UART, p_data, size, cb); HAL_UART_Transmit(&DEBUG_UART, (uint8_t*)p_data, (uint16_t)size, HAL_MAX_DELAY); - + cb(); /* USER CODE END DbgOutputTraces */ return; } diff --git a/firmware/targets/f4/ble-glue/tl_dbg_conf.h b/firmware/targets/f4/ble-glue/tl_dbg_conf.h index 3966c9ce..62c30fb8 100644 --- a/firmware/targets/f4/ble-glue/tl_dbg_conf.h +++ b/firmware/targets/f4/ble-glue/tl_dbg_conf.h @@ -40,14 +40,14 @@ extern UART_HandleTypeDef DEBUG_UART; * Enable or Disable traces * The raw data output is the hci binary packet format as specified by the BT specification * */ -#define TL_SHCI_CMD_DBG_EN 1 /* Reports System commands sent to CPU2 and the command response */ +#define TL_SHCI_CMD_DBG_EN 0 /* Reports System commands sent to CPU2 and the command response */ #define TL_SHCI_CMD_DBG_RAW_EN 0 /* Reports raw data System commands sent to CPU2 and the command response */ -#define TL_SHCI_EVT_DBG_EN 1 /* Reports System Asynchronous Events received from CPU2 */ +#define TL_SHCI_EVT_DBG_EN 0 /* Reports System Asynchronous Events received from CPU2 */ #define TL_SHCI_EVT_DBG_RAW_EN 0 /* Reports raw data System Asynchronous Events received from CPU2 */ -#define TL_HCI_CMD_DBG_EN 1 /* Reports BLE command sent to CPU2 and the command response */ +#define TL_HCI_CMD_DBG_EN 0 /* Reports BLE command sent to CPU2 and the command response */ #define TL_HCI_CMD_DBG_RAW_EN 0 /* Reports raw data BLE command sent to CPU2 and the command response */ -#define TL_HCI_EVT_DBG_EN 1 /* Reports BLE Asynchronous Events received from CPU2 */ +#define TL_HCI_EVT_DBG_EN 0 /* Reports BLE Asynchronous Events received from CPU2 */ #define TL_HCI_EVT_DBG_RAW_EN 0 /* Reports raw data BLE Asynchronous Events received from CPU2 */ #define TL_MM_DBG_EN 1 /* Reports the informations of the buffer released to CPU2 */ diff --git a/firmware/targets/f4/target.mk b/firmware/targets/f4/target.mk index 510d7d40..5398041d 100644 --- a/firmware/targets/f4/target.mk +++ b/firmware/targets/f4/target.mk @@ -1,7 +1,5 @@ TOOLCHAIN = arm -OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" - BOOT_ADDRESS = 0x08000000 FW_ADDRESS = 0x08008000 OS_OFFSET = 0x00008000 @@ -16,13 +14,14 @@ FLASH_ADDRESS = 0x08000000 CFLAGS += -DNO_BOOTLOADER endif +OPENOCD_OPTS = -f interface/stlink.cfg -c "transport select hla_swd" -f ../debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" -c "init" BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OFFSET=$(OS_OFFSET) MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs -CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions +CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group MXPROJECT_DIR = $(TARGET_DIR) diff --git a/make/rules.mk b/make/rules.mk index d25f5ce2..a29cac3c 100644 --- a/make/rules.mk +++ b/make/rules.mk @@ -11,6 +11,10 @@ OBJECTS += $(addprefix $(OBJ_DIR)/, $(notdir $(CPP_SOURCES:.cpp=.o))) # Generate dependencies DEPS = $(OBJECTS:.o=.d) +ifdef DFU_SERIAL + DFU_OPTIONS += -S $(DFU_SERIAL) +endif + $(shell test -d $(OBJ_DIR) || mkdir -p $(OBJ_DIR)) BUILD_FLAGS_SHELL=\ @@ -59,7 +63,7 @@ $(OBJ_DIR)/flash: $(OBJ_DIR)/$(PROJECT).bin touch $@ $(OBJ_DIR)/upload: $(OBJ_DIR)/$(PROJECT).bin - dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) -S $(DFU_SERIAL) + dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS) touch $@ $(ASSETS): $(ASSETS_SOURCES) $(ASSETS_COMPILLER) @@ -80,6 +84,9 @@ debug: flash -ex "compare-sections" \ $(OBJ_DIR)/$(PROJECT).elf; \ +openocd: + openocd $(OPENOCD_OPTS) + bm_debug: flash set -m; blackmagic & echo $$! > $(OBJ_DIR)/agent.PID arm-none-eabi-gdb \