[FL-781] FURI, CLI, stdlib: stdout hooks, integration between subsystems, uniform printf usage (#311)
* FURI stdglue: stdout hooks, local and global, ISR safe printf. Uniform newlines for terminal/debug output. Power: prevent sleep while core 2 has not started. * Furi record, stdglue: check mutex allocation * remove unused test * Furi stdglue: buferized output, dynamically allocated state. Furi record: dynamically allocated state. Input dump: proper line ending. Hal VCP: dynamically allocated state. * Interrupt manager: explicitly init list. * Makefile: cleanup rules, fix broken dfu upload. F4: add compiler stack protection options. * BLE: call debug uart callback on transmission complete * FreeRTOS: add configUSE_NEWLIB_REENTRANT * API HAL Timebase: fix issue with idle thread stack corruption caused by systick interrupt. BT: cleanup debug info output. FreeRTOS: disable reentry for newlib. * F4: update stack protection CFLAGS to match used compiller * F4: disable compiller stack protection because of incompatibility with current compiller * Makefile: return openocd logs to gdb * BLE: fixed pin, moar power, ble trace info. * Prevent sleep when connection is active * Makefile: return serial port to upload rule, add workaround for mac os * Furi: prevent usage of stack for cmsis functions. * F4: add missing includes, add debugger breakpoints * Applications: per app stack size. * Furi: honor kernel state in stdglue * FreeRTOS: remove unused hooks * Cleanup and format sources Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
This commit is contained in:
parent
fd5f694758
commit
584c0962d8
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
|
||||
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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
/****************************************************************
|
||||
|
@ -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 ". "
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 621044255a8be4d2c3f342e2b22178a342ccbfe8
|
||||
Subproject commit 7ba50ef912566c78d2ddd37ab5912a8cada5c35d
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 <class T> void SdTest::set_error(std::initializer_list<T> list) {
|
||||
template <class T> void SdTest::set_text(std::initializer_list<T> 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 <class T> void SdTest::set_text(std::initializer_list<T> 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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ 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
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "record.h"
|
||||
#include "check.h"
|
||||
#include "memmgr.h"
|
||||
|
||||
#include <cmsis_os2.h>
|
||||
#include <m-string.h>
|
||||
@ -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);
|
||||
}
|
||||
|
@ -1,12 +1,57 @@
|
||||
#include "stdglue.h"
|
||||
#include <main.h>
|
||||
#include "check.h"
|
||||
#include "memmgr.h"
|
||||
|
||||
#include <main.h>
|
||||
#include <cmsis_os2.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <m-dict.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
@ -150,7 +150,7 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
/* 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 */
|
||||
|
@ -3,49 +3,23 @@
|
||||
#include <task.h>
|
||||
#include <main.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <api-hal-power.h>
|
||||
#include <api-hal-clock.h>
|
||||
#include <api-hal-bt.h>
|
||||
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_pwr.h>
|
||||
@ -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));
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 <api-hal.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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,6 +14,7 @@ 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
|
||||
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user