From cc8d006e83c70c4955ac364897e1274f186d4de2 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:31:30 +0300 Subject: [PATCH 01/36] upd ifttt fixes by Willy-JL --- non_catalog_apps/ifttt/ifttt_virtual_button.c | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/non_catalog_apps/ifttt/ifttt_virtual_button.c b/non_catalog_apps/ifttt/ifttt_virtual_button.c index d8252f44ebd..4373d2f8539 100644 --- a/non_catalog_apps/ifttt/ifttt_virtual_button.c +++ b/non_catalog_apps/ifttt/ifttt_virtual_button.c @@ -36,9 +36,7 @@ void save_settings_file(FlipperFormat* file, Settings* settings) { flipper_format_write_string_cstr(file, CONF_EVENT, settings->save_event); } -Settings* load_settings() { - Settings* settings = malloc(sizeof(Settings)); - +Settings* load_settings(Settings* settings) { settings->save_ssid = ""; settings->save_password = ""; settings->save_key = ""; @@ -63,26 +61,28 @@ Settings* load_settings() { uint32_t value; if(flipper_format_read_header(file, string_value, &value)) { if(flipper_format_read_string(file, CONF_SSID, text_ssid_value)) { - settings->save_ssid = malloc(furi_string_size(text_ssid_value) + 1); - strcpy(settings->save_ssid, furi_string_get_cstr(text_ssid_value)); + settings->save_ssid = (char*)furi_string_get_cstr(text_ssid_value); } if(flipper_format_read_string(file, CONF_PASSWORD, text_password_value)) { - settings->save_password = malloc(furi_string_size(text_password_value) + 1); - strcpy(settings->save_password, furi_string_get_cstr(text_password_value)); + settings->save_password = (char*)furi_string_get_cstr(text_password_value); } if(flipper_format_read_string(file, CONF_KEY, text_key_value)) { - settings->save_key = malloc(furi_string_size(text_key_value) + 1); - strcpy(settings->save_key, furi_string_get_cstr(text_key_value)); + settings->save_key = (char*)furi_string_get_cstr(text_key_value); } if(flipper_format_read_string(file, CONF_EVENT, text_event_value)) { - settings->save_event = malloc(furi_string_size(text_event_value) + 1); - strcpy(settings->save_event, furi_string_get_cstr(text_event_value)); + settings->save_event = (char*)furi_string_get_cstr(text_event_value); } } flipper_format_file_close(file); } } + // We assigned some constant / internal buffer of furi string, so duplicate it and free at exit + settings->save_ssid = strdup(settings->save_ssid); + settings->save_password = strdup(settings->save_password); + settings->save_key = strdup(settings->save_key); + settings->save_event = strdup(settings->save_event); + furi_string_free(text_ssid_value); furi_string_free(text_password_value); furi_string_free(text_key_value); @@ -203,6 +203,7 @@ void ifttt_virtual_button_app_free(VirtualButtonApp* app) { free(app->settings.save_ssid); free(app->settings.save_password); free(app->settings.save_key); + free(app->settings.save_event); // Views view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewSendView); @@ -228,7 +229,7 @@ void ifttt_virtual_button_app_free(VirtualButtonApp* app) { int32_t ifttt_virtual_button_app(void* p) { UNUSED(p); - + // Disable expansion protocol to avoid interference with UART Handle Expansion* expansion = furi_record_open(RECORD_EXPANSION); expansion_disable(expansion); @@ -242,7 +243,7 @@ int32_t ifttt_virtual_button_app(void* p) { uint32_t first_scene = VirtualButtonAppSceneStart; VirtualButtonApp* app = ifttt_virtual_button_app_alloc(first_scene); - memcpy(&app->settings, load_settings(), sizeof(Settings)); + load_settings(&app->settings); send_serial_command_config(app->serial_handle, ESerialCommand_Config, &(app->settings)); view_dispatcher_run(app->view_dispatcher); From fc5eb63a3ae267132f0733ef3aff69a09e28b499 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:34:54 +0300 Subject: [PATCH 02/36] upd quac fixes by Willy-JL --- non_catalog_apps/quac/actions/action_subghz.c | 12 ++++-------- non_catalog_apps/quac/scenes/scene_action_settings.c | 10 +++++----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/non_catalog_apps/quac/actions/action_subghz.c b/non_catalog_apps/quac/actions/action_subghz.c index 76b4ea52c8e..1c05643db2c 100644 --- a/non_catalog_apps/quac/actions/action_subghz.c +++ b/non_catalog_apps/quac/actions/action_subghz.c @@ -222,10 +222,7 @@ void action_subghz_tx(void* context, const FuriString* action_path, FuriString* } } else { // if not RAW protocol FURI_LOG_I(TAG, "Protocol != RAW"); - bool repeat_exists = flipper_format_key_exist(fff_data_file, "Repeat"); - if(!repeat_exists) { - flipper_format_write_uint32(fff_data_file, "Repeat", &repeat, 1); - } + flipper_format_insert_or_update_uint32(fff_data_file, "Repeat", &repeat, 1); transmitter = subghz_transmitter_alloc_init(environment, furi_string_get_cstr(temp_str)); if(transmitter == NULL) { @@ -240,9 +237,6 @@ void action_subghz_tx(void* context, const FuriString* action_path, FuriString* is_init_protocol = false; } } - if(!repeat_exists) { - flipper_format_delete_key(fff_data_file, "Repeat"); - } } if(is_init_protocol) { @@ -250,7 +244,9 @@ void action_subghz_tx(void* context, const FuriString* action_path, FuriString* } else { subghz_devices_sleep(device); subghz_devices_end(device); - subghz_transmitter_free(transmitter); + if(transmitter != NULL) { + subghz_transmitter_free(transmitter); + } } } while(false); diff --git a/non_catalog_apps/quac/scenes/scene_action_settings.c b/non_catalog_apps/quac/scenes/scene_action_settings.c index 1afa4129d6f..edaf6646f5b 100644 --- a/non_catalog_apps/quac/scenes/scene_action_settings.c +++ b/non_catalog_apps/quac/scenes/scene_action_settings.c @@ -76,15 +76,15 @@ static bool scene_action_settings_import_file_browser_callback( char ext[MAX_EXT_LEN]; path_extract_extension(path, ext, MAX_EXT_LEN); if(!strcmp(ext, ".sub")) { - memcpy(*icon, icon_get_data(&I_SubGHz_10px), 32); // TODO: find the right size! + memcpy(*icon, icon_get_frame_data(&I_SubGHz_10px, 0), 32); // TODO: find the right size! } else if(!strcmp(ext, ".rfid")) { - memcpy(*icon, icon_get_data(&I_RFID_10px), 32); + memcpy(*icon, icon_get_frame_data(&I_RFID_10px, 0), 32); } else if(!strcmp(ext, ".ir")) { - memcpy(*icon, icon_get_data(&I_IR_10px), 32); + memcpy(*icon, icon_get_frame_data(&I_IR_10px, 0), 32); } else if(!strcmp(ext, ".nfc")) { - memcpy(*icon, icon_get_data(&I_NFC_10px), 32); + memcpy(*icon, icon_get_frame_data(&I_NFC_10px, 0), 32); } else if(!strcmp(ext, ".qpl")) { - memcpy(*icon, icon_get_data(&I_Playlist_10px), 32); + memcpy(*icon, icon_get_frame_data(&I_Playlist_10px, 0), 32); } else { return false; } From d2bcdc0a7f1d60cc7171a257ced8109280a46565 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:40:57 +0300 Subject: [PATCH 03/36] upd subghz playlist by Willy-JL --- base_pack/playlist/playlist.c | 123 +++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/base_pack/playlist/playlist.c b/base_pack/playlist/playlist.c index 3ae152ba4f6..f5241f00939 100644 --- a/base_pack/playlist/playlist.c +++ b/base_pack/playlist/playlist.c @@ -41,14 +41,15 @@ typedef struct { int current_playlist_repetition; // current playlist repetition // last 3 files - FuriString* prev_0_path; // current file - FuriString* prev_1_path; // previous file - FuriString* prev_2_path; // previous previous file - FuriString* prev_3_path; // you get the idea + FuriString* prev_0_text; // current file + FuriString* prev_1_text; // previous file + FuriString* prev_2_text; // previous previous file + FuriString* prev_3_text; // you get the idea int state; // current state ViewPort* view_port; + FuriMutex* mutex; } DisplayMeta; typedef struct { @@ -183,6 +184,11 @@ static int playlist_worker_process( TAG, " (TX) The SubGhz device used does not support the frequency for transmitеing, %lu", frequency); + + subghz_devices_idle(worker->radio_device); + + subghz_transmitter_free(transmitter); + subghz_environment_free(environment); return -5; } FURI_LOG_D(TAG, " (TX) Start sending ..."); @@ -242,17 +248,14 @@ static bool playlist_worker_wait_pause(PlaylistWorker* worker) { } void updatePlayListView(PlaylistWorker* worker, const char* str) { - furi_string_reset(worker->meta->prev_3_path); - furi_string_set(worker->meta->prev_3_path, furi_string_get_cstr(worker->meta->prev_2_path)); + furi_check(furi_mutex_acquire(worker->meta->mutex, FuriWaitForever) == FuriStatusOk); - furi_string_reset(worker->meta->prev_2_path); - furi_string_set(worker->meta->prev_2_path, furi_string_get_cstr(worker->meta->prev_1_path)); + furi_string_set(worker->meta->prev_3_text, furi_string_get_cstr(worker->meta->prev_2_text)); + furi_string_set(worker->meta->prev_2_text, furi_string_get_cstr(worker->meta->prev_1_text)); + furi_string_set(worker->meta->prev_1_text, furi_string_get_cstr(worker->meta->prev_0_text)); + furi_string_set(worker->meta->prev_0_text, str); - furi_string_reset(worker->meta->prev_1_path); - furi_string_set(worker->meta->prev_1_path, furi_string_get_cstr(worker->meta->prev_0_path)); - - furi_string_reset(worker->meta->prev_0_path); - furi_string_set(worker->meta->prev_0_path, str); + furi_mutex_release(worker->meta->mutex); view_port_update(worker->meta->view_port); } @@ -283,7 +286,10 @@ static bool playlist_worker_play_playlist_once( const char* str = furi_string_get_cstr(data); // it's not fancy, but it works for now :) - updatePlayListView(worker, str); + FuriString* filename = furi_string_alloc(); + path_extract_filename(data, filename, true); + updatePlayListView(worker, furi_string_get_cstr(filename)); + furi_string_free(filename); for(int i = 0; i < 1; i++) { if(!playlist_worker_wait_pause(worker)) { @@ -300,9 +306,18 @@ static bool playlist_worker_play_playlist_once( playlist_worker_process(worker, fff_file, fff_data, str, preset, protocol); // if there was an error, fff_file is not already freed + // why do you do this with numbers without meaning x_x if(status < 0) { - flipper_format_file_close(fff_file); - flipper_format_free(fff_file); + if(status > -5) { + flipper_format_file_close(fff_file); + flipper_format_free(fff_file); + } + + furi_check( + furi_mutex_acquire(worker->meta->mutex, FuriWaitForever) == FuriStatusOk); + furi_string_cat(worker->meta->prev_0_text, " FAIL"); + furi_mutex_release(worker->meta->mutex); + view_port_update(worker->meta->view_port); } // re-send file is paused mid-send @@ -410,18 +425,18 @@ void playlist_meta_reset(DisplayMeta* instance) { instance->current_count = 0; instance->current_playlist_repetition = 0; - furi_string_reset(instance->prev_0_path); - furi_string_reset(instance->prev_1_path); - furi_string_reset(instance->prev_2_path); - furi_string_reset(instance->prev_3_path); + furi_string_reset(instance->prev_0_text); + furi_string_reset(instance->prev_1_text); + furi_string_reset(instance->prev_2_text); + furi_string_reset(instance->prev_3_text); } DisplayMeta* playlist_meta_alloc() { DisplayMeta* instance = malloc(sizeof(DisplayMeta)); - instance->prev_0_path = furi_string_alloc(); - instance->prev_1_path = furi_string_alloc(); - instance->prev_2_path = furi_string_alloc(); - instance->prev_3_path = furi_string_alloc(); + instance->prev_0_text = furi_string_alloc(); + instance->prev_1_text = furi_string_alloc(); + instance->prev_2_text = furi_string_alloc(); + instance->prev_3_text = furi_string_alloc(); playlist_meta_reset(instance); instance->state = STATE_NONE; instance->playlist_repetitions = 1; @@ -429,10 +444,10 @@ DisplayMeta* playlist_meta_alloc() { } void playlist_meta_free(DisplayMeta* instance) { - furi_string_free(instance->prev_0_path); - furi_string_free(instance->prev_1_path); - furi_string_free(instance->prev_2_path); - furi_string_free(instance->prev_3_path); + furi_string_free(instance->prev_0_text); + furi_string_free(instance->prev_1_text); + furi_string_free(instance->prev_2_text); + furi_string_free(instance->prev_3_text); free(instance); } @@ -625,35 +640,51 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_set_font(canvas, FontSecondary); // current - if(!furi_string_empty(app->meta->prev_0_path)) { - path_extract_filename(app->meta->prev_0_path, temp_str, true); - int w = canvas_string_width(canvas, furi_string_get_cstr(temp_str)); + if(!furi_string_empty(app->meta->prev_0_text)) { + int w = canvas_string_width(canvas, furi_string_get_cstr(app->meta->prev_0_text)); canvas_set_color(canvas, ColorBlack); canvas_draw_rbox(canvas, 1, 1, w + 4, 12, 2); canvas_set_color(canvas, ColorWhite); canvas_draw_str_aligned( - canvas, 3, 3, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); + canvas, + 3, + 3, + AlignLeft, + AlignTop, + furi_string_get_cstr(app->meta->prev_0_text)); } // last 3 canvas_set_color(canvas, ColorBlack); - if(!furi_string_empty(app->meta->prev_1_path)) { - path_extract_filename(app->meta->prev_1_path, temp_str, true); + if(!furi_string_empty(app->meta->prev_1_text)) { canvas_draw_str_aligned( - canvas, 3, 15, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); + canvas, + 3, + 15, + AlignLeft, + AlignTop, + furi_string_get_cstr(app->meta->prev_1_text)); } - if(!furi_string_empty(app->meta->prev_2_path)) { - path_extract_filename(app->meta->prev_2_path, temp_str, true); + if(!furi_string_empty(app->meta->prev_2_text)) { canvas_draw_str_aligned( - canvas, 3, 26, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); + canvas, + 3, + 26, + AlignLeft, + AlignTop, + furi_string_get_cstr(app->meta->prev_2_text)); } - if(!furi_string_empty(app->meta->prev_3_path)) { - path_extract_filename(app->meta->prev_3_path, temp_str, true); + if(!furi_string_empty(app->meta->prev_3_text)) { canvas_draw_str_aligned( - canvas, 3, 37, AlignLeft, AlignTop, furi_string_get_cstr(temp_str)); + canvas, + 3, + 37, + AlignLeft, + AlignTop, + furi_string_get_cstr(app->meta->prev_3_text)); } } break; @@ -723,9 +754,7 @@ void playlist_free(Playlist* app) { free(app); } -int32_t playlist_app(void* p) { - UNUSED(p); - +int32_t playlist_app(char* p) { // create playlist folder { Storage* storage = furi_record_open(RECORD_STORAGE); @@ -739,11 +768,14 @@ int32_t playlist_app(void* p) { DisplayMeta* meta = playlist_meta_alloc(); Playlist* app = playlist_alloc(meta); meta->view_port = app->view_port; + meta->mutex = app->mutex; furi_hal_power_suppress_charge_enter(); // select playlist file - { + if(p && strlen(p)) { + furi_string_set(app->file_path, p); + } else { DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, PLAYLIST_EXT, &I_sub1_10px); @@ -769,6 +801,7 @@ int32_t playlist_app(void* p) { while(1) { // close application if no file was selected furi_check( furi_message_queue_get(app->input_queue, &input, FuriWaitForever) == FuriStatusOk); + furi_check(furi_mutex_acquire(app->mutex, FuriWaitForever) == FuriStatusOk); switch(input.key) { case InputKeyLeft: From 7d20ca4d26158bf6c941e1c730996094944053c1 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:45:09 +0300 Subject: [PATCH 04/36] upd totp --- base_pack/totp/application.fam | 2 +- base_pack/totp/cli/cli_shared_methods.c | 3 ++- base_pack/totp/cli/cli_shared_methods.h | 2 +- base_pack/totp/cli/plugins/export/export.c | 2 +- base_pack/totp/version.h | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/base_pack/totp/application.fam b/base_pack/totp/application.fam index b4e89b61dd5..1bd75518e3b 100644 --- a/base_pack/totp/application.fam +++ b/base_pack/totp/application.fam @@ -7,7 +7,7 @@ App( requires=["gui", "cli", "dialogs", "storage", "input", "notification", "bt"], stack_size=2 * 1024, order=20, - fap_version="5.140", + fap_version="5.141", fap_author="Alexander Kopachov (@akopachov)", fap_description="Software-based TOTP/HOTP authenticator for Flipper Zero device", fap_weburl="https://github.com/akopachov/flipper-zero_authenticator", diff --git a/base_pack/totp/cli/cli_shared_methods.c b/base_pack/totp/cli/cli_shared_methods.c index ce62d50f84b..1857bea2e66 100644 --- a/base_pack/totp/cli/cli_shared_methods.c +++ b/base_pack/totp/cli/cli_shared_methods.c @@ -26,7 +26,8 @@ bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) { return true; } -void totp_cli_force_close_app(FuriMessageQueue* event_queue) { +void totp_cli_force_close_app(void* ctx) { + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventForceCloseApp}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } diff --git a/base_pack/totp/cli/cli_shared_methods.h b/base_pack/totp/cli/cli_shared_methods.h index 3c706ce0f13..d2d287c8740 100644 --- a/base_pack/totp/cli/cli_shared_methods.h +++ b/base_pack/totp/cli/cli_shared_methods.h @@ -20,7 +20,7 @@ bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli); * @brief Forces application to be instantly closed * @param event_queue main app queue */ -void totp_cli_force_close_app(FuriMessageQueue* event_queue); +void totp_cli_force_close_app(void* ctx); /** * @brief Reads line of characters from console diff --git a/base_pack/totp/cli/plugins/export/export.c b/base_pack/totp/cli/plugins/export/export.c index dd3819194c1..781e556aacb 100644 --- a/base_pack/totp/cli/plugins/export/export.c +++ b/base_pack/totp/cli/plugins/export/export.c @@ -41,7 +41,7 @@ static void print_uri_component(const char* data, size_t length) { c == '-' || c == '_') { putchar(c); } else { - printf("%%%x", c); + printf("%%%02x", c); } c_ptr++; } diff --git a/base_pack/totp/version.h b/base_pack/totp/version.h index 6343f0cdaec..86fbad5aedc 100644 --- a/base_pack/totp/version.h +++ b/base_pack/totp/version.h @@ -2,4 +2,4 @@ #define TOTP_APP_VERSION_MAJOR (5) #define TOTP_APP_VERSION_MINOR (14) -#define TOTP_APP_VERSION_PATCH (0) \ No newline at end of file +#define TOTP_APP_VERSION_PATCH (1) \ No newline at end of file From 2c11e76fd5fd318acb6be4910c893760c415d852 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 5 Jun 2024 22:46:19 +0300 Subject: [PATCH 05/36] upd picopass --- base_pack/picopass/acknowledgements.h | 2 + .../scenes/picopass_scene_acknowledgements.c | 47 +++++++++++++++++++ .../picopass/scenes/picopass_scene_config.h | 1 + .../picopass/scenes/picopass_scene_start.c | 13 ++++- 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 base_pack/picopass/acknowledgements.h create mode 100644 base_pack/picopass/scenes/picopass_scene_acknowledgements.c diff --git a/base_pack/picopass/acknowledgements.h b/base_pack/picopass/acknowledgements.h new file mode 100644 index 00000000000..bc65cb76445 --- /dev/null +++ b/base_pack/picopass/acknowledgements.h @@ -0,0 +1,2 @@ +const char* acknowledgements_text = + "The developers of Picopass would like to humbly acknowledge the work of those who came before and made this possible.\nWe stand on the shoulders of giants.\nFlavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and Milosch Meriac for their research on iClass. Martin HS (holiman) for their work on the loclass library. Iceman and the Proxmark3 community."; diff --git a/base_pack/picopass/scenes/picopass_scene_acknowledgements.c b/base_pack/picopass/scenes/picopass_scene_acknowledgements.c new file mode 100644 index 00000000000..ada5ac73e6d --- /dev/null +++ b/base_pack/picopass/scenes/picopass_scene_acknowledgements.c @@ -0,0 +1,47 @@ +#include "../picopass_i.h" +#include +#include "../acknowledgements.h" + +void picopass_scene_acknowledgements_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + Picopass* picopass = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(picopass->view_dispatcher, result); + } +} + +void picopass_scene_acknowledgements_on_enter(void* context) { + Picopass* picopass = context; + + furi_string_reset(picopass->text_box_store); + + FuriString* str = picopass->text_box_store; + furi_string_cat_printf(str, "%s\n", acknowledgements_text); + + text_box_set_font(picopass->text_box, TextBoxFontText); + text_box_set_text(picopass->text_box, furi_string_get_cstr(picopass->text_box_store)); + view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewTextBox); +} + +bool picopass_scene_acknowledgements_on_event(void* context, SceneManagerEvent event) { + Picopass* picopass = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = scene_manager_previous_scene(picopass->scene_manager); + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_previous_scene(picopass->scene_manager); + } + return consumed; +} + +void picopass_scene_acknowledgements_on_exit(void* context) { + Picopass* picopass = context; + + // Clear views + text_box_reset(picopass->text_box); +} diff --git a/base_pack/picopass/scenes/picopass_scene_config.h b/base_pack/picopass/scenes/picopass_scene_config.h index 9eb5f7f5ff6..6a529d8aa37 100644 --- a/base_pack/picopass/scenes/picopass_scene_config.h +++ b/base_pack/picopass/scenes/picopass_scene_config.h @@ -22,3 +22,4 @@ ADD_SCENE(picopass, key_input, KeyInput) ADD_SCENE(picopass, nr_mac_saved, NrMacSaved) ADD_SCENE(picopass, more_info, MoreInfo) ADD_SCENE(picopass, formats, Formats) +ADD_SCENE(picopass, acknowledgements, Acknowledgements) diff --git a/base_pack/picopass/scenes/picopass_scene_start.c b/base_pack/picopass/scenes/picopass_scene_start.c index 2e1c95bc12b..3fed865f2c3 100644 --- a/base_pack/picopass/scenes/picopass_scene_start.c +++ b/base_pack/picopass/scenes/picopass_scene_start.c @@ -3,6 +3,7 @@ enum SubmenuIndex { SubmenuIndexRead, SubmenuIndexSaved, SubmenuIndexLoclass, + SubmenuIndexAcknowledgements, }; void picopass_scene_start_submenu_callback(void* context, uint32_t index) { @@ -17,9 +18,14 @@ void picopass_scene_start_on_enter(void* context) { submenu, "Read Card", SubmenuIndexRead, picopass_scene_start_submenu_callback, picopass); submenu_add_item( submenu, "Saved", SubmenuIndexSaved, picopass_scene_start_submenu_callback, picopass); - submenu_add_item( submenu, "Loclass", SubmenuIndexLoclass, picopass_scene_start_submenu_callback, picopass); + submenu_add_item( + submenu, + "Acknowledgements", + SubmenuIndexAcknowledgements, + picopass_scene_start_submenu_callback, + picopass); submenu_set_selected_item( submenu, scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneStart)); @@ -49,6 +55,11 @@ bool picopass_scene_start_on_event(void* context, SceneManagerEvent event) { picopass->scene_manager, PicopassSceneStart, PicopassSceneLoclass); scene_manager_next_scene(picopass->scene_manager, PicopassSceneLoclass); consumed = true; + } else if(event.event == SubmenuIndexAcknowledgements) { + scene_manager_set_scene_state( + picopass->scene_manager, PicopassSceneStart, PicopassSceneAcknowledgements); + scene_manager_next_scene(picopass->scene_manager, PicopassSceneAcknowledgements); + consumed = true; } } From 7a96cca20ebca2c0cde09b6ff457920ac2fb0dab Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:20:42 +0300 Subject: [PATCH 06/36] oof --- apps_source_code/Snake_2/snake_20.c | 10 ++++++---- apps_source_code/bluetooth-trigger/bt_trigger.c | 6 ++++-- apps_source_code/bluetooth-trigger/bt_trigger.h | 2 +- apps_source_code/bpmtapper/bpm.c | 5 +++-- apps_source_code/dice/dice_app.c | 10 ++++++---- apps_source_code/flipper-dcf77/dcf77_app.c | 10 ++++++---- apps_source_code/flipper-flashlight/flashlight.c | 5 +++-- .../flipperzero-tuning-fork/tuning_fork.c | 5 +++-- apps_source_code/game_of_life/game_of_life.c | 5 +++-- .../gpio_7segment/gpio_7segment_app.c | 5 +++-- apps_source_code/gpio_pins_reader/GPIO_reader.c | 5 +++-- .../ir_intervalometer/intervalometer.c | 5 +++-- apps_source_code/mandelbrot/mandelbrot.c | 5 +++-- apps_source_code/montyhall/monteyhall.c | 5 +++-- apps_source_code/racegame/race.c | 5 +++-- apps_source_code/rootoflife/roots_of_life_game.c | 10 ++++++---- .../scorched_tanks/scorched_tanks_game_app.c | 10 ++++++---- apps_source_code/servotester/servotester.c | 5 +++-- apps_source_code/t-rex-runner/trexrunner.c | 5 +++-- apps_source_code/timelapse/zeitraffer.c | 5 +++-- base_pack/arkanoid/arkanoid_game.c | 10 ++++++---- base_pack/blackjack/blackjack.c | 12 ++++++++---- base_pack/doom/doom.c | 10 ++++++---- base_pack/esp8266_deauth/esp8266_deauth.c | 5 +++-- base_pack/flappy_bird/flappy_bird.c | 10 ++++++---- base_pack/gps_nmea_uart/gps.c | 5 +++-- base_pack/hc_sr04/hc_sr04.c | 5 +++-- base_pack/heap_defence_game/heap_defence.c | 11 +++++++---- base_pack/jetpack_joyride/jetpack.c | 10 ++++++---- base_pack/metronome/metronome.c | 5 +++-- base_pack/mfkey/mfkey.c | 5 +++-- base_pack/mousejacker/mousejacker.c | 5 +++-- base_pack/multi_converter/multi_converter.c | 5 +++-- base_pack/nrfsniff/nrfsniff.c | 5 +++-- base_pack/sentry_safe/sentry_safe.c | 5 +++-- base_pack/solitaire/solitaire.c | 16 ++++++++++------ base_pack/tetris_game/tetris_game.c | 10 ++++++---- base_pack/tictactoe_game/tictactoe_game.c | 10 ++++++---- base_pack/wifi_scanner/wifi_scanner.c | 5 +++-- base_pack/zombiez/zombiez.c | 6 ++++-- .../FlipperNightStand_clock/clock_app.c | 7 +++++-- non_catalog_apps/chess_clock/chess_clock.c | 5 +++-- non_catalog_apps/flipper_plane/paperplane.c | 5 +++-- .../logic_analyzer/logic_analyzer_app.c | 5 +++-- non_catalog_apps/memsic_2125/memsic_2125_app.c | 6 ++++-- non_catalog_apps/mousejacker_ms/mousejacker.c | 5 +++-- non_catalog_apps/nrf24-batch/nrf24batch.c | 6 ++++-- non_catalog_apps/nrf24scan/nrf24scan.c | 6 ++++-- non_catalog_apps/nrfsniff_ms/nrfsniff.c | 5 +++-- non_catalog_apps/rc2014_coleco/coleco.c | 5 +++-- non_catalog_apps/secret_toggle/secret_toggle.c | 6 ++++-- non_catalog_apps/step_counter/stepcounter.c | 5 ++++- non_catalog_apps/tama_p1/tama_p1.c | 10 ++++++---- non_catalog_apps/tanksgame/tanks_game.c | 10 ++++++---- non_catalog_apps/usping/usping.c | 5 +++-- non_catalog_apps/wii_ec_anal/wii_anal.c | 10 ++++++---- 56 files changed, 233 insertions(+), 146 deletions(-) diff --git a/apps_source_code/Snake_2/snake_20.c b/apps_source_code/Snake_2/snake_20.c index b620814ec15..4401e6ae7be 100644 --- a/apps_source_code/Snake_2/snake_20.c +++ b/apps_source_code/Snake_2/snake_20.c @@ -191,15 +191,17 @@ static void snake_game_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(snake_state->mutex); } -static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void snake_game_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; SnakeEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void snake_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void snake_game_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; SnakeEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/bluetooth-trigger/bt_trigger.c b/apps_source_code/bluetooth-trigger/bt_trigger.c index 07873a9e2f3..9f213710e6a 100644 --- a/apps_source_code/bluetooth-trigger/bt_trigger.c +++ b/apps_source_code/bluetooth-trigger/bt_trigger.c @@ -201,9 +201,11 @@ static void input_callback(InputEvent* input_event, void* ctx) { } //Timer callback -static void timer_callback(FuriMessageQueue* event_queue) { +static void timer_callback(void* ctx) { //check eventqueue is not null - furi_assert(event_queue); + furi_assert(ctx); + //Getting our event queue + FuriMessageQueue* event_queue = ctx; //creating event and adding it to the event list IosTriggerEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/bluetooth-trigger/bt_trigger.h b/apps_source_code/bluetooth-trigger/bt_trigger.h index a89cc316281..15516f00432 100644 --- a/apps_source_code/bluetooth-trigger/bt_trigger.h +++ b/apps_source_code/bluetooth-trigger/bt_trigger.h @@ -47,7 +47,7 @@ typedef struct { static void draw_callback(Canvas* canvas, void* ctx); static void input_callback(InputEvent* input_event, void* ctx); -static void timer_callback(FuriMessageQueue* event_queue); +static void timer_callback(void* ctx); static void bt_hid_connection_status_changed_callback(BtStatus status, void* context); AppStruct* appStructAlloc(); void cleanUpBeforeYouLeave(AppStruct* app); diff --git a/apps_source_code/bpmtapper/bpm.c b/apps_source_code/bpmtapper/bpm.c index 097d0a9a380..0c08642f3d2 100644 --- a/apps_source_code/bpmtapper/bpm.c +++ b/apps_source_code/bpmtapper/bpm.c @@ -119,8 +119,9 @@ static void show_hello() { // END HELLO DIALOG } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/apps_source_code/dice/dice_app.c b/apps_source_code/dice/dice_app.c index b7231c5fc0f..95058843a9c 100644 --- a/apps_source_code/dice/dice_app.c +++ b/apps_source_code/dice/dice_app.c @@ -270,15 +270,17 @@ static void draw_callback(Canvas* canvas, void* ctx) { furi_mutex_release(state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; AppEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; AppEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/flipper-dcf77/dcf77_app.c b/apps_source_code/flipper-dcf77/dcf77_app.c index bdbe7096ec7..50ea2c34ceb 100644 --- a/apps_source_code/flipper-dcf77/dcf77_app.c +++ b/apps_source_code/flipper-dcf77/dcf77_app.c @@ -223,15 +223,17 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(app_fsm->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; AppEvent event = {.type = EventKeyPress, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void timer_tick_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void timer_tick_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; AppEvent event = {.type = EventTimerTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/flipper-flashlight/flashlight.c b/apps_source_code/flipper-flashlight/flashlight.c index 79cfe7f60c9..2a36f455937 100644 --- a/apps_source_code/flipper-flashlight/flashlight.c +++ b/apps_source_code/flipper-flashlight/flashlight.c @@ -48,8 +48,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/apps_source_code/flipperzero-tuning-fork/tuning_fork.c b/apps_source_code/flipperzero-tuning-fork/tuning_fork.c index 8326429c706..0538bcd1fbf 100644 --- a/apps_source_code/flipperzero-tuning-fork/tuning_fork.c +++ b/apps_source_code/flipperzero-tuning-fork/tuning_fork.c @@ -187,8 +187,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(tuning_fork_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/apps_source_code/game_of_life/game_of_life.c b/apps_source_code/game_of_life/game_of_life.c index 892e3754015..f4c21204ce9 100644 --- a/apps_source_code/game_of_life/game_of_life.c +++ b/apps_source_code/game_of_life/game_of_life.c @@ -85,8 +85,9 @@ static void update_field(State* state) { } } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; AppEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/gpio_7segment/gpio_7segment_app.c b/apps_source_code/gpio_7segment/gpio_7segment_app.c index 3b194287b70..6c72b277055 100644 --- a/apps_source_code/gpio_7segment/gpio_7segment_app.c +++ b/apps_source_code/gpio_7segment/gpio_7segment_app.c @@ -101,8 +101,9 @@ typedef struct { // Invoked when input (button press) is detected. Queues message and returns to caller. // @param input_event the input event that caused the callback to be invoked. // @param queue the message queue for queueing key event. -static void gpio_7segment_input_callback(InputEvent* input_event, FuriMessageQueue* queue) { - furi_assert(queue); +static void gpio_7segment_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* queue = ctx; GpioEvent event = {.type = GpioEventTypeKey, .input = *input_event}; furi_message_queue_put(queue, &event, FuriWaitForever); } diff --git a/apps_source_code/gpio_pins_reader/GPIO_reader.c b/apps_source_code/gpio_pins_reader/GPIO_reader.c index e3659baba7b..7a46a713d52 100644 --- a/apps_source_code/gpio_pins_reader/GPIO_reader.c +++ b/apps_source_code/gpio_pins_reader/GPIO_reader.c @@ -63,8 +63,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/apps_source_code/ir_intervalometer/intervalometer.c b/apps_source_code/ir_intervalometer/intervalometer.c index 2bad93e78e6..a43fe737601 100644 --- a/apps_source_code/ir_intervalometer/intervalometer.c +++ b/apps_source_code/ir_intervalometer/intervalometer.c @@ -478,8 +478,9 @@ static void flipvalo_run_state_init(struct flipvalo_run_state* fv_run_state) { fv_run_state->tick_cur = 0; } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; struct plugin_event event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } diff --git a/apps_source_code/mandelbrot/mandelbrot.c b/apps_source_code/mandelbrot/mandelbrot.c index 628bb0a0749..3777d2bfa33 100644 --- a/apps_source_code/mandelbrot/mandelbrot.c +++ b/apps_source_code/mandelbrot/mandelbrot.c @@ -78,8 +78,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/apps_source_code/montyhall/monteyhall.c b/apps_source_code/montyhall/monteyhall.c index 69a91f048ff..f5b595868e5 100644 --- a/apps_source_code/montyhall/monteyhall.c +++ b/apps_source_code/montyhall/monteyhall.c @@ -301,8 +301,9 @@ static void montyhall_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(monty_state->mutex); } -static void montyhall_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void montyhall_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; furi_message_queue_put(event_queue, input_event, FuriWaitForever); } diff --git a/apps_source_code/racegame/race.c b/apps_source_code/racegame/race.c index eb1a8856a44..31aad9e2710 100644 --- a/apps_source_code/racegame/race.c +++ b/apps_source_code/racegame/race.c @@ -160,8 +160,9 @@ static void input_callback(InputEvent* input_event, void* ctx) { furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; RaceGameEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); } diff --git a/apps_source_code/rootoflife/roots_of_life_game.c b/apps_source_code/rootoflife/roots_of_life_game.c index c1f521f0ccb..0cb0cec6efe 100644 --- a/apps_source_code/rootoflife/roots_of_life_game.c +++ b/apps_source_code/rootoflife/roots_of_life_game.c @@ -603,15 +603,17 @@ static void roots_draw_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(state->mutex); } -static void roots_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void roots_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void roots_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void roots_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/scorched_tanks/scorched_tanks_game_app.c b/apps_source_code/scorched_tanks/scorched_tanks_game_app.c index eee945c84da..cb3250cb9d0 100644 --- a/apps_source_code/scorched_tanks/scorched_tanks_game_app.c +++ b/apps_source_code/scorched_tanks/scorched_tanks_game_app.c @@ -350,15 +350,17 @@ static void scorched_tanks_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(game_state->mutex); } -static void scorched_tanks_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void scorched_tanks_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; ScorchedTanksEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void scorched_tanks_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void scorched_tanks_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; ScorchedTanksEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/servotester/servotester.c b/apps_source_code/servotester/servotester.c index fabc5d03418..f471b9888f1 100644 --- a/apps_source_code/servotester/servotester.c +++ b/apps_source_code/servotester/servotester.c @@ -67,8 +67,9 @@ static void servotester_input_callback(InputEvent* input_event, void* ctx) { furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void servotester_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void servotester_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; ServoTesterEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/apps_source_code/t-rex-runner/trexrunner.c b/apps_source_code/t-rex-runner/trexrunner.c index f1e8079273c..6ef1c86d4b0 100644 --- a/apps_source_code/t-rex-runner/trexrunner.c +++ b/apps_source_code/t-rex-runner/trexrunner.c @@ -136,8 +136,9 @@ static void timer_callback(void* ctx) { furi_mutex_release(game_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/apps_source_code/timelapse/zeitraffer.c b/apps_source_code/timelapse/zeitraffer.c index 46aa6f87bfb..9495f954044 100644 --- a/apps_source_code/timelapse/zeitraffer.c +++ b/apps_source_code/timelapse/zeitraffer.c @@ -106,9 +106,10 @@ static void input_callback(InputEvent* input_event, void* ctx) { furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void timer_callback(FuriMessageQueue* event_queue) { +static void timer_callback(void* ctx) { // Проверяем, что контекст не нулевой - furi_assert(event_queue); + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; ZeitrafferEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/base_pack/arkanoid/arkanoid_game.c b/base_pack/arkanoid/arkanoid_game.c index 2cda17039c0..0eec3bf6eb3 100644 --- a/base_pack/arkanoid/arkanoid_game.c +++ b/base_pack/arkanoid/arkanoid_game.c @@ -355,15 +355,17 @@ static void arkanoid_draw_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(arkanoid_state->mutex); } -static void arkanoid_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void arkanoid_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void arkanoid_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void arkanoid_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/base_pack/blackjack/blackjack.c b/base_pack/blackjack/blackjack.c index 9b714f67d1e..4cb49364066 100644 --- a/base_pack/blackjack/blackjack.c +++ b/base_pack/blackjack/blackjack.c @@ -463,14 +463,18 @@ void init(GameState* game_state) { start_round(game_state); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + AppEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + AppEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); } diff --git a/base_pack/doom/doom.c b/base_pack/doom/doom.c index 20397692e2a..dc6b438b6bf 100644 --- a/base_pack/doom/doom.c +++ b/base_pack/doom/doom.c @@ -794,8 +794,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, 0); @@ -844,8 +845,9 @@ static void doom_state_init(PluginState* const plugin_state) { #endif } -static void doom_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void doom_game_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/base_pack/esp8266_deauth/esp8266_deauth.c b/base_pack/esp8266_deauth/esp8266_deauth.c index 215a1e2ac93..0d8cf3c4dbc 100644 --- a/base_pack/esp8266_deauth/esp8266_deauth.c +++ b/base_pack/esp8266_deauth/esp8266_deauth.c @@ -205,8 +205,9 @@ static void esp8266_deauth_module_render_callback(Canvas* const canvas, void* ct } static void - esp8266_deauth_module_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); + esp8266_deauth_module_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; SPluginEvent event = {.m_type = EventTypeKey, .m_input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/flappy_bird/flappy_bird.c b/base_pack/flappy_bird/flappy_bird.c index cd591f0a2e4..13681db0b6d 100644 --- a/base_pack/flappy_bird/flappy_bird.c +++ b/base_pack/flappy_bird/flappy_bird.c @@ -269,15 +269,17 @@ static void flappy_game_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(game_state->mutex); } -static void flappy_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void flappy_game_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void flappy_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void flappy_game_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/base_pack/gps_nmea_uart/gps.c b/base_pack/gps_nmea_uart/gps.c index 85a4157db41..905c90c9208 100644 --- a/base_pack/gps_nmea_uart/gps.c +++ b/base_pack/gps_nmea_uart/gps.c @@ -123,8 +123,9 @@ static void render_callback(Canvas* const canvas, void* context) { furi_mutex_release(gps_uart->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/hc_sr04/hc_sr04.c b/base_pack/hc_sr04/hc_sr04.c index 5cdeac3f7d3..0a61fc77409 100644 --- a/base_pack/hc_sr04/hc_sr04.c +++ b/base_pack/hc_sr04/hc_sr04.c @@ -89,8 +89,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/heap_defence_game/heap_defence.c b/base_pack/heap_defence_game/heap_defence.c index 1f2b0f56d8c..948e342b569 100644 --- a/base_pack/heap_defence_game/heap_defence.c +++ b/base_pack/heap_defence_game/heap_defence.c @@ -484,16 +484,19 @@ static void heap_defense_render_callback(Canvas* const canvas, void* mutex) { furi_mutex_release(game->mutex); } -static void heap_defense_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { +static void heap_defense_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + if(input_event->type != InputTypePress && input_event->type != InputTypeLong) return; - furi_assert(event_queue); GameEvent event = {.type = EventKeyPress, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void heap_defense_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void heap_defense_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event; event.type = EventGameTick; diff --git a/base_pack/jetpack_joyride/jetpack.c b/base_pack/jetpack_joyride/jetpack.c index 2bbb6075c45..99b77cd819c 100644 --- a/base_pack/jetpack_joyride/jetpack.c +++ b/base_pack/jetpack_joyride/jetpack.c @@ -257,15 +257,17 @@ static void jetpack_game_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(game_state->mutex); } -static void jetpack_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void jetpack_game_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void jetpack_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void jetpack_game_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/base_pack/metronome/metronome.c b/base_pack/metronome/metronome.c index 4cfbeee7e2a..d65ea66ea7e 100644 --- a/base_pack/metronome/metronome.c +++ b/base_pack/metronome/metronome.c @@ -135,8 +135,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(metronome_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/mfkey/mfkey.c b/base_pack/mfkey/mfkey.c index 034a56b5978..38b84240e7f 100644 --- a/base_pack/mfkey/mfkey.c +++ b/base_pack/mfkey/mfkey.c @@ -756,8 +756,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(program_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/mousejacker/mousejacker.c b/base_pack/mousejacker/mousejacker.c index 367f5e8ab61..549b8ecba71 100644 --- a/base_pack/mousejacker/mousejacker.c +++ b/base_pack/mousejacker/mousejacker.c @@ -92,8 +92,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/multi_converter/multi_converter.c b/base_pack/multi_converter/multi_converter.c index a31d4c773cd..de51970fd0d 100644 --- a/base_pack/multi_converter/multi_converter.c +++ b/base_pack/multi_converter/multi_converter.c @@ -22,8 +22,9 @@ static void multi_converter_render_callback(Canvas* const canvas, void* ctx) { } static void - multi_converter_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); + multi_converter_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; MultiConverterEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/nrfsniff/nrfsniff.c b/base_pack/nrfsniff/nrfsniff.c index d948a533acf..51e7be5d837 100644 --- a/base_pack/nrfsniff/nrfsniff.c +++ b/base_pack/nrfsniff/nrfsniff.c @@ -128,8 +128,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/sentry_safe/sentry_safe.c b/base_pack/sentry_safe/sentry_safe.c index b208b7629ea..afbceb27139 100644 --- a/base_pack/sentry_safe/sentry_safe.c +++ b/base_pack/sentry_safe/sentry_safe.c @@ -45,8 +45,9 @@ static void sentry_safe_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(sentry_state->mutex); } -static void sentry_safe_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void sentry_safe_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; Event event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/solitaire/solitaire.c b/base_pack/solitaire/solitaire.c index 92b971662ce..c8a2a6dd6bf 100644 --- a/base_pack/solitaire/solitaire.c +++ b/base_pack/solitaire/solitaire.c @@ -434,14 +434,18 @@ void init_start(GameState *game_state) { } -static void input_callback(InputEvent *input_event, FuriMessageQueue *event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent *input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + AppEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void update_timer_callback(FuriMessageQueue *event_queue) { - furi_assert(event_queue); +static void update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + AppEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); } @@ -449,8 +453,8 @@ static void update_timer_callback(FuriMessageQueue *event_queue) { int32_t solitaire_app(void *p) { UNUSED(p); int32_t return_code = 0; - FuriMessageQueue *event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); - GameState *game_state = malloc(sizeof(GameState)); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(AppEvent)); + GameState* game_state = malloc(sizeof(GameState)); init_start(game_state); set_card_graphics(&I_card_graphics); diff --git a/base_pack/tetris_game/tetris_game.c b/base_pack/tetris_game/tetris_game.c index e4e9543a024..4c4a41a3e70 100644 --- a/base_pack/tetris_game/tetris_game.c +++ b/base_pack/tetris_game/tetris_game.c @@ -229,8 +229,9 @@ static void tetris_game_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(tetris_state->mutex); } -static void tetris_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tetris_game_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; TetrisEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); @@ -382,8 +383,9 @@ static bool tetris_game_piece_at_bottom(TetrisState* tetris_state, Piece* newPie return false; } -static void tetris_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tetris_game_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; TetrisEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/tictactoe_game/tictactoe_game.c b/base_pack/tictactoe_game/tictactoe_game.c index f0f9b6dbcca..db1be8f445e 100644 --- a/base_pack/tictactoe_game/tictactoe_game.c +++ b/base_pack/tictactoe_game/tictactoe_game.c @@ -288,15 +288,17 @@ static void tictactoe_draw_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(ticst->mutex); } -static void tictactoe_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tictactoe_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void tictactoe_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tictactoe_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; GameEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/base_pack/wifi_scanner/wifi_scanner.c b/base_pack/wifi_scanner/wifi_scanner.c index 52b399102dc..12e1c06d15a 100644 --- a/base_pack/wifi_scanner/wifi_scanner.c +++ b/base_pack/wifi_scanner/wifi_scanner.c @@ -636,8 +636,9 @@ static void wifi_module_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(app->mutex); } -static void wifi_module_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void wifi_module_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; SPluginEvent event = {.m_type = EventTypeKey, .m_input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/base_pack/zombiez/zombiez.c b/base_pack/zombiez/zombiez.c index 4c135f13959..3c646a80219 100644 --- a/base_pack/zombiez/zombiez.c +++ b/base_pack/zombiez/zombiez.c @@ -184,8 +184,10 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } diff --git a/non_catalog_apps/FlipperNightStand_clock/clock_app.c b/non_catalog_apps/FlipperNightStand_clock/clock_app.c index f356a88c072..4f2fe9cafbb 100644 --- a/non_catalog_apps/FlipperNightStand_clock/clock_app.c +++ b/non_catalog_apps/FlipperNightStand_clock/clock_app.c @@ -82,13 +82,16 @@ void handle_down() { set_backlight_brightness((float)(brightness / 100.f)); } -static void clock_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void clock_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } //do you are have stupid? +// idk who left that comment here, but i don't have stupid sorry void elements_progress_bar_vertical( Canvas* canvas, uint8_t x, diff --git a/non_catalog_apps/chess_clock/chess_clock.c b/non_catalog_apps/chess_clock/chess_clock.c index c463bd0cfc0..f105f06993f 100644 --- a/non_catalog_apps/chess_clock/chess_clock.c +++ b/non_catalog_apps/chess_clock/chess_clock.c @@ -60,8 +60,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { elements_multiline_text_aligned(canvas, 64, 32, AlignCenter, AlignCenter, text); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/non_catalog_apps/flipper_plane/paperplane.c b/non_catalog_apps/flipper_plane/paperplane.c index 632bc3b41c2..2b62aec60a3 100644 --- a/non_catalog_apps/flipper_plane/paperplane.c +++ b/non_catalog_apps/flipper_plane/paperplane.c @@ -44,8 +44,9 @@ static void timer_callback(void* ctx) { furi_mutex_release(game_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/non_catalog_apps/logic_analyzer/logic_analyzer_app.c b/non_catalog_apps/logic_analyzer/logic_analyzer_app.c index 9ac4a5c0827..31a3faa747d 100644 --- a/non_catalog_apps/logic_analyzer/logic_analyzer_app.c +++ b/non_catalog_apps/logic_analyzer/logic_analyzer_app.c @@ -83,8 +83,9 @@ static void render_callback(Canvas* const canvas, void* cb_ctx) { furi_mutex_release(app->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; /* better skip than sorry */ if(furi_message_queue_get_count(event_queue) < QUEUE_SIZE) { diff --git a/non_catalog_apps/memsic_2125/memsic_2125_app.c b/non_catalog_apps/memsic_2125/memsic_2125_app.c index aeceb3e5dd8..3751044a502 100644 --- a/non_catalog_apps/memsic_2125/memsic_2125_app.c +++ b/non_catalog_apps/memsic_2125/memsic_2125_app.c @@ -64,8 +64,10 @@ typedef struct { // We queue a message and then return to the caller. // @input_event the button that triggered the callback. // @queue our message queue. -static void input_callback(InputEvent* input_event, FuriMessageQueue* queue) { - furi_assert(queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* queue = ctx; + DemoEvent event = {.type = DemoEventTypeKey, .input = *input_event}; furi_message_queue_put(queue, &event, FuriWaitForever); } diff --git a/non_catalog_apps/mousejacker_ms/mousejacker.c b/non_catalog_apps/mousejacker_ms/mousejacker.c index d3daf7d9c04..0ea16d217e1 100644 --- a/non_catalog_apps/mousejacker_ms/mousejacker.c +++ b/non_catalog_apps/mousejacker_ms/mousejacker.c @@ -86,8 +86,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/non_catalog_apps/nrf24-batch/nrf24batch.c b/non_catalog_apps/nrf24-batch/nrf24batch.c index 180a19a09d0..dd14a1c7399 100644 --- a/non_catalog_apps/nrf24-batch/nrf24batch.c +++ b/non_catalog_apps/nrf24-batch/nrf24batch.c @@ -1091,8 +1091,10 @@ static void save_batch(void) { } } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } diff --git a/non_catalog_apps/nrf24scan/nrf24scan.c b/non_catalog_apps/nrf24scan/nrf24scan.c index 5a746ad7d7e..7ff07d839c5 100644 --- a/non_catalog_apps/nrf24scan/nrf24scan.c +++ b/non_catalog_apps/nrf24scan/nrf24scan.c @@ -456,8 +456,10 @@ static uint8_t load_settings_file(Stream* file_stream) { return err; } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } diff --git a/non_catalog_apps/nrfsniff_ms/nrfsniff.c b/non_catalog_apps/nrfsniff_ms/nrfsniff.c index e4cf5d3b1d9..33f9add0745 100644 --- a/non_catalog_apps/nrfsniff_ms/nrfsniff.c +++ b/non_catalog_apps/nrfsniff_ms/nrfsniff.c @@ -129,8 +129,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/non_catalog_apps/rc2014_coleco/coleco.c b/non_catalog_apps/rc2014_coleco/coleco.c index 311b0ceacd8..f886aa0244c 100644 --- a/non_catalog_apps/rc2014_coleco/coleco.c +++ b/non_catalog_apps/rc2014_coleco/coleco.c @@ -131,8 +131,9 @@ static void render_callback(Canvas* const canvas, void* context) { furi_mutex_release(coleco->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/non_catalog_apps/secret_toggle/secret_toggle.c b/non_catalog_apps/secret_toggle/secret_toggle.c index 04b3f73caae..463e2eca930 100644 --- a/non_catalog_apps/secret_toggle/secret_toggle.c +++ b/non_catalog_apps/secret_toggle/secret_toggle.c @@ -232,8 +232,10 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_string_free(tempStatusStr); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } diff --git a/non_catalog_apps/step_counter/stepcounter.c b/non_catalog_apps/step_counter/stepcounter.c index 17097fa4f84..8583098645b 100644 --- a/non_catalog_apps/step_counter/stepcounter.c +++ b/non_catalog_apps/step_counter/stepcounter.c @@ -65,7 +65,10 @@ void step_callback(void* ctx) { } } -static void input_callback(InputEvent* input_event, FuriMessageQueue* queue) { +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* queue = ctx; + StepCounterEvent event = { .type = StepCounterEventTypeKey, .input_event.key = input_event->key, diff --git a/non_catalog_apps/tama_p1/tama_p1.c b/non_catalog_apps/tama_p1/tama_p1.c index 93db6775dfd..acafba5dcc9 100644 --- a/non_catalog_apps/tama_p1/tama_p1.c +++ b/non_catalog_apps/tama_p1/tama_p1.c @@ -458,15 +458,17 @@ static void tama_p1_draw_callback(Canvas* const canvas, void* cb_ctx) { furi_mutex_release(mutex); } -static void tama_p1_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tama_p1_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; TamaEvent event = {.type = EventTypeInput, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void tama_p1_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tama_p1_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; TamaEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/non_catalog_apps/tanksgame/tanks_game.c b/non_catalog_apps/tanksgame/tanks_game.c index 01c160a7a27..392886d27e0 100644 --- a/non_catalog_apps/tanksgame/tanks_game.c +++ b/non_catalog_apps/tanksgame/tanks_game.c @@ -619,15 +619,17 @@ static void tanks_game_render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(tanks_state->mutex); } -static void tanks_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tanks_game_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; TanksEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); } -static void tanks_game_update_timer_callback(FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void tanks_game_update_timer_callback(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; TanksEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); diff --git a/non_catalog_apps/usping/usping.c b/non_catalog_apps/usping/usping.c index adaf8d7de5f..562c2fa0284 100644 --- a/non_catalog_apps/usping/usping.c +++ b/non_catalog_apps/usping/usping.c @@ -91,8 +91,9 @@ static void render_callback(Canvas* const canvas, void* ctx) { furi_mutex_release(plugin_state->mutex); } -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); +static void input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; PluginEvent event = {.type = EventTypeKey, .input = *input_event}; furi_message_queue_put(event_queue, &event, FuriWaitForever); diff --git a/non_catalog_apps/wii_ec_anal/wii_anal.c b/non_catalog_apps/wii_ec_anal/wii_anal.c index 4f1c97d87c7..1dbc2782d25 100644 --- a/non_catalog_apps/wii_ec_anal/wii_anal.c +++ b/non_catalog_apps/wii_ec_anal/wii_anal.c @@ -44,9 +44,10 @@ // OS Callback : Timer tick // We register this function to be called when the OS signals a timer 'tick' event // -static void cbTimer(FuriMessageQueue* queue) { +static void cbTimer(void* ctx) { ENTER; - furi_assert(queue); + furi_assert(ctx); + FuriMessageQueue* queue = ctx; eventMsg_t message = {.id = EVID_TICK}; furi_message_queue_put(queue, &message, 0); @@ -59,10 +60,11 @@ static void cbTimer(FuriMessageQueue* queue) { // OS Callback : Keypress // We register this function to be called when the OS detects a keypress // -static void cbInput(InputEvent* event, FuriMessageQueue* queue) { +static void cbInput(InputEvent* event, void* ctx) { ENTER; - furi_assert(queue); + furi_assert(ctx); furi_assert(event); + FuriMessageQueue* queue = ctx; // Put an "input" event message on the message queue eventMsg_t message = {.id = EVID_KEY, .input = *event}; From 8ae634eff0012466e2e23224e8fc3314b23606a8 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:22:37 +0300 Subject: [PATCH 07/36] no server :( --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index ef574322cf4..6b8bf3bf101 100644 --- a/.drone.yml +++ b/.drone.yml @@ -143,4 +143,4 @@ trigger: - tag node: - typ: dev1 + typ: dev2 From 2808debcbbc973b6c8933eb5ca89d7f9b9fddfa0 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:23:05 +0300 Subject: [PATCH 08/36] upd readme --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 4d00257b18a..c13be39abf5 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -13,7 +13,7 @@ Apps contains changes needed to compile them on latest firmware, fixes has been The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done. -### Apps checked & updated at `24 May 23:18 GMT +3` +### Apps checked & updated at `6 Jun 00:22 GMT +3` # Default pack From 3149ec5bf479bde83dc6c8615c266019398d25bb Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:45:44 +0300 Subject: [PATCH 09/36] fix for latest API --- base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c | 3 +-- .../esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c b/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c index 6b9c6f595a2..cf4c11022d5 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c +++ b/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c @@ -48,8 +48,7 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { if(!rfal_platform.thread) { rfal_platform.thread = - furi_thread_alloc_ex("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); - furi_thread_mark_as_service(rfal_platform.thread); + furi_thread_alloc_service("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); furi_thread_set_priority(rfal_platform.thread, FuriThreadPriorityIsr); furi_thread_start(rfal_platform.thread); } diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c index 6b9c6f595a2..cf4c11022d5 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c @@ -48,8 +48,7 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { if(!rfal_platform.thread) { rfal_platform.thread = - furi_thread_alloc_ex("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); - furi_thread_mark_as_service(rfal_platform.thread); + furi_thread_alloc_service("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); furi_thread_set_priority(rfal_platform.thread, FuriThreadPriorityIsr); furi_thread_start(rfal_platform.thread); } From bc4e5f0d8d229ca8bc8f16f69910982397da00ea Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 01:56:01 +0300 Subject: [PATCH 10/36] fix mutex --- apps_source_code/counter/counter.c | 2 +- apps_source_code/flipper_passgen/passgen.c | 2 +- apps_source_code/flipperzero-slots/slotmachine.c | 2 +- apps_source_code/videopoker/poker.c | 2 +- base_pack/doom/sound.h | 2 +- base_pack/game15/sandbox.c | 2 +- base_pack/morse_code/morse_code.c | 2 +- base_pack/music_player/music_player.c | 2 +- non_catalog_apps/flipperzero-qrcode/qrcode_app.c | 2 +- non_catalog_apps/multi_counter/counter.c | 2 +- non_catalog_apps/music_beeper/music_beeper.c | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps_source_code/counter/counter.c b/apps_source_code/counter/counter.c index 8bc625a1f3d..5102ff8860a 100644 --- a/apps_source_code/counter/counter.c +++ b/apps_source_code/counter/counter.c @@ -20,7 +20,7 @@ typedef struct { FuriMessageQueue* input_queue; ViewPort* view_port; Gui* gui; - FuriMutex** mutex; + FuriMutex* mutex; NotificationApp* notifications; int count; diff --git a/apps_source_code/flipper_passgen/passgen.c b/apps_source_code/flipper_passgen/passgen.c index 7585eda26d4..2e5301e439c 100644 --- a/apps_source_code/flipper_passgen/passgen.c +++ b/apps_source_code/flipper_passgen/passgen.c @@ -62,7 +62,7 @@ typedef struct { FuriMessageQueue* input_queue; ViewPort* view_port; Gui* gui; - FuriMutex** mutex; + FuriMutex* mutex; NotificationApp* notify; const char* alphabet; char password[PASSGEN_MAX_LENGTH + 1]; diff --git a/apps_source_code/flipperzero-slots/slotmachine.c b/apps_source_code/flipperzero-slots/slotmachine.c index fd89fd22784..6a376e8a361 100644 --- a/apps_source_code/flipperzero-slots/slotmachine.c +++ b/apps_source_code/flipperzero-slots/slotmachine.c @@ -24,7 +24,7 @@ typedef struct { Gui* gui; // container gui ViewPort* view_port; // current viewport FuriMessageQueue* input_queue; // Input Events queue - FuriMutex** model_mutex; // mutex for safe threads + FuriMutex* model_mutex; // mutex for safe threads uint16_t bet; double money, winamount; SlotColumn* columns[4]; diff --git a/apps_source_code/videopoker/poker.c b/apps_source_code/videopoker/poker.c index b31deae5936..470549e72aa 100644 --- a/apps_source_code/videopoker/poker.c +++ b/apps_source_code/videopoker/poker.c @@ -38,7 +38,7 @@ typedef struct { } PokerPlayer_card; typedef struct { - FuriMutex** model_mutex; + FuriMutex* model_mutex; FuriMessageQueue* event_queue; ViewPort* view_port; Gui* gui; diff --git a/base_pack/doom/sound.h b/base_pack/doom/sound.h index 514381334b1..a6f5ada4710 100644 --- a/base_pack/doom/sound.h +++ b/base_pack/doom/sound.h @@ -28,7 +28,7 @@ typedef struct { typedef struct { MusicPlayerModel* model; MusicPlayerWorker* worker; - FuriMutex** model_mutex; + FuriMutex* model_mutex; } MusicPlayer; #endif \ No newline at end of file diff --git a/base_pack/game15/sandbox.c b/base_pack/game15/sandbox.c index e6fcfc61295..db19191eb65 100644 --- a/base_pack/game15/sandbox.c +++ b/base_pack/game15/sandbox.c @@ -3,7 +3,7 @@ #include "sandbox.h" FuriMessageQueue* sandbox_event_queue; -FuriMutex** sandbox_mutex; +FuriMutex* sandbox_mutex; ViewPort* sandbox_view_port; Gui* sandbox_gui; FuriTimer* sandbox_timer; diff --git a/base_pack/morse_code/morse_code.c b/base_pack/morse_code/morse_code.c index 3f96969e7db..bef9132e6da 100644 --- a/base_pack/morse_code/morse_code.c +++ b/base_pack/morse_code/morse_code.c @@ -17,7 +17,7 @@ typedef struct { typedef struct { MorseCodeModel* model; - FuriMutex** model_mutex; + FuriMutex* model_mutex; FuriMessageQueue* input_queue; diff --git a/base_pack/music_player/music_player.c b/base_pack/music_player/music_player.c index c353f207537..12803ef0f0f 100644 --- a/base_pack/music_player/music_player.c +++ b/base_pack/music_player/music_player.c @@ -28,7 +28,7 @@ typedef struct { typedef struct { MusicPlayerModel* model; - FuriMutex** model_mutex; + FuriMutex* model_mutex; FuriMessageQueue* input_queue; diff --git a/non_catalog_apps/flipperzero-qrcode/qrcode_app.c b/non_catalog_apps/flipperzero-qrcode/qrcode_app.c index 49a48e55105..f65c657471c 100644 --- a/non_catalog_apps/flipperzero-qrcode/qrcode_app.c +++ b/non_catalog_apps/flipperzero-qrcode/qrcode_app.c @@ -59,7 +59,7 @@ typedef struct { Gui* gui; ViewPort* view_port; - FuriMutex** mutex; + FuriMutex* mutex; FuriString* message; QRCode* qrcode; uint8_t min_mode; diff --git a/non_catalog_apps/multi_counter/counter.c b/non_catalog_apps/multi_counter/counter.c index c4e85e32fc5..a07bbe0ebdd 100644 --- a/non_catalog_apps/multi_counter/counter.c +++ b/non_catalog_apps/multi_counter/counter.c @@ -26,7 +26,7 @@ typedef struct { ViewPort* view_port; Gui* gui; NotificationApp* notification; - FuriMutex** mutex; + FuriMutex* mutex; bool togglelight; int count; diff --git a/non_catalog_apps/music_beeper/music_beeper.c b/non_catalog_apps/music_beeper/music_beeper.c index d6b06bb05b4..47888667bea 100644 --- a/non_catalog_apps/music_beeper/music_beeper.c +++ b/non_catalog_apps/music_beeper/music_beeper.c @@ -28,7 +28,7 @@ typedef struct { typedef struct { MusicBeeperModel* model; - FuriMutex** model_mutex; + FuriMutex* model_mutex; FuriMessageQueue* input_queue; From fcb3503d4e5ed46beeeb4152e4813dcbf261666f Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 12:13:05 +0300 Subject: [PATCH 11/36] fix build --- base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c | 2 +- .../esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c b/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c index cf4c11022d5..cc1a1f19366 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c +++ b/base_pack/mifare_nested/lib/nfclegacy/ST25RFAL002/platform.c @@ -48,7 +48,7 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { if(!rfal_platform.thread) { rfal_platform.thread = - furi_thread_alloc_service("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); + furi_thread_alloc_ex("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); furi_thread_set_priority(rfal_platform.thread, FuriThreadPriorityIsr); furi_thread_start(rfal_platform.thread); } diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c index cf4c11022d5..cc1a1f19366 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/ST25RFAL002/platform.c @@ -48,7 +48,7 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { if(!rfal_platform.thread) { rfal_platform.thread = - furi_thread_alloc_service("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); + furi_thread_alloc_ex("RfalIrqDriver", 1024, rfal_platform_irq_thread, NULL); furi_thread_set_priority(rfal_platform.thread, FuriThreadPriorityIsr); furi_thread_start(rfal_platform.thread); } From b03140d76651a9c129660265040aa78711bfd507 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 12:25:03 +0300 Subject: [PATCH 12/36] upd airmouse --- non_catalog_apps/airmouse/README.md | 28 +- non_catalog_apps/airmouse/air_mouse.c | 15 +- non_catalog_apps/airmouse/air_mouse.h | 2 + non_catalog_apps/airmouse/application.fam | 23 +- .../airmouse/lib/bmi160-api/LICENSE | 30 + .../airmouse/lib/bmi160-api/README.md | 42 + .../airmouse/lib/bmi160-api/bmi160.c | 6428 ++++++++ .../{tracking/imu => lib/bmi160-api}/bmi160.h | 1961 ++- .../airmouse/lib/bmi160-api/bmi160_defs.h | 1647 ++ .../bmi160-api/examples/read_chip_id/Makefile | 13 + .../examples/read_chip_id/read_chip_id.c | 237 + .../examples/read_sensor_data/Makefile | 13 + .../read_sensor_data/read_sensor_data.c | 271 + .../lib/bmi160-api/examples/tap/Makefile | 13 + .../lib/bmi160-api/examples/tap/tap.c | 366 + .../airmouse/lib/lsm6ds3tr-api/.gitsubtree | 1 + .../lib/lsm6ds3tr-api/CONTRIBUTING.md | 33 + .../airmouse/lib/lsm6ds3tr-api/LICENSE | 29 + .../airmouse/lib/lsm6ds3tr-api/README.md | 59 + .../lib/lsm6ds3tr-api/Release_Notes.html | 82 + .../lib/lsm6ds3tr-api/Release_Notes.md | 89 + .../lib/lsm6ds3tr-api/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../lsm6ds3tr-api/_htmresc/mini-st_2020.css | 1711 ++ .../lsm6ds3tr-api/_htmresc/st_logo_2020.png | Bin 0 -> 7520 bytes .../lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.c | 8219 ++++++++++ .../lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.h | 2804 ++++ .../airmouse/lib/lsm6dso-api/.gitsubtree | 1 + .../lib/lsm6dso-api/CODE_OF_CONDUCT.md | 73 + .../airmouse/lib/lsm6dso-api/CONTRIBUTING.md | 40 + .../airmouse/lib/lsm6dso-api/LICENSE.md | 27 + .../airmouse/lib/lsm6dso-api/README.md | 34 + .../lib/lsm6dso-api/Release_Notes.html | 257 + .../airmouse/lib/lsm6dso-api/SECURITY.md | 31 + .../lib/lsm6dso-api/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../lib/lsm6dso-api/_htmresc/mini-st_2020.css | 1711 ++ .../lib/lsm6dso-api/_htmresc/st_logo_2020.png | Bin 0 -> 7520 bytes .../airmouse/lib/lsm6dso-api/lsm6dso.c | 3909 +++++ .../airmouse/lib/lsm6dso-api/lsm6dso.h | 369 + .../airmouse/lib/lsm6dso-api/lsm6dso_reg.c | 13139 ++++++++++++++++ .../airmouse/lib/lsm6dso-api/lsm6dso_reg.h | 4486 ++++++ .../airmouse/tracking/imu/bmi160.c | 6020 +------ .../airmouse/tracking/imu/bmi160_defs.h | 1619 -- non_catalog_apps/airmouse/tracking/imu/imu.c | 47 +- non_catalog_apps/airmouse/tracking/imu/imu.h | 16 +- .../airmouse/tracking/imu/imu_bmi160.c | 88 - .../airmouse/tracking/imu/lsm6ds3tr_c_reg.c | 7105 --------- .../airmouse/tracking/imu/lsm6ds3tr_c_reg.h | 2448 --- .../imu/{imu_lsm6ds3trc.c => lsm6ds3trc.c} | 37 +- .../airmouse/tracking/imu/lsm6dso.c | 90 + 49 files changed, 47403 insertions(+), 18260 deletions(-) create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/LICENSE create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/README.md create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/bmi160.c rename non_catalog_apps/airmouse/{tracking/imu => lib/bmi160-api}/bmi160.h (89%) create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/bmi160_defs.h create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/Makefile create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/read_chip_id.c create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/Makefile create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/read_sensor_data.c create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/Makefile create mode 100644 non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/tap.c create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/.gitsubtree create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/CONTRIBUTING.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/LICENSE create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/README.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.html create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/favicon.png create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/mini-st_2020.css create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/st_logo_2020.png create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.c create mode 100644 non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.h create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/.gitsubtree create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/CODE_OF_CONDUCT.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/CONTRIBUTING.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/LICENSE.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/README.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/Release_Notes.html create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/SECURITY.md create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/favicon.png create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/mini-st_2020.css create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/st_logo_2020.png create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.c create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.h create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.c create mode 100644 non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.h delete mode 100644 non_catalog_apps/airmouse/tracking/imu/bmi160_defs.h delete mode 100644 non_catalog_apps/airmouse/tracking/imu/imu_bmi160.c delete mode 100644 non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.c delete mode 100644 non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.h rename non_catalog_apps/airmouse/tracking/imu/{imu_lsm6ds3trc.c => lsm6ds3trc.c} (73%) create mode 100644 non_catalog_apps/airmouse/tracking/imu/lsm6dso.c diff --git a/non_catalog_apps/airmouse/README.md b/non_catalog_apps/airmouse/README.md index 04e346e4bf8..99d20de214a 100644 --- a/non_catalog_apps/airmouse/README.md +++ b/non_catalog_apps/airmouse/README.md @@ -1,4 +1,7 @@ -# Flipper Air Mouse +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/ginkage) +[![paypal](https://www.paypalobjects.com/en_GB/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=LF9S5WAF6E4VA) + +# BMI Air Mouse ## Brief @@ -24,10 +27,24 @@ Using it is really simple: See early prototype [in action](https://www.youtube.com/watch?v=DdxAmmsYfMA). +## How? + + * Clone this repository with `git clone --recurse-submodules` to include the driver implementations. + * Build the project using `ufbt` + ## Hardware The custom module is using Bosch BMI160 accelerometer/gyroscope chip connected via I2C. +Note: in fact, some other IMU chips are also supported. +It's detected via the first found I2C Address. + +| Chip | Expected I2C Address | +|:--------:|:--------------------:| +| BMI160 | 0x69 | +| LSM6DS3 | 0x6A | +| LSM6DSO | 0x6B | + Take a look into the [schematic](https://github.com/ginkage/FlippAirMouse/tree/main/schematic) folder for Gerber, BOM and CPL files, so you can order directly from JLCPCB. Original idea: @@ -46,15 +63,6 @@ Reality: The code is based on the original Bosch [driver](https://github.com/BoschSensortec/BMI160_driver/) and an orientation tracking implementation from the Google [Cardboard](https://github.com/googlevr/cardboard/tree/master/sdk/sensors) project -If you're familiar with Flipper applications, start in the [firmware](https://github.com/flipperdevices/flipperzero-firmware) checkout folder and do the following: -``` -cd applications/plugins -git clone https://github.com/ginkage/FlippAirMouse -cd ../.. -./fbt fap_air_mouse -``` -If you're not familiar with those, just grab a `fap` file from Releases. - ## License TL;DR: Use the code however you want, give credit where it's due, no warranty of any kind is provided. diff --git a/non_catalog_apps/airmouse/air_mouse.c b/non_catalog_apps/airmouse/air_mouse.c index 54a6e80273b..4f0a296ef1f 100644 --- a/non_catalog_apps/airmouse/air_mouse.c +++ b/non_catalog_apps/airmouse/air_mouse.c @@ -91,7 +91,7 @@ AirMouse* air_mouse_app_alloc() { view_dispatcher_add_view( app->view_dispatcher, AirMouseViewSubmenu, submenu_get_view(app->submenu)); - // Dialog view + // Dialog views app->dialog = dialog_ex_alloc(); dialog_ex_set_result_callback(app->dialog, air_mouse_dialog_callback); dialog_ex_set_context(app->dialog, app); @@ -102,6 +102,14 @@ AirMouse* air_mouse_app_alloc() { view_dispatcher_add_view( app->view_dispatcher, AirMouseViewExitConfirm, dialog_ex_get_view(app->dialog)); + app->error_dialog = dialog_ex_alloc(); + dialog_ex_set_header(app->error_dialog, "Failed to init IMU", 63, 0, AlignCenter, AlignTop); + dialog_ex_set_text( + app->error_dialog, "Please connect sensor module", 63, 30, AlignCenter, AlignTop); + view_set_previous_callback(dialog_ex_get_view(app->error_dialog), air_mouse_exit); + view_dispatcher_add_view( + app->view_dispatcher, AirMouseViewError, dialog_ex_get_view(app->error_dialog)); + // Bluetooth view app->bt_mouse = bt_mouse_alloc(app->view_dispatcher); view_set_previous_callback(bt_mouse_get_view(app->bt_mouse), air_mouse_exit_confirm_view); @@ -135,6 +143,8 @@ void air_mouse_app_free(AirMouse* app) { submenu_free(app->submenu); view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewExitConfirm); dialog_ex_free(app->dialog); + view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewError); + dialog_ex_free(app->error_dialog); view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewBtMouse); bt_mouse_free(app->bt_mouse); view_dispatcher_remove_view(app->view_dispatcher, AirMouseViewUsbMouse); @@ -156,8 +166,7 @@ int32_t air_mouse_app(void* p) { AirMouse* app = air_mouse_app_alloc(); if(!imu_begin()) { - air_mouse_app_free(app); - return -1; + view_dispatcher_switch_to_view(app->view_dispatcher, AirMouseViewError); } view_dispatcher_run(app->view_dispatcher); diff --git a/non_catalog_apps/airmouse/air_mouse.h b/non_catalog_apps/airmouse/air_mouse.h index 3a1ba783ec1..95925ff6d6d 100644 --- a/non_catalog_apps/airmouse/air_mouse.h +++ b/non_catalog_apps/airmouse/air_mouse.h @@ -15,6 +15,7 @@ typedef struct { ViewDispatcher* view_dispatcher; Submenu* submenu; DialogEx* dialog; + DialogEx* error_dialog; BtMouse* bt_mouse; UsbMouse* usb_mouse; Calibration* calibration; @@ -27,4 +28,5 @@ typedef enum { AirMouseViewUsbMouse, AirMouseViewCalibration, AirMouseViewExitConfirm, + AirMouseViewError, } AirMouseView; diff --git a/non_catalog_apps/airmouse/application.fam b/non_catalog_apps/airmouse/application.fam index 61cf1edbd4c..1d3a7073d3e 100644 --- a/non_catalog_apps/airmouse/application.fam +++ b/non_catalog_apps/airmouse/application.fam @@ -1,12 +1,31 @@ App( appid="air_mouse", - name="[BMI160] Air Mouse", + name="[BMI/LSM] Air Mouse", apptype=FlipperAppType.EXTERNAL, entry_point="air_mouse_app", stack_size=10 * 1024, fap_category="GPIO", fap_icon="mouse_10px.png", - fap_version="1.1", + fap_version="1.2", fap_libs=["ble_profile"], sources=["*.c", "*.cc"], + fap_private_libs=[ + Lib( + name="bmi160-api", + cflags=["-Wno-error"], + sources=[ + "bmi160.c", + "bmi160.h", + "bmi160_defs.h", + ], + ), + Lib( + name="lsm6ds3tr-api", + cflags=["-Wno-error"], + ), + Lib( + name="lsm6dso-api", + cflags=["-Wno-error"], + ), + ], ) diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/LICENSE b/non_catalog_apps/airmouse/lib/bmi160-api/LICENSE new file mode 100644 index 00000000000..39d644246fb --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. + +BSD-3-Clause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/README.md b/non_catalog_apps/airmouse/lib/bmi160-api/README.md new file mode 100644 index 00000000000..a29e977c406 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/README.md @@ -0,0 +1,42 @@ +# BMI160 Sensor API + +### Sensor overview + +The small, low power BMI160 is a low noise 16-bit IMU designed for mobile applications such as AR or indoor navigation, providing highly accurate sensor data and real-time sensor data. The low current consumption of BMI160 enables always-on applications in battery-driven devices. This sensor features a configurable on-chip interrupt engine which provides motion-based gesture recognition and context awareness as always-on background functions. + +### Target Application +- Augmented reality and immersive gaming +- Indoor navigation +- 3D-scanning / indoor mapping +- Advanced gesture recognition +- Immersive gaming +- 9-axis motion detection +- Air mouse applications and pointers +- Pedometer / step counting +- Advanced system power management for mobile applications +- Optical image stabilization of camera modules +- Free-fall detection and warranty logging + +### Features +- Any-motion detection (accelerometer) +- Significant motion detection (accelerometer) +- Step detector (accelerometer) +- Tap sensing (accelerometer) +- Orientation recognition (accelerometer) +- Flat detection (accelerometer) +- Low-G / Free-fall detection (accelerometer) +- High-G detection (accelerometer) +- Slow-motion alert / No-motion interrupt (accelerometer) +- Data ready detection (accelerometer, gyroscope and external sensors) +- PMU trigger (gyroscope) +- FIFO interrupts ((accelerometer, gyroscope and external sensors) + +### Important links + +- [BMI160 product page](https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi160/) +- [BMI160 datasheet](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi160-ds000.pdf) +- [BMI160 shuttle board flyer](https://www.bosch-sensortec.com/media/boschsensortec/downloads/shuttle_board_flyer/bst-dhw-fl022.pdf) +- [Community support page](https://community.bosch-sensortec.com) + +--- +#### Copyright (C) 2020 Bosch Sensortec GmbH \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/bmi160.c b/non_catalog_apps/airmouse/lib/bmi160-api/bmi160.c new file mode 100644 index 00000000000..733db9f0d88 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/bmi160.c @@ -0,0 +1,6428 @@ +/** +* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* @file bmi160.c +* @date 2021-10-05 +* @version v3.9.2 +* +*/ + +#include "bmi160.h" + +/* Below look up table follows the enum bmi160_int_types. + * Hence any change should match to the enum bmi160_int_types + */ +const uint8_t int_mask_lookup_table[13] = { + BMI160_INT1_SLOPE_MASK, BMI160_INT1_SLOPE_MASK, BMI160_INT2_LOW_STEP_DETECT_MASK, BMI160_INT1_DOUBLE_TAP_MASK, + BMI160_INT1_SINGLE_TAP_MASK, BMI160_INT1_ORIENT_MASK, BMI160_INT1_FLAT_MASK, BMI160_INT1_HIGH_G_MASK, + BMI160_INT1_LOW_G_MASK, BMI160_INT1_NO_MOTION_MASK, BMI160_INT2_DATA_READY_MASK, BMI160_INT2_FIFO_FULL_MASK, + BMI160_INT2_FIFO_WM_MASK +}; + +/*********************************************************************/ +/* Static function declarations */ + +/*! + * @brief This API configures the pins to fire the + * interrupt signal when it occurs + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_intr_pin_config(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the any-motion interrupt of the sensor. + * This interrupt occurs when accel values exceeds preset threshold + * for a certain period of time. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_any_motion_int(struct bmi160_int_settg *int_config, struct bmi160_dev *dev); + +/*! + * @brief This API sets tap interrupts.Interrupt is fired when + * tap movements happen. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_tap_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the data ready interrupt for both accel and gyro. + * This interrupt occurs when new accel and gyro data come. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_gyro_data_ready_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the significant motion interrupt of the sensor.This + * interrupt occurs when there is change in user location. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_sig_motion_int(struct bmi160_int_settg *int_config, struct bmi160_dev *dev); + +/*! + * @brief This API sets the no motion/slow motion interrupt of the sensor. + * Slow motion is similar to any motion interrupt.No motion interrupt + * occurs when slope bet. two accel values falls below preset threshold + * for preset duration. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_no_motion_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the step detection interrupt.This interrupt + * occurs when the single step causes accel values to go above + * preset threshold. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_step_detect_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the orientation interrupt of the sensor.This + * interrupt occurs when there is orientation change in the sensor + * with respect to gravitational field vector g. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_orientation_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the flat interrupt of the sensor.This interrupt + * occurs in case of flat orientation + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_flat_detect_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the low-g interrupt of the sensor.This interrupt + * occurs during free-fall. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_low_g_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the high-g interrupt of the sensor.The interrupt + * occurs if the absolute value of acceleration data of any enabled axis + * exceeds the programmed threshold and the sign of the value does not + * change for a preset duration. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_high_g_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the default configuration parameters of accel & gyro. + * Also maintain the previous state of configurations. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static void default_param_settg(struct bmi160_dev *dev); + +/*! + * @brief This API is used to validate the device structure pointer for + * null conditions. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t null_ptr_check(const struct bmi160_dev *dev); + +/*! + * @brief This API set the accel configuration. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_conf(struct bmi160_dev *dev); + +/*! + * @brief This API gets the accel configuration. + * + * @param[out] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t get_accel_conf(struct bmi160_dev *dev); + +/*! + * @brief This API check the accel configuration. + * + * @param[in] data : Pointer to store the updated accel config. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t check_accel_config(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API process the accel odr. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_accel_odr(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API process the accel bandwidth. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_accel_bw(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API process the accel range. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_accel_range(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API checks the invalid settings for ODR & Bw for Accel and Gyro. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t check_invalid_settg(const struct bmi160_dev *dev); + +/*! + * @brief This API set the gyro configuration. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_gyro_conf(struct bmi160_dev *dev); + +/*! + * @brief This API get the gyro configuration. + * + * @param[out] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t get_gyro_conf(struct bmi160_dev *dev); + +/*! + * @brief This API check the gyro configuration. + * + * @param[in] data : Pointer to store the updated gyro config. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t check_gyro_config(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API process the gyro odr. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_gyro_odr(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API process the gyro bandwidth. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_gyro_bw(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API process the gyro range. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_gyro_range(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the accel power mode. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_accel_pwr(struct bmi160_dev *dev); + +/*! + * @brief This API process the undersampling setting of Accel. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t process_under_sampling(uint8_t *data, const struct bmi160_dev *dev); + +/*! + * @brief This API sets the gyro power mode. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + */ +static int8_t set_gyro_pwr(struct bmi160_dev *dev); + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + * + * @param[in] len : len to read no of bytes + * @param[out] accel : Structure pointer to store accel data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_accel_data(uint8_t len, struct bmi160_sensor_data *accel, const struct bmi160_dev *dev); + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + * + * @param[in] len : len to read no of bytes + * @param[out] gyro : Structure pointer to store accel data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_gyro_data(uint8_t len, struct bmi160_sensor_data *gyro, const struct bmi160_dev *dev); + +/*! + * @brief This API reads accel and gyro data along with sensor time + * if time is requested by user. + * Kindly refer the user guide(README.md) for more info. + * + * @param[in] len : len to read no of bytes + * @param[out] accel : Structure pointer to store accel data + * @param[out] gyro : Structure pointer to store accel data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_accel_gyro_data(uint8_t len, + struct bmi160_sensor_data *accel, + struct bmi160_sensor_data *gyro, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the any-motion interrupt for accel. + * + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_accel_any_motion_int(const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + struct bmi160_dev *dev); + +/*! + * @brief This API disable the sig-motion interrupt. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t disable_sig_motion_int(const struct bmi160_dev *dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for any-motion interrupt. + * + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_any_motion_src(const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the duration and threshold of + * any-motion interrupt. + * + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_any_dur_threshold(const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure necessary setting of any-motion interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] any_motion_int_cfg : Structure instance of + * bmi160_acc_any_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_any_motion_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API enable the data ready interrupt. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_data_ready_int(const struct bmi160_dev *dev); + +/*! + * @brief This API enables the no motion/slow motion interrupt. + * + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_no_motion_int(const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the interrupt PIN setting for + * no motion/slow motion interrupt. + * + * @param[in] int_config : structure instance of bmi160_int_settg. + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_no_motion_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the source of interrupt for no motion. + * + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_no_motion_data_src(const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the duration and threshold of + * no motion/slow motion interrupt along with selection of no/slow motion. + * + * @param[in] no_mot_int_cfg : Structure instance of + * bmi160_acc_no_motion_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_no_motion_dur_thr(const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the sig-motion motion interrupt. + * + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_sig_motion_int(const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, struct bmi160_dev *dev); + +/*! + * @brief This API configure the interrupt PIN setting for + * significant motion interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sig_motion_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for sig motion interrupt. + * + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sig_motion_data_src(const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the threshold, skip and proof time of + * sig motion interrupt. + * + * @param[in] sig_mot_int_cfg : Structure instance of + * bmi160_acc_sig_mot_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sig_dur_threshold(const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the step detector interrupt. + * + * @param[in] step_detect_int_cfg : Structure instance of + * bmi160_acc_step_detect_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_step_detect_int(const struct bmi160_acc_step_detect_int_cfg *step_detect_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the step detector parameter. + * + * @param[in] step_detect_int_cfg : Structure instance of + * bmi160_acc_step_detect_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_step_detect(const struct bmi160_acc_step_detect_int_cfg *step_detect_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the single/double tap interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_tap_int(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_tap_int_cfg *tap_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the interrupt PIN setting for + * tap interrupt. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_tap_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_tap_int_cfg *tap_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for tap interrupt. + * + * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_tap_data_src(const struct bmi160_acc_tap_int_cfg *tap_int_cfg, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the parameters of tap interrupt. + * Threshold, quite, shock, and duration. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_tap_param(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_tap_int_cfg *tap_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API enable the external mode configuration. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_sec_if(const struct bmi160_dev *dev); + +/*! + * @brief This API configure the ODR of the auxiliary sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_aux_odr(const struct bmi160_dev *dev); + +/*! + * @brief This API maps the actual burst read length set by user. + * + * @param[in] len : Pointer to store the read length. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t map_read_len(uint16_t *len, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the settings of auxiliary sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_aux_settg(const struct bmi160_dev *dev); + +/*! + * @brief This API extract the read data from auxiliary sensor. + * + * @param[in] map_len : burst read value. + * @param[in] reg_addr : Address of register to read. + * @param[in] aux_data : Pointer to store the read data. + * @param[in] len : length to read the data. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t extract_aux_read(uint16_t map_len, + uint8_t reg_addr, + uint8_t *aux_data, + uint16_t len, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the orient interrupt. + * + * @param[in] orient_int_cfg : Structure instance of bmi160_acc_orient_int_cfg. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_orient_int(const struct bmi160_acc_orient_int_cfg *orient_int_cfg, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the necessary setting of orientation interrupt. + * + * @param[in] orient_int_cfg : Structure instance of bmi160_acc_orient_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_orient_int_settg(const struct bmi160_acc_orient_int_cfg *orient_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the flat interrupt. + * + * @param[in] flat_int : Structure instance of bmi160_acc_flat_detect_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_flat_int(const struct bmi160_acc_flat_detect_int_cfg *flat_int, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the necessary setting of flat interrupt. + * + * @param[in] flat_int : Structure instance of bmi160_acc_flat_detect_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_flat_int_settg(const struct bmi160_acc_flat_detect_int_cfg *flat_int, + const struct bmi160_dev *dev); + +/*! + * @brief This API enables the Low-g interrupt. + * + * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_low_g_int(const struct bmi160_acc_low_g_int_cfg *low_g_int, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) for low-g interrupt. + * + * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_low_g_data_src(const struct bmi160_acc_low_g_int_cfg *low_g_int, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the necessary setting of low-g interrupt. + * + * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_low_g_int_settg(const struct bmi160_acc_low_g_int_cfg *low_g_int, const struct bmi160_dev *dev); + +/*! + * @brief This API enables the high-g interrupt. + * + * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_high_g_int(const struct bmi160_acc_high_g_int_cfg *high_g_int_cfg, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for high-g interrupt. + * + * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_high_g_data_src(const struct bmi160_acc_high_g_int_cfg *high_g_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the necessary setting of high-g interrupt. + * + * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_high_g_int_settg(const struct bmi160_acc_high_g_int_cfg *high_g_int_cfg, + const struct bmi160_dev *dev); + +/*! + * @brief This API configure the behavioural setting of interrupt pin. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_int_out_ctrl(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API configure the mode(input enable, latch or non-latch) of interrupt pin. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t config_int_latch(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API performs the self test for accelerometer of BMI160 + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t perform_accel_self_test(struct bmi160_dev *dev); + +/*! + * @brief This API enables to perform the accel self test by setting proper + * configurations to facilitate accel self test + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_accel_self_test(struct bmi160_dev *dev); + +/*! + * @brief This API performs accel self test with positive excitation + * + * @param[in] accel_pos : Structure pointer to store accel data + * for positive excitation + * @param[in] dev : structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t accel_self_test_positive_excitation(struct bmi160_sensor_data *accel_pos, const struct bmi160_dev *dev); + +/*! + * @brief This API performs accel self test with negative excitation + * + * @param[in] accel_neg : Structure pointer to store accel data + * for negative excitation + * @param[in] dev : structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t accel_self_test_negative_excitation(struct bmi160_sensor_data *accel_neg, const struct bmi160_dev *dev); + +/*! + * @brief This API validates the accel self test results + * + * @param[in] accel_pos : Structure pointer to store accel data + * for positive excitation + * @param[in] accel_neg : Structure pointer to store accel data + * for negative excitation + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error / +ve value -> Self test fail + */ +static int8_t validate_accel_self_test(const struct bmi160_sensor_data *accel_pos, + const struct bmi160_sensor_data *accel_neg); + +/*! + * @brief This API performs the self test for gyroscope of BMI160 + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t perform_gyro_self_test(const struct bmi160_dev *dev); + +/*! + * @brief This API enables the self test bit to trigger self test for gyro + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_gyro_self_test(const struct bmi160_dev *dev); + +/*! + * @brief This API validates the self test results of gyro + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t validate_gyro_self_test(const struct bmi160_dev *dev); + +/*! + * @brief This API sets FIFO full interrupt of the sensor.This interrupt + * occurs when the FIFO is full and the next full data sample would cause + * a FIFO overflow, which may delete the old samples. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t set_fifo_full_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This enable the FIFO full interrupt engine. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_fifo_full_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API sets FIFO watermark interrupt of the sensor.The FIFO + * watermark interrupt is fired, when the FIFO fill level is above a fifo + * watermark. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t set_fifo_watermark_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This enable the FIFO watermark interrupt engine. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t enable_fifo_wtm_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to reset the FIFO related configurations + * in the fifo_frame structure. + * + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void reset_fifo_data_structure(const struct bmi160_dev *dev); + +/*! + * @brief This API is used to read number of bytes filled + * currently in FIFO buffer. + * + * @param[in] bytes_to_read : Number of bytes available in FIFO at the + * instant which is obtained from FIFO counter. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error. + * @retval Any non zero value -> Fail + * + */ +static int8_t get_fifo_byte_counter(uint16_t *bytes_to_read, struct bmi160_dev const *dev); + +/*! + * @brief This API is used to compute the number of bytes of accel FIFO data + * which is to be parsed in header-less mode + * + * @param[out] data_index : The start index for parsing data + * @param[out] data_read_length : Number of bytes to be parsed + * @param[in] acc_frame_count : Number of accelerometer frames to be read + * @param[in] dev : Structure instance of bmi160_dev. + * + */ +static void get_accel_len_to_parse(uint16_t *data_index, + uint16_t *data_read_length, + const uint8_t *acc_frame_count, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in,out] acc : structure instance of sensor data + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] acc_idx : Index value of accelerometer data + * (x,y,z axes) frames parsed + * @param[in] frame_info : It consists of either fifo_data_enable + * parameter in header-less mode or + * frame header data in header mode + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_accel_frame(struct bmi160_sensor_data *acc, + uint16_t *idx, + uint8_t *acc_idx, + uint8_t frame_info, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + * + * @param[in,out] accel_data : structure instance of sensor data + * @param[in,out] data_start_index : Index value of number of bytes parsed + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_accel_data(struct bmi160_sensor_data *accel_data, + uint16_t data_start_index, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in header mode. + * + * @param[in,out] accel_data : Structure instance of sensor data + * @param[in,out] accel_length : Number of accelerometer frames + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void extract_accel_header_mode(struct bmi160_sensor_data *accel_data, + uint8_t *accel_length, + const struct bmi160_dev *dev); + +/*! + * @brief This API computes the number of bytes of gyro FIFO data + * which is to be parsed in header-less mode + * + * @param[out] data_index : The start index for parsing data + * @param[out] data_read_length : No of bytes to be parsed from FIFO buffer + * @param[in] gyro_frame_count : Number of Gyro data frames to be read + * @param[in] dev : Structure instance of bmi160_dev. + */ +static void get_gyro_len_to_parse(uint16_t *data_index, + uint16_t *data_read_length, + const uint8_t *gyro_frame_count, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the gyroscope's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + * + * @param[in,out] gyro : structure instance of sensor data + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] gyro_idx : Index value of gyro data + * (x,y,z axes) frames parsed + * @param[in] frame_info : It consists of either fifo_data_enable + * parameter in header-less mode or + * frame header data in header mode + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_gyro_frame(struct bmi160_sensor_data *gyro, + uint16_t *idx, + uint8_t *gyro_idx, + uint8_t frame_info, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + * + * @param[in,out] gyro_data : structure instance of sensor data + * @param[in,out] data_start_index : Index value of number of bytes parsed + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_gyro_data(struct bmi160_sensor_data *gyro_data, + uint16_t data_start_index, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data in header mode. + * + * @param[in,out] gyro_data : Structure instance of sensor data + * @param[in,out] gyro_length : Number of gyro frames + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void extract_gyro_header_mode(struct bmi160_sensor_data *gyro_data, + uint8_t *gyro_length, + const struct bmi160_dev *dev); + +/*! + * @brief This API computes the number of bytes of aux FIFO data + * which is to be parsed in header-less mode + * + * @param[out] data_index : The start index for parsing data + * @param[out] data_read_length : No of bytes to be parsed from FIFO buffer + * @param[in] aux_frame_count : Number of Aux data frames to be read + * @param[in] dev : Structure instance of bmi160_dev. + */ +static void get_aux_len_to_parse(uint16_t *data_index, + uint16_t *data_read_length, + const uint8_t *aux_frame_count, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the aux's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed + * + * @param[in,out] aux_data : structure instance of sensor data + * @param[in,out] idx : Index value of number of bytes parsed + * @param[in,out] aux_index : Index value of gyro data + * (x,y,z axes) frames parsed + * @param[in] frame_info : It consists of either fifo_data_enable + * parameter in header-less mode or + * frame header data in header mode + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_aux_frame(struct bmi160_aux_data *aux_data, + uint16_t *idx, + uint8_t *aux_index, + uint8_t frame_info, + const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data and store it in the instance of the structure bmi160_aux_data. + * + * @param[in,out] aux_data : structure instance of sensor data + * @param[in,out] data_start_index : Index value of number of bytes parsed + * @param[in] dev : structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_aux_data(struct bmi160_aux_data *aux_data, uint16_t data_start_index, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data in header mode. + * + * @param[in,out] aux_data : Structure instance of sensor data + * @param[in,out] aux_length : Number of aux frames + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void extract_aux_header_mode(struct bmi160_aux_data *aux_data, uint8_t *aux_length, + const struct bmi160_dev *dev); + +/*! + * @brief This API checks the presence of non-valid frames in the read fifo data. + * + * @param[in,out] data_index : The index of the current data to + * be parsed from fifo data + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void check_frame_validity(uint16_t *data_index, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + * + * @param[in,out] data_index : Index of the FIFO data which + * is to be moved ahead of the + * current_frame_length + * @param[in] current_frame_length : Number of bytes in a particular frame + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse and store the sensor time from the + * FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the sensor time. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_sensortime_frame(uint16_t *data_index, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to parse and store the skipped_frame_count from + * the FIFO data in the structure instance dev. + * + * @param[in,out] data_index : Index of the FIFO data which + * has the skipped frame count. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static void unpack_skipped_frame(uint16_t *data_index, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to get the FOC status from the sensor + * + * @param[in,out] foc_status : Result of FOC status. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_foc_status(uint8_t *foc_status, struct bmi160_dev const *dev); + +/*! + * @brief This API is used to configure the offset enable bits in the sensor + * + * @param[in,out] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC and offset configurations + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t configure_offset_enable(const struct bmi160_foc_conf *foc_conf, struct bmi160_dev const *dev); + +/*! + * @brief This API is used to trigger the FOC in the sensor + * + * @param[in,out] offset : Structure instance of bmi160_offsets which + * reads and stores the offset values after FOC + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t trigger_foc(struct bmi160_offsets *offset, struct bmi160_dev const *dev); + +/*! + * @brief This API is used to map/unmap the Dataready(Accel & Gyro), FIFO full + * and FIFO watermark interrupt + * + * @param[in] int_config : Structure instance of bmi160_int_settg which + * stores the interrupt type and interrupt channel + * configurations to map/unmap the interrupt pins + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t map_hardware_interrupt(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*! + * @brief This API is used to map/unmap the Any/Sig motion, Step det/Low-g, + * Double tap, Single tap, Orientation, Flat, High-G, Nomotion interrupt pins. + * + * @param[in] int_config : Structure instance of bmi160_int_settg which + * stores the interrupt type and interrupt channel + * configurations to map/unmap the interrupt pins + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t map_feature_interrupt(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev); + +/*********************** User function definitions ****************************/ + +/*! + * @brief This API reads the data from the given register address + * of sensor. + */ +int8_t bmi160_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->read == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else if (len == 0) + { + rslt = BMI160_E_READ_WRITE_LENGTH_INVALID; + } + else + { + /* Configuring reg_addr for SPI Interface */ + if (dev->intf == BMI160_SPI_INTF) + { + reg_addr = (reg_addr | BMI160_SPI_RD_MASK); + } + + rslt = dev->read(dev->id, reg_addr, data, len); + } + + return rslt; +} + +/*! + * @brief This API writes the given data to the register address + * of sensor. + */ +int8_t bmi160_set_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + uint8_t count = 0; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->write == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else if (len == 0) + { + rslt = BMI160_E_READ_WRITE_LENGTH_INVALID; + } + else + { + /* Configuring reg_addr for SPI Interface */ + if (dev->intf == BMI160_SPI_INTF) + { + reg_addr = (reg_addr & BMI160_SPI_WR_MASK); + } + + if ((dev->prev_accel_cfg.power == BMI160_ACCEL_NORMAL_MODE) || + (dev->prev_gyro_cfg.power == BMI160_GYRO_NORMAL_MODE)) + { + rslt = dev->write(dev->id, reg_addr, data, len); + + /* Kindly refer bmi160 data sheet section 3.2.4 */ + dev->delay_ms(1); + + } + else + { + /*Burst write is not allowed in + * suspend & low power mode */ + for (; count < len; count++) + { + rslt = dev->write(dev->id, reg_addr, &data[count], 1); + reg_addr++; + + /* Kindly refer bmi160 data sheet section 3.2.4 */ + dev->delay_ms(1); + + } + } + + if (rslt != BMI160_OK) + { + rslt = BMI160_E_COM_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API is the entry point for sensor.It performs + * the selection of I2C/SPI read mechanism according to the + * selected interface and reads the chip-id of bmi160 sensor. + */ +int8_t bmi160_init(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data; + uint8_t try = 3; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + /* Dummy read of 0x7F register to enable SPI Interface + * if SPI is used */ + if ((rslt == BMI160_OK) && (dev->intf == BMI160_SPI_INTF)) + { + rslt = bmi160_get_regs(BMI160_SPI_COMM_TEST_ADDR, &data, 1, dev); + } + + if (rslt == BMI160_OK) + { + /* Assign chip id as zero */ + dev->chip_id = 0; + + while ((try--) && (dev->chip_id != BMI160_CHIP_ID)) + { + /* Read chip_id */ + rslt = bmi160_get_regs(BMI160_CHIP_ID_ADDR, &dev->chip_id, 1, dev); + } + + if ((rslt == BMI160_OK) && (dev->chip_id == BMI160_CHIP_ID)) + { + dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; + + /* Soft reset */ + rslt = bmi160_soft_reset(dev); + } + else + { + rslt = BMI160_E_DEV_NOT_FOUND; + } + } + + return rslt; +} + +/*! + * @brief This API resets and restarts the device. + * All register values are overwritten with default parameters. + */ +int8_t bmi160_soft_reset(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = BMI160_SOFT_RESET_CMD; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Reset the device */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &data, 1, dev); + dev->delay_ms(BMI160_SOFT_RESET_DELAY_MS); + if ((rslt == BMI160_OK) && (dev->intf == BMI160_SPI_INTF)) + { + /* Dummy read of 0x7F register to enable SPI Interface + * if SPI is used */ + rslt = bmi160_get_regs(BMI160_SPI_COMM_TEST_ADDR, &data, 1, dev); + } + + if (rslt == BMI160_OK) + { + /* Update the default parameters */ + default_param_settg(dev); + } + } + + return rslt; +} + +/*! + * @brief This API configures the power mode, range and bandwidth + * of sensor. + */ +int8_t bmi160_set_sens_conf(struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = set_accel_conf(dev); + if (rslt == BMI160_OK) + { + rslt = set_gyro_conf(dev); + if (rslt == BMI160_OK) + { + /* write power mode for accel and gyro */ + rslt = bmi160_set_power_mode(dev); + if (rslt == BMI160_OK) + { + rslt = check_invalid_settg(dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API gets accel and gyro configurations. + */ +int8_t bmi160_get_sens_conf(struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = get_accel_conf(dev); + if (rslt == BMI160_OK) + { + rslt = get_gyro_conf(dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the power mode of the sensor. + */ +int8_t bmi160_set_power_mode(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = set_accel_pwr(dev); + if (rslt == BMI160_OK) + { + rslt = set_gyro_pwr(dev); + } + } + + return rslt; +} + +/*! + * @brief This API gets the power mode of the sensor. + */ +int8_t bmi160_get_power_mode(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t power_mode = 0; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_get_regs(BMI160_PMU_STATUS_ADDR, &power_mode, 1, dev); + if (rslt == BMI160_OK) + { + /* Power mode of the accel, gyro sensor is obtained */ + dev->gyro_cfg.power = BMI160_GET_BITS(power_mode, BMI160_GYRO_POWER_MODE); + dev->accel_cfg.power = BMI160_GET_BITS(power_mode, BMI160_ACCEL_POWER_MODE); + } + } + + return rslt; +} + +/*! + * @brief This API reads sensor data, stores it in + * the bmi160_sensor_data structure pointer passed by the user. + */ +int8_t bmi160_get_sensor_data(uint8_t select_sensor, + struct bmi160_sensor_data *accel, + struct bmi160_sensor_data *gyro, + const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + uint8_t time_sel; + uint8_t sen_sel; + uint8_t len = 0; + + /*Extract the sensor and time select information*/ + sen_sel = select_sensor & BMI160_SEN_SEL_MASK; + time_sel = ((sen_sel & BMI160_TIME_SEL) >> 2); + sen_sel = sen_sel & (BMI160_ACCEL_SEL | BMI160_GYRO_SEL); + if (time_sel == 1) + { + len = 3; + } + + /* Null-pointer check */ + if (dev != NULL) + { + switch (sen_sel) + { + case BMI160_ACCEL_ONLY: + + /* Null-pointer check */ + if (accel == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = get_accel_data(len, accel, dev); + } + + break; + case BMI160_GYRO_ONLY: + + /* Null-pointer check */ + if (gyro == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = get_gyro_data(len, gyro, dev); + } + + break; + case BMI160_BOTH_ACCEL_AND_GYRO: + + /* Null-pointer check */ + if ((gyro == NULL) || (accel == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = get_accel_gyro_data(len, accel, gyro, dev); + } + + break; + default: + rslt = BMI160_E_INVALID_INPUT; + break; + } + } + else + { + rslt = BMI160_E_NULL_PTR; + } + + return rslt; +} + +/*! + * @brief This API configures the necessary interrupt based on + * the user settings in the bmi160_int_settg structure instance. + */ +int8_t bmi160_set_int_config(struct bmi160_int_settg *int_config, struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + switch (int_config->int_type) + { + case BMI160_ACC_ANY_MOTION_INT: + + /*Any-motion interrupt*/ + rslt = set_accel_any_motion_int(int_config, dev); + break; + case BMI160_ACC_SIG_MOTION_INT: + + /* Significant motion interrupt */ + rslt = set_accel_sig_motion_int(int_config, dev); + break; + case BMI160_ACC_SLOW_NO_MOTION_INT: + + /* Slow or no motion interrupt */ + rslt = set_accel_no_motion_int(int_config, dev); + break; + case BMI160_ACC_DOUBLE_TAP_INT: + case BMI160_ACC_SINGLE_TAP_INT: + + /* Double tap and single tap Interrupt */ + rslt = set_accel_tap_int(int_config, dev); + break; + case BMI160_STEP_DETECT_INT: + + /* Step detector interrupt */ + rslt = set_accel_step_detect_int(int_config, dev); + break; + case BMI160_ACC_ORIENT_INT: + + /* Orientation interrupt */ + rslt = set_accel_orientation_int(int_config, dev); + break; + case BMI160_ACC_FLAT_INT: + + /* Flat detection interrupt */ + rslt = set_accel_flat_detect_int(int_config, dev); + break; + case BMI160_ACC_LOW_G_INT: + + /* Low-g interrupt */ + rslt = set_accel_low_g_int(int_config, dev); + break; + case BMI160_ACC_HIGH_G_INT: + + /* High-g interrupt */ + rslt = set_accel_high_g_int(int_config, dev); + break; + case BMI160_ACC_GYRO_DATA_RDY_INT: + + /* Data ready interrupt */ + rslt = set_accel_gyro_data_ready_int(int_config, dev); + break; + case BMI160_ACC_GYRO_FIFO_FULL_INT: + + /* Fifo full interrupt */ + rslt = set_fifo_full_int(int_config, dev); + break; + case BMI160_ACC_GYRO_FIFO_WATERMARK_INT: + + /* Fifo water-mark interrupt */ + rslt = set_fifo_watermark_int(int_config, dev); + break; + case BMI160_FIFO_TAG_INT_PIN: + + /* Fifo tagging feature support */ + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + break; + default: + break; + } + + return rslt; +} + +/*! + * @brief This API enables or disable the step counter feature. + * 1 - enable step counter (0 - disable) + */ +int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_get_regs(BMI160_INT_STEP_CONFIG_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + if (step_cnt_enable == BMI160_ENABLE) + { + data |= (uint8_t)(step_cnt_enable << 3); + } + else + { + data &= ~BMI160_STEP_COUNT_EN_BIT_MASK; + } + + rslt = bmi160_set_regs(BMI160_INT_STEP_CONFIG_1_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API reads the step counter value. + */ +int8_t bmi160_read_step_counter(uint16_t *step_val, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0, 0 }; + uint16_t msb = 0; + uint8_t lsb = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_get_regs(BMI160_INT_STEP_CNT_0_ADDR, data, 2, dev); + if (rslt == BMI160_OK) + { + lsb = data[0]; + msb = data[1] << 8; + *step_val = msb | lsb; + } + } + + return rslt; +} + +/*! + * @brief This API reads the mention no of byte of data from the given + * register address of auxiliary sensor. + */ +int8_t bmi160_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + uint16_t map_len = 0; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->read == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + if (dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) + { + rslt = map_read_len(&map_len, dev); + if (rslt == BMI160_OK) + { + rslt = extract_aux_read(map_len, reg_addr, aux_data, len, dev); + } + } + else + { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This API writes the mention no of byte of data to the given + * register address of auxiliary sensor. + */ +int8_t bmi160_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + uint8_t count = 0; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->write == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + for (; count < len; count++) + { + /* set data to write */ + rslt = bmi160_set_regs(BMI160_AUX_IF_4_ADDR, aux_data, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if (rslt == BMI160_OK) + { + /* set address to write */ + rslt = bmi160_set_regs(BMI160_AUX_IF_3_ADDR, ®_addr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if (rslt == BMI160_OK && (count < len - 1)) + { + aux_data++; + reg_addr++; + } + } + } + } + + return rslt; +} + +/*! + * @brief This API initialize the auxiliary sensor + * in order to access it. + */ +int8_t bmi160_aux_init(const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + if (dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) + { + /* Configures the auxiliary sensor interface settings */ + rslt = config_aux_settg(dev); + } + else + { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This API is used to setup the auxiliary sensor of bmi160 in auto mode + * Thus enabling the auto update of 8 bytes of data from auxiliary sensor + * to BMI160 register address 0x04 to 0x0B + */ +int8_t bmi160_set_aux_auto_mode(uint8_t *data_addr, struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + if (dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) + { + /* Write the aux. address to read in 0x4D of BMI160*/ + rslt = bmi160_set_regs(BMI160_AUX_IF_2_ADDR, data_addr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if (rslt == BMI160_OK) + { + /* Configure the polling ODR for + * auxiliary sensor */ + rslt = config_aux_odr(dev); + if (rslt == BMI160_OK) + { + /* Disable the aux. manual mode, i.e aux. + * sensor is in auto-mode (data-mode) */ + dev->aux_cfg.manual_enable = BMI160_DISABLE; + rslt = bmi160_config_aux_mode(dev); + + /* Auxiliary sensor data is obtained + * in auto mode from this point */ + } + } + } + else + { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This API configures the 0x4C register and settings like + * Auxiliary sensor manual enable/ disable and aux burst read length. + */ +int8_t bmi160_config_aux_mode(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t aux_if[2] = { (uint8_t)(dev->aux_cfg.aux_i2c_addr * 2), 0 }; + + rslt = bmi160_get_regs(BMI160_AUX_IF_1_ADDR, &aux_if[1], 1, dev); + if (rslt == BMI160_OK) + { + /* update the Auxiliary interface to manual/auto mode */ + aux_if[1] = BMI160_SET_BITS(aux_if[1], BMI160_MANUAL_MODE_EN, dev->aux_cfg.manual_enable); + + /* update the burst read length defined by user */ + aux_if[1] = BMI160_SET_BITS_POS_0(aux_if[1], BMI160_AUX_READ_BURST, dev->aux_cfg.aux_rd_burst_len); + + /* Set the secondary interface address and manual mode + * along with burst read length */ + rslt = bmi160_set_regs(BMI160_AUX_IF_0_ADDR, &aux_if[0], 2, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + } + + return rslt; +} + +/*! + * @brief This API is used to read the raw uncompensated auxiliary sensor + * data of 8 bytes from BMI160 register address 0x04 to 0x0B + */ +int8_t bmi160_read_aux_data_auto_mode(uint8_t *aux_data, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + if ((dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) && (dev->aux_cfg.manual_enable == BMI160_DISABLE)) + { + /* Read the aux. sensor's raw data */ + rslt = bmi160_get_regs(BMI160_AUX_DATA_ADDR, aux_data, 8, dev); + } + else + { + rslt = BMI160_E_INVALID_INPUT; + } + } + + return rslt; +} + +/*! + * @brief This is used to perform self test of accel/gyro of the BMI160 sensor + */ +int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev *dev) +{ + int8_t rslt; + int8_t self_test_rslt = 0; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + + /* Proceed if null check is fine */ + switch (select_sensor) + { + case BMI160_ACCEL_ONLY: + rslt = perform_accel_self_test(dev); + break; + case BMI160_GYRO_ONLY: + + /* Set the power mode as normal mode */ + dev->gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; + rslt = bmi160_set_power_mode(dev); + + /* Perform gyro self test */ + if (rslt == BMI160_OK) + { + /* Perform gyro self test */ + rslt = perform_gyro_self_test(dev); + } + + break; + default: + rslt = BMI160_E_INVALID_INPUT; + break; + } + + /* Check to ensure bus error does not occur */ + if (rslt >= BMI160_OK) + { + /* Store the status of self test result */ + self_test_rslt = rslt; + + /* Perform soft reset */ + rslt = bmi160_soft_reset(dev); + + } + + /* Check to ensure bus operations are success */ + if (rslt == BMI160_OK) + { + /* Restore self_test_rslt as return value */ + rslt = self_test_rslt; + } + } + + return rslt; +} + +/*! + * @brief This API reads the data from fifo buffer. + */ +int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + uint16_t bytes_to_read = 0; + uint16_t user_fifo_len = 0; + + /* check the bmi160 structure as NULL*/ + if ((dev == NULL) || (dev->fifo->data == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + reset_fifo_data_structure(dev); + + /* get current FIFO fill-level*/ + rslt = get_fifo_byte_counter(&bytes_to_read, dev); + if (rslt == BMI160_OK) + { + user_fifo_len = dev->fifo->length; + if ((dev->fifo->length > bytes_to_read)) + { + /* Handling the case where user requests + * more data than available in FIFO */ + dev->fifo->length = bytes_to_read; + } + + if ((dev->fifo->fifo_time_enable == BMI160_FIFO_TIME_ENABLE) && + (bytes_to_read + BMI160_FIFO_BYTES_OVERREAD <= user_fifo_len)) + { + /* Handling case of sensor time availability*/ + dev->fifo->length = dev->fifo->length + BMI160_FIFO_BYTES_OVERREAD; + } + + /* read only the filled bytes in the FIFO Buffer */ + rslt = bmi160_get_regs(BMI160_FIFO_DATA_ADDR, dev->fifo->data, dev->fifo->length, dev); + } + } + + return rslt; +} + +/*! + * @brief This API writes fifo_flush command to command register.This + * action clears all data in the Fifo without changing fifo configuration + * settings + */ +int8_t bmi160_set_fifo_flush(const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t data = BMI160_FIFO_FLUSH_VALUE; + uint8_t reg_addr = BMI160_COMMAND_REG_ADDR; + + /* Check the bmi160_dev structure for NULL address*/ + if (dev == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + } + + return rslt; +} + +/*! + * @brief This API sets the FIFO configuration in the sensor. + */ +int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + uint8_t data = 0; + uint8_t reg_addr = BMI160_FIFO_CONFIG_1_ADDR; + uint8_t fifo_config = config & BMI160_FIFO_CONFIG_1_MASK; + + /* Check the bmi160_dev structure for NULL address*/ + if (dev == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); + if (rslt == BMI160_OK) + { + if (fifo_config > 0) + { + if (enable == BMI160_ENABLE) + { + data = data | fifo_config; + } + else + { + data = data & (~fifo_config); + } + } + + /* write fifo frame content configuration*/ + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + if (rslt == BMI160_OK) + { + /* read fifo frame content configuration*/ + rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); + if (rslt == BMI160_OK) + { + /* extract fifo header enabled status */ + dev->fifo->fifo_header_enable = data & BMI160_FIFO_HEAD_ENABLE; + + /* extract accel/gyr/aux. data enabled status */ + dev->fifo->fifo_data_enable = data & BMI160_FIFO_M_G_A_ENABLE; + + /* extract fifo sensor time enabled status */ + dev->fifo->fifo_time_enable = data & BMI160_FIFO_TIME_ENABLE; + } + } + } + } + + return rslt; +} + +/*! @brief This API is used to configure the down sampling ratios of + * the accel and gyro data for FIFO.Also, it configures filtered or + * pre-filtered data for accel and gyro. + * + */ +int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t data = 0; + uint8_t reg_addr = BMI160_FIFO_DOWN_ADDR; + + /* Check the bmi160_dev structure for NULL address*/ + if (dev == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); + if (rslt == BMI160_OK) + { + data = data | fifo_down; + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the FIFO watermark level in the sensor. + * + */ +int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t data = fifo_wm; + uint8_t reg_addr = BMI160_FIFO_CONFIG_0_ADDR; + + /* Check the bmi160_dev structure for NULL address*/ + if (dev == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the accelerometer frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "accel_data" structure instance. + */ +int8_t bmi160_extract_accel(struct bmi160_sensor_data *accel_data, uint8_t *accel_length, struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + uint16_t data_index = 0; + uint16_t data_read_length = 0; + uint8_t accel_index = 0; + uint8_t fifo_data_enable = 0; + + if (dev == NULL || dev->fifo == NULL || dev->fifo->data == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Parsing the FIFO data in header-less mode */ + if (dev->fifo->fifo_header_enable == 0) + { + /* Number of bytes to be parsed from FIFO */ + get_accel_len_to_parse(&data_index, &data_read_length, accel_length, dev); + for (; data_index < data_read_length;) + { + /*Check for the availability of next two bytes of FIFO data */ + check_frame_validity(&data_index, dev); + fifo_data_enable = dev->fifo->fifo_data_enable; + unpack_accel_frame(accel_data, &data_index, &accel_index, fifo_data_enable, dev); + } + + /* update number of accel data read*/ + *accel_length = accel_index; + + /*update the accel byte index*/ + dev->fifo->accel_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + extract_accel_header_mode(accel_data, accel_length, dev); + } + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the gyro frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "gyro_data" structure instance. + */ +int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_length, struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + uint16_t data_index = 0; + uint16_t data_read_length = 0; + uint8_t gyro_index = 0; + uint8_t fifo_data_enable = 0; + + if (dev == NULL || dev->fifo->data == NULL) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Parsing the FIFO data in header-less mode */ + if (dev->fifo->fifo_header_enable == 0) + { + /* Number of bytes to be parsed from FIFO */ + get_gyro_len_to_parse(&data_index, &data_read_length, gyro_length, dev); + for (; data_index < data_read_length;) + { + /*Check for the availability of next two bytes of FIFO data */ + check_frame_validity(&data_index, dev); + fifo_data_enable = dev->fifo->fifo_data_enable; + unpack_gyro_frame(gyro_data, &data_index, &gyro_index, fifo_data_enable, dev); + } + + /* update number of gyro data read */ + *gyro_length = gyro_index; + + /* update the gyro byte index */ + dev->fifo->gyro_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + extract_gyro_header_mode(gyro_data, gyro_length, dev); + } + } + + return rslt; +} + +/*! + * @brief This API parses and extracts the aux frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "aux_data" structure instance. + */ +int8_t bmi160_extract_aux(struct bmi160_aux_data *aux_data, uint8_t *aux_len, struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + uint16_t data_index = 0; + uint16_t data_read_length = 0; + uint8_t aux_index = 0; + uint8_t fifo_data_enable = 0; + + if ((dev == NULL) || (dev->fifo->data == NULL) || (aux_data == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Parsing the FIFO data in header-less mode */ + if (dev->fifo->fifo_header_enable == 0) + { + /* Number of bytes to be parsed from FIFO */ + get_aux_len_to_parse(&data_index, &data_read_length, aux_len, dev); + for (; data_index < data_read_length;) + { + /* Check for the availability of next two + * bytes of FIFO data */ + check_frame_validity(&data_index, dev); + fifo_data_enable = dev->fifo->fifo_data_enable; + unpack_aux_frame(aux_data, &data_index, &aux_index, fifo_data_enable, dev); + } + + /* update number of aux data read */ + *aux_len = aux_index; + + /* update the aux byte index */ + dev->fifo->aux_byte_start_idx = data_index; + } + else + { + /* Parsing the FIFO data in header mode */ + extract_aux_header_mode(aux_data, aux_len, dev); + } + } + + return rslt; +} + +/*! + * @brief This API starts the FOC of accel and gyro + * + * @note FOC should not be used in low-power mode of sensor + * + * @note Accel FOC targets values of +1g , 0g , -1g + * Gyro FOC always targets value of 0 dps + */ +int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, + struct bmi160_offsets *offset, + struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Set the offset enable bits */ + rslt = configure_offset_enable(foc_conf, dev); + if (rslt == BMI160_OK) + { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); + + /* Set the FOC config for gyro */ + data = BMI160_SET_BITS(data, BMI160_GYRO_FOC_EN, foc_conf->foc_gyr_en); + + /* Set the FOC config for accel xyz axes */ + data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_X_CONF, foc_conf->foc_acc_x); + data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_Y_CONF, foc_conf->foc_acc_y); + data = BMI160_SET_BITS_POS_0(data, BMI160_ACCEL_FOC_Z_CONF, foc_conf->foc_acc_z); + if (rslt == BMI160_OK) + { + /* Set the FOC config in the sensor */ + rslt = bmi160_set_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* Procedure to trigger + * FOC and check status */ + rslt = trigger_foc(offset, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API reads and stores the offset values of accel and gyro + */ +int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[7]; + uint8_t lsb, msb; + int16_t offset_msb, offset_lsb; + int16_t offset_data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_OFFSET_ADDR, data, 7, dev); + + /* Accel offsets */ + offset->off_acc_x = (int8_t)data[0]; + offset->off_acc_y = (int8_t)data[1]; + offset->off_acc_z = (int8_t)data[2]; + + /* Gyro x-axis offset */ + lsb = data[3]; + msb = BMI160_GET_BITS_POS_0(data[6], BMI160_GYRO_OFFSET_X); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_x = (int16_t)(offset_data / 64); + + /* Gyro y-axis offset */ + lsb = data[4]; + msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Y); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_y = (int16_t)(offset_data / 64); + + /* Gyro z-axis offset */ + lsb = data[5]; + msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Z); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_z = (int16_t)(offset_data / 64); + } + + return rslt; +} + +/*! + * @brief This API writes the offset values of accel and gyro to + * the sensor but these values will be reset on POR or soft reset. + */ +int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, + const struct bmi160_offsets *offset, + struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data[7]; + uint8_t x_msb, y_msb, z_msb; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Update the accel offset */ + data[0] = (uint8_t)offset->off_acc_x; + data[1] = (uint8_t)offset->off_acc_y; + data[2] = (uint8_t)offset->off_acc_z; + + /* Update the LSB of gyro offset */ + data[3] = BMI160_GET_LSB(offset->off_gyro_x); + data[4] = BMI160_GET_LSB(offset->off_gyro_y); + data[5] = BMI160_GET_LSB(offset->off_gyro_z); + + /* Update the MSB of gyro offset */ + x_msb = BMI160_GET_BITS(offset->off_gyro_x, BMI160_GYRO_OFFSET); + y_msb = BMI160_GET_BITS(offset->off_gyro_y, BMI160_GYRO_OFFSET); + z_msb = BMI160_GET_BITS(offset->off_gyro_z, BMI160_GYRO_OFFSET); + data[6] = (uint8_t)(z_msb << 4 | y_msb << 2 | x_msb); + + /* Set the offset enable/disable for gyro and accel */ + data[6] = BMI160_SET_BITS(data[6], BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); + data[6] = BMI160_SET_BITS(data[6], BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); + + /* Set the offset config and values in the sensor */ + rslt = bmi160_set_regs(BMI160_OFFSET_ADDR, data, 7, dev); + } + + return rslt; +} + +/*! + * @brief This API writes the image registers values to NVM which is + * stored even after POR or soft reset + */ +int8_t bmi160_update_nvm(struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + uint8_t cmd = BMI160_NVM_BACKUP_EN; + + /* Read the nvm_prog_en configuration */ + rslt = bmi160_get_regs(BMI160_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + data = BMI160_SET_BITS(data, BMI160_NVM_UPDATE, 1); + + /* Set the nvm_prog_en bit in the sensor */ + rslt = bmi160_set_regs(BMI160_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* Update NVM */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if (rslt == BMI160_OK) + { + /* Check for NVM ready status */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + data = BMI160_GET_BITS(data, BMI160_NVM_STATUS); + if (data != BMI160_ENABLE) + { + /* Delay to update NVM */ + dev->delay_ms(25); + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API gets the interrupt status from the sensor. + */ +int8_t bmi160_get_int_status(enum bmi160_int_status_sel int_status_sel, + union bmi160_int_status *int_status, + struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + + /* To get the status of all interrupts */ + if (int_status_sel == BMI160_INT_STATUS_ALL) + { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR, &int_status->data[0], 4, dev); + } + else + { + if (int_status_sel & BMI160_INT_STATUS_0) + { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR, &int_status->data[0], 1, dev); + } + + if (int_status_sel & BMI160_INT_STATUS_1) + { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 1, &int_status->data[1], 1, dev); + } + + if (int_status_sel & BMI160_INT_STATUS_2) + { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 2, &int_status->data[2], 1, dev); + } + + if (int_status_sel & BMI160_INT_STATUS_3) + { + rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 3, &int_status->data[3], 1, dev); + } + } + + return rslt; +} + +/*********************** Local function definitions ***************************/ + +/*! + * @brief This API sets the any-motion interrupt of the sensor. + * This interrupt occurs when accel values exceeds preset threshold + * for a certain period of time. + */ +static int8_t set_accel_any_motion_int(struct bmi160_int_settg *int_config, struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg = &(int_config->int_type_cfg.acc_any_motion_int); + rslt = enable_accel_any_motion_int(any_motion_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_any_motion_int_settg(int_config, any_motion_int_cfg, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets tap interrupts.Interrupt is fired when + * tap movements happen. + */ +static int8_t set_accel_tap_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_tap_int_cfg *tap_int_cfg = &(int_config->int_type_cfg.acc_tap_int); + rslt = enable_tap_int(int_config, tap_int_cfg, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_tap_int_settg(int_config, tap_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the data ready interrupt for both accel and gyro. + * This interrupt occurs when new accel and gyro data comes. + */ +static int8_t set_accel_gyro_data_ready_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + rslt = enable_data_ready_int(dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_hardware_interrupt(int_config, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the significant motion interrupt of the sensor.This + * interrupt occurs when there is change in user location. + */ +static int8_t set_accel_sig_motion_int(struct bmi160_int_settg *int_config, struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg = &(int_config->int_type_cfg.acc_sig_motion_int); + rslt = enable_sig_motion_int(sig_mot_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_sig_motion_int_settg(int_config, sig_mot_int_cfg, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the no motion/slow motion interrupt of the sensor. + * Slow motion is similar to any motion interrupt.No motion interrupt + * occurs when slope bet. two accel values falls below preset threshold + * for preset duration. + */ +static int8_t set_accel_no_motion_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg = &(int_config->int_type_cfg.acc_no_motion_int); + rslt = enable_no_motion_int(no_mot_int_cfg, dev); + if (rslt == BMI160_OK) + { + /* Configure the INT PIN settings*/ + rslt = config_no_motion_int_settg(int_config, no_mot_int_cfg, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the step detection interrupt.This interrupt + * occurs when the single step causes accel values to go above + * preset threshold. + */ +static int8_t set_accel_step_detect_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_step_detect_int_cfg *step_detect_int_cfg = &(int_config->int_type_cfg.acc_step_detect_int); + rslt = enable_step_detect_int(step_detect_int_cfg, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_step_detect(step_detect_int_cfg, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the orientation interrupt of the sensor.This + * interrupt occurs when there is orientation change in the sensor + * with respect to gravitational field vector g. + */ +static int8_t set_accel_orientation_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_orient_int_cfg *orient_int_cfg = &(int_config->int_type_cfg.acc_orient_int); + rslt = enable_orient_int(orient_int_cfg, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + /* map INT pin to orient interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + /* configure the + * orientation setting*/ + rslt = config_orient_int_settg(orient_int_cfg, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the flat interrupt of the sensor.This interrupt + * occurs in case of flat orientation + */ +static int8_t set_accel_flat_detect_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_flat_detect_int_cfg *flat_detect_int = &(int_config->int_type_cfg.acc_flat_int); + + /* enable the flat interrupt */ + rslt = enable_flat_int(flat_detect_int, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + /* map INT pin to flat interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + /* configure the flat setting*/ + rslt = config_flat_int_settg(flat_detect_int, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the low-g interrupt of the sensor.This interrupt + * occurs during free-fall. + */ +static int8_t set_accel_low_g_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_low_g_int_cfg *low_g_int = &(int_config->int_type_cfg.acc_low_g_int); + + /* Enable the low-g interrupt*/ + rslt = enable_low_g_int(low_g_int, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + /* Map INT pin to low-g interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + /* configure the data source + * for low-g interrupt*/ + rslt = config_low_g_data_src(low_g_int, dev); + if (rslt == BMI160_OK) + { + rslt = config_low_g_int_settg(low_g_int, dev); + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API sets the high-g interrupt of the sensor.The interrupt + * occurs if the absolute value of acceleration data of any enabled axis + * exceeds the programmed threshold and the sign of the value does not + * change for a preset duration. + */ +static int8_t set_accel_high_g_int(struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if ((rslt != BMI160_OK) || (int_config == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* updating the interrupt structure to local structure */ + struct bmi160_acc_high_g_int_cfg *high_g_int_cfg = &(int_config->int_type_cfg.acc_high_g_int); + + /* Enable the high-g interrupt */ + rslt = enable_high_g_int(high_g_int_cfg, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + /* Map INT pin to high-g interrupt */ + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + /* configure the data source + * for high-g interrupt*/ + rslt = config_high_g_data_src(high_g_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_high_g_int_settg(high_g_int_cfg, dev); + } + } + } + } + } + + return rslt; +} + +/*! + * @brief This API configures the pins to fire the + * interrupt signal when it occurs. + */ +static int8_t set_intr_pin_config(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* configure the behavioural settings of interrupt pin */ + rslt = config_int_out_ctrl(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_int_latch(int_config, dev); + } + + return rslt; +} + +/*! + * @brief This internal API is used to validate the device structure pointer for + * null conditions. + */ +static int8_t null_ptr_check(const struct bmi160_dev *dev) +{ + int8_t rslt; + + if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Device structure is fine */ + rslt = BMI160_OK; + } + + return rslt; +} + +/*! + * @brief This API sets the default configuration parameters of accel & gyro. + * Also maintain the previous state of configurations. + */ +static void default_param_settg(struct bmi160_dev *dev) +{ + /* Initializing accel and gyro params with + * default values */ + dev->accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; + dev->accel_cfg.odr = BMI160_ACCEL_ODR_100HZ; + dev->accel_cfg.power = BMI160_ACCEL_SUSPEND_MODE; + dev->accel_cfg.range = BMI160_ACCEL_RANGE_2G; + dev->gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; + dev->gyro_cfg.odr = BMI160_GYRO_ODR_100HZ; + dev->gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE; + dev->gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; + + /* To maintain the previous state of accel configuration */ + dev->prev_accel_cfg = dev->accel_cfg; + + /* To maintain the previous state of gyro configuration */ + dev->prev_gyro_cfg = dev->gyro_cfg; +} + +/*! + * @brief This API set the accel configuration. + */ +static int8_t set_accel_conf(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0 }; + + rslt = check_accel_config(data, dev); + if (rslt == BMI160_OK) + { + /* Write output data rate and bandwidth */ + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, &data[0], 1, dev); + if (rslt == BMI160_OK) + { + dev->prev_accel_cfg.odr = dev->accel_cfg.odr; + dev->prev_accel_cfg.bw = dev->accel_cfg.bw; + + /* write accel range */ + rslt = bmi160_set_regs(BMI160_ACCEL_RANGE_ADDR, &data[1], 1, dev); + if (rslt == BMI160_OK) + { + dev->prev_accel_cfg.range = dev->accel_cfg.range; + } + } + } + + return rslt; +} + +/*! + * @brief This API gets the accel configuration. + */ +static int8_t get_accel_conf(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0 }; + + /* Get accel configurations */ + rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 2, dev); + if (rslt == BMI160_OK) + { + dev->accel_cfg.odr = (data[0] & BMI160_ACCEL_ODR_MASK); + dev->accel_cfg.bw = (data[0] & BMI160_ACCEL_BW_MASK) >> BMI160_ACCEL_BW_POS; + dev->accel_cfg.range = (data[1] & BMI160_ACCEL_RANGE_MASK); + } + + return rslt; +} + +/*! + * @brief This API check the accel configuration. + */ +static int8_t check_accel_config(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* read accel Output data rate and bandwidth */ + rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 2, dev); + if (rslt == BMI160_OK) + { + rslt = process_accel_odr(&data[0], dev); + if (rslt == BMI160_OK) + { + rslt = process_accel_bw(&data[0], dev); + if (rslt == BMI160_OK) + { + rslt = process_accel_range(&data[1], dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API process the accel odr. + */ +static int8_t process_accel_odr(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t odr = 0; + + if (dev->accel_cfg.odr <= BMI160_ACCEL_ODR_1600HZ) + { + if (dev->accel_cfg.odr != dev->prev_accel_cfg.odr) + { + odr = (uint8_t)dev->accel_cfg.odr; + temp = *data & ~BMI160_ACCEL_ODR_MASK; + + /* Adding output data rate */ + *data = temp | (odr & BMI160_ACCEL_ODR_MASK); + } + } + else + { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the accel bandwidth. + */ +static int8_t process_accel_bw(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t bw = 0; + + if (dev->accel_cfg.bw <= BMI160_ACCEL_BW_RES_AVG128) + { + if (dev->accel_cfg.bw != dev->prev_accel_cfg.bw) + { + bw = (uint8_t)dev->accel_cfg.bw; + temp = *data & ~BMI160_ACCEL_BW_MASK; + + /* Adding bandwidth */ + *data = temp | ((bw << 4) & BMI160_ACCEL_BW_MASK); + } + } + else + { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the accel range. + */ +static int8_t process_accel_range(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t range = 0; + + if (dev->accel_cfg.range <= BMI160_ACCEL_RANGE_16G) + { + if (dev->accel_cfg.range != dev->prev_accel_cfg.range) + { + range = (uint8_t)dev->accel_cfg.range; + temp = *data & ~BMI160_ACCEL_RANGE_MASK; + + /* Adding range */ + *data = temp | (range & BMI160_ACCEL_RANGE_MASK); + } + } + else + { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API checks the invalid settings for ODR & Bw for + * Accel and Gyro. + */ +static int8_t check_invalid_settg(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + /* read the error reg */ + rslt = bmi160_get_regs(BMI160_ERROR_REG_ADDR, &data, 1, dev); + data = data >> 1; + data = data & BMI160_ERR_REG_MASK; + if (data == 1) + { + rslt = BMI160_E_ACCEL_ODR_BW_INVALID; + } + else if (data == 2) + { + rslt = BMI160_E_GYRO_ODR_BW_INVALID; + } + else if (data == 3) + { + rslt = BMI160_E_LWP_PRE_FLTR_INT_INVALID; + } + else if (data == 7) + { + rslt = BMI160_E_LWP_PRE_FLTR_INVALID; + } + + return rslt; +} +static int8_t set_gyro_conf(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0 }; + + rslt = check_gyro_config(data, dev); + if (rslt == BMI160_OK) + { + /* Write output data rate and bandwidth */ + rslt = bmi160_set_regs(BMI160_GYRO_CONFIG_ADDR, &data[0], 1, dev); + if (rslt == BMI160_OK) + { + dev->prev_gyro_cfg.odr = dev->gyro_cfg.odr; + dev->prev_gyro_cfg.bw = dev->gyro_cfg.bw; + + /* Write gyro range */ + rslt = bmi160_set_regs(BMI160_GYRO_RANGE_ADDR, &data[1], 1, dev); + if (rslt == BMI160_OK) + { + dev->prev_gyro_cfg.range = dev->gyro_cfg.range; + } + } + } + + return rslt; +} + +/*! + * @brief This API gets the gyro configuration. + */ +static int8_t get_gyro_conf(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[2] = { 0 }; + + /* Get accel configurations */ + rslt = bmi160_get_regs(BMI160_GYRO_CONFIG_ADDR, data, 2, dev); + if (rslt == BMI160_OK) + { + dev->gyro_cfg.odr = (data[0] & BMI160_GYRO_ODR_MASK); + dev->gyro_cfg.bw = (data[0] & BMI160_GYRO_BW_MASK) >> BMI160_GYRO_BW_POS; + dev->gyro_cfg.range = (data[1] & BMI160_GYRO_RANGE_MASK); + } + + return rslt; +} + +/*! + * @brief This API check the gyro configuration. + */ +static int8_t check_gyro_config(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* read gyro Output data rate and bandwidth */ + rslt = bmi160_get_regs(BMI160_GYRO_CONFIG_ADDR, data, 2, dev); + if (rslt == BMI160_OK) + { + rslt = process_gyro_odr(&data[0], dev); + if (rslt == BMI160_OK) + { + rslt = process_gyro_bw(&data[0], dev); + if (rslt == BMI160_OK) + { + rslt = process_gyro_range(&data[1], dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API process the gyro odr. + */ +static int8_t process_gyro_odr(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t odr = 0; + + if (dev->gyro_cfg.odr <= BMI160_GYRO_ODR_3200HZ) + { + if (dev->gyro_cfg.odr != dev->prev_gyro_cfg.odr) + { + odr = (uint8_t)dev->gyro_cfg.odr; + temp = (*data & ~BMI160_GYRO_ODR_MASK); + + /* Adding output data rate */ + *data = temp | (odr & BMI160_GYRO_ODR_MASK); + } + } + else + { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the gyro bandwidth. + */ +static int8_t process_gyro_bw(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t bw = 0; + + if (dev->gyro_cfg.bw <= BMI160_GYRO_BW_NORMAL_MODE) + { + bw = (uint8_t)dev->gyro_cfg.bw; + temp = *data & ~BMI160_GYRO_BW_MASK; + + /* Adding bandwidth */ + *data = temp | ((bw << 4) & BMI160_GYRO_BW_MASK); + } + else + { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API process the gyro range. + */ +static int8_t process_gyro_range(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t temp = 0; + uint8_t range = 0; + + if (dev->gyro_cfg.range <= BMI160_GYRO_RANGE_125_DPS) + { + if (dev->gyro_cfg.range != dev->prev_gyro_cfg.range) + { + range = (uint8_t)dev->gyro_cfg.range; + temp = *data & ~BMI160_GYRO_RANGE_MASK; + + /* Adding range */ + *data = temp | (range & BMI160_GYRO_RANGE_MASK); + } + } + else + { + rslt = BMI160_E_OUT_OF_RANGE; + } + + return rslt; +} + +/*! + * @brief This API sets the accel power. + */ +static int8_t set_accel_pwr(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + uint8_t data = 0; + + if ((dev->accel_cfg.power >= BMI160_ACCEL_SUSPEND_MODE) && (dev->accel_cfg.power <= BMI160_ACCEL_LOWPOWER_MODE)) + { + if (dev->accel_cfg.power != dev->prev_accel_cfg.power) + { + rslt = process_under_sampling(&data, dev); + if (rslt == BMI160_OK) + { + /* Write accel power */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->accel_cfg.power, 1, dev); + + /* Add delay of 3.8 ms - refer data sheet table 24*/ + if (dev->prev_accel_cfg.power == BMI160_ACCEL_SUSPEND_MODE) + { + dev->delay_ms(BMI160_ACCEL_DELAY_MS); + } + + dev->prev_accel_cfg.power = dev->accel_cfg.power; + } + } + } + else + { + rslt = BMI160_E_INVALID_CONFIG; + } + + return rslt; +} + +/*! + * @brief This API process the undersampling setting of Accel. + */ +static int8_t process_under_sampling(uint8_t *data, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t pre_filter[2] = { 0 }; + + rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); + if (rslt == BMI160_OK) + { + if (dev->accel_cfg.power == BMI160_ACCEL_LOWPOWER_MODE) + { + temp = *data & ~BMI160_ACCEL_UNDERSAMPLING_MASK; + + /* Set under-sampling parameter */ + *data = temp | ((1 << 7) & BMI160_ACCEL_UNDERSAMPLING_MASK); + + /* Write data */ + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); + + /* Disable the pre-filter data in low power mode */ + if (rslt == BMI160_OK) + { + /* Disable the Pre-filter data*/ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, pre_filter, 2, dev); + } + } + else if (*data & BMI160_ACCEL_UNDERSAMPLING_MASK) + { + temp = *data & ~BMI160_ACCEL_UNDERSAMPLING_MASK; + + /* Disable under-sampling parameter if already enabled */ + *data = temp; + + /* Write data */ + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API sets the gyro power mode. + */ +static int8_t set_gyro_pwr(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + + if ((dev->gyro_cfg.power == BMI160_GYRO_SUSPEND_MODE) || (dev->gyro_cfg.power == BMI160_GYRO_NORMAL_MODE) || + (dev->gyro_cfg.power == BMI160_GYRO_FASTSTARTUP_MODE)) + { + if (dev->gyro_cfg.power != dev->prev_gyro_cfg.power) + { + /* Write gyro power */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->gyro_cfg.power, 1, dev); + if (dev->prev_gyro_cfg.power == BMI160_GYRO_SUSPEND_MODE) + { + /* Delay of 80 ms - datasheet Table 24 */ + dev->delay_ms(BMI160_GYRO_DELAY_MS); + } + else if ((dev->prev_gyro_cfg.power == BMI160_GYRO_FASTSTARTUP_MODE) && + (dev->gyro_cfg.power == BMI160_GYRO_NORMAL_MODE)) + { + /* This delay is required for transition from + * fast-startup mode to normal mode - datasheet Table 3 */ + dev->delay_ms(10); + } + else + { + /* do nothing */ + } + + dev->prev_gyro_cfg.power = dev->gyro_cfg.power; + } + } + else + { + rslt = BMI160_E_INVALID_CONFIG; + } + + return rslt; +} + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + */ +static int8_t get_accel_data(uint8_t len, struct bmi160_sensor_data *accel, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t idx = 0; + uint8_t data_array[9] = { 0 }; + uint8_t time_0 = 0; + uint16_t time_1 = 0; + uint32_t time_2 = 0; + uint8_t lsb; + uint8_t msb; + int16_t msblsb; + + /* read accel sensor data along with time if requested */ + rslt = bmi160_get_regs(BMI160_ACCEL_DATA_ADDR, data_array, 6 + len, dev); + if (rslt == BMI160_OK) + { + /* Accel Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->x = msblsb; /* Data in X axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->y = msblsb; /* Data in Y axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->z = msblsb; /* Data in Z axis */ + if (len == 3) + { + time_0 = data_array[idx++]; + time_1 = (uint16_t)(data_array[idx++] << 8); + time_2 = (uint32_t)(data_array[idx++] << 16); + accel->sensortime = (uint32_t)(time_2 | time_1 | time_0); + } + else + { + accel->sensortime = 0; + } + } + else + { + rslt = BMI160_E_COM_FAIL; + } + + return rslt; +} + +/*! + * @brief This API reads accel data along with sensor time if time is requested + * by user. Kindly refer the user guide(README.md) for more info. + */ +static int8_t get_gyro_data(uint8_t len, struct bmi160_sensor_data *gyro, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t idx = 0; + uint8_t data_array[15] = { 0 }; + uint8_t time_0 = 0; + uint16_t time_1 = 0; + uint32_t time_2 = 0; + uint8_t lsb; + uint8_t msb; + int16_t msblsb; + + if (len == 0) + { + /* read gyro data only */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 6, dev); + if (rslt == BMI160_OK) + { + /* Gyro Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->x = msblsb; /* Data in X axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->y = msblsb; /* Data in Y axis */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->z = msblsb; /* Data in Z axis */ + gyro->sensortime = 0; + } + else + { + rslt = BMI160_E_COM_FAIL; + } + } + else + { + /* read gyro sensor data along with time */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 12 + len, dev); + if (rslt == BMI160_OK) + { + /* Gyro Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->x = msblsb; /* gyro X axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->y = msblsb; /* gyro Y axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->z = msblsb; /* gyro Z axis data */ + idx = idx + 6; + time_0 = data_array[idx++]; + time_1 = (uint16_t)(data_array[idx++] << 8); + time_2 = (uint32_t)(data_array[idx++] << 16); + gyro->sensortime = (uint32_t)(time_2 | time_1 | time_0); + } + else + { + rslt = BMI160_E_COM_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API reads accel and gyro data along with sensor time + * if time is requested by user. + * Kindly refer the user guide(README.md) for more info. + */ +static int8_t get_accel_gyro_data(uint8_t len, + struct bmi160_sensor_data *accel, + struct bmi160_sensor_data *gyro, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t idx = 0; + uint8_t data_array[15] = { 0 }; + uint8_t time_0 = 0; + uint16_t time_1 = 0; + uint32_t time_2 = 0; + uint8_t lsb; + uint8_t msb; + int16_t msblsb; + + /* read both accel and gyro sensor data + * along with time if requested */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 12 + len, dev); + if (rslt == BMI160_OK) + { + /* Gyro Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->x = msblsb; /* gyro X axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->y = msblsb; /* gyro Y axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + gyro->z = msblsb; /* gyro Z axis data */ + /* Accel Data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->x = (int16_t)msblsb; /* accel X axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->y = (int16_t)msblsb; /* accel Y axis data */ + lsb = data_array[idx++]; + msb = data_array[idx++]; + msblsb = (int16_t)((msb << 8) | lsb); + accel->z = (int16_t)msblsb; /* accel Z axis data */ + if (len == 3) + { + time_0 = data_array[idx++]; + time_1 = (uint16_t)(data_array[idx++] << 8); + time_2 = (uint32_t)(data_array[idx++] << 16); + accel->sensortime = (uint32_t)(time_2 | time_1 | time_0); + gyro->sensortime = (uint32_t)(time_2 | time_1 | time_0); + } + else + { + accel->sensortime = 0; + gyro->sensortime = 0; + } + } + else + { + rslt = BMI160_E_COM_FAIL; + } + + return rslt; +} + +/*! + * @brief This API enables the any-motion interrupt for accel. + */ +static int8_t enable_accel_any_motion_int(const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable any motion x, any motion y, any motion z + * in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + if (any_motion_int_cfg->anymotion_en == BMI160_ENABLE) + { + temp = data & ~BMI160_ANY_MOTION_X_INT_EN_MASK; + + /* Adding Any_motion x axis */ + data = temp | (any_motion_int_cfg->anymotion_x & BMI160_ANY_MOTION_X_INT_EN_MASK); + temp = data & ~BMI160_ANY_MOTION_Y_INT_EN_MASK; + + /* Adding Any_motion y axis */ + data = temp | ((any_motion_int_cfg->anymotion_y << 1) & BMI160_ANY_MOTION_Y_INT_EN_MASK); + temp = data & ~BMI160_ANY_MOTION_Z_INT_EN_MASK; + + /* Adding Any_motion z axis */ + data = temp | ((any_motion_int_cfg->anymotion_z << 2) & BMI160_ANY_MOTION_Z_INT_EN_MASK); + + /* any-motion feature selected*/ + dev->any_sig_sel = BMI160_ANY_MOTION_ENABLED; + } + else + { + data = data & ~BMI160_ANY_MOTION_ALL_INT_EN_MASK; + + /* neither any-motion feature nor sig-motion selected */ + dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; + } + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API disable the sig-motion interrupt. + */ +static int8_t disable_sig_motion_int(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Disabling Significant motion interrupt if enabled */ + rslt = bmi160_get_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = (data & BMI160_SIG_MOTION_SEL_MASK); + if (temp) + { + temp = data & ~BMI160_SIG_MOTION_SEL_MASK; + data = temp; + + /* Write data to register */ + rslt = bmi160_set_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API is used to map/unmap the Any/Sig motion, Step det/Low-g, + * Double tap, Single tap, Orientation, Flat, High-G, Nomotion interrupt pins. + */ +static int8_t map_feature_interrupt(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[3] = { 0, 0, 0 }; + uint8_t temp[3] = { 0, 0, 0 }; + + rslt = bmi160_get_regs(BMI160_INT_MAP_0_ADDR, data, 3, dev); + if (rslt == BMI160_OK) + { + temp[0] = data[0] & ~int_mask_lookup_table[int_config->int_type]; + temp[2] = data[2] & ~int_mask_lookup_table[int_config->int_type]; + switch (int_config->int_channel) + { + case BMI160_INT_CHANNEL_NONE: + data[0] = temp[0]; + data[2] = temp[2]; + break; + case BMI160_INT_CHANNEL_1: + data[0] = temp[0] | int_mask_lookup_table[int_config->int_type]; + data[2] = temp[2]; + break; + case BMI160_INT_CHANNEL_2: + data[2] = temp[2] | int_mask_lookup_table[int_config->int_type]; + data[0] = temp[0]; + break; + case BMI160_INT_CHANNEL_BOTH: + data[0] = temp[0] | int_mask_lookup_table[int_config->int_type]; + data[2] = temp[2] | int_mask_lookup_table[int_config->int_type]; + break; + default: + rslt = BMI160_E_OUT_OF_RANGE; + } + if (rslt == BMI160_OK) + { + rslt = bmi160_set_regs(BMI160_INT_MAP_0_ADDR, data, 3, dev); + } + } + + return rslt; +} + +/*! + * @brief This API is used to map/unmap the Dataready(Accel & Gyro), FIFO full + * and FIFO watermark interrupt. + */ +static int8_t map_hardware_interrupt(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + rslt = bmi160_get_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~int_mask_lookup_table[int_config->int_type]; + temp = temp & ~((uint8_t)(int_mask_lookup_table[int_config->int_type] << 4)); + switch (int_config->int_channel) + { + case BMI160_INT_CHANNEL_NONE: + data = temp; + break; + case BMI160_INT_CHANNEL_1: + data = temp | (uint8_t)((int_mask_lookup_table[int_config->int_type]) << 4); + break; + case BMI160_INT_CHANNEL_2: + data = temp | int_mask_lookup_table[int_config->int_type]; + break; + case BMI160_INT_CHANNEL_BOTH: + data = temp | int_mask_lookup_table[int_config->int_type]; + data = data | (uint8_t)((int_mask_lookup_table[int_config->int_type]) << 4); + break; + default: + rslt = BMI160_E_OUT_OF_RANGE; + } + if (rslt == BMI160_OK) + { + rslt = bmi160_set_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for any-motion interrupt. + */ +static int8_t config_any_motion_src(const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 1 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_MOTION_SRC_INT_MASK; + data = temp | ((any_motion_int_cfg->anymotion_data_src << 7) & BMI160_MOTION_SRC_INT_MASK); + + /* Write data to DATA 1 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the duration and threshold of + * any-motion interrupt. + */ +static int8_t config_any_dur_threshold(const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t data_array[2] = { 0 }; + uint8_t dur; + + /* Configure Int Motion 0 register */ + rslt = bmi160_get_regs(BMI160_INT_MOTION_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* slope duration */ + dur = (uint8_t)any_motion_int_cfg->anymotion_dur; + temp = data & ~BMI160_SLOPE_INT_DUR_MASK; + data = temp | (dur & BMI160_MOTION_SRC_INT_MASK); + data_array[0] = data; + + /* add slope threshold */ + data_array[1] = any_motion_int_cfg->anymotion_thr; + + /* INT MOTION 0 and INT MOTION 1 address lie consecutively, + * hence writing data to respective registers at one go */ + + /* Writing to Int_motion 0 and + * Int_motion 1 Address simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_MOTION_0_ADDR, data_array, 2, dev); + } + + return rslt; +} + +/*! + * @brief This API configure necessary setting of any-motion interrupt. + */ +static int8_t config_any_motion_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_any_mot_int_cfg *any_motion_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = disable_sig_motion_int(dev); + if (rslt == BMI160_OK) + { + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_any_motion_src(any_motion_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_any_dur_threshold(any_motion_int_cfg, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API enable the data ready interrupt. + */ +static int8_t enable_data_ready_int(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable data ready interrupt in Int Enable 1 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_DATA_RDY_INT_EN_MASK; + data = temp | ((1 << 4) & BMI160_DATA_RDY_INT_EN_MASK); + + /* Writing data to INT ENABLE 1 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the no motion/slow motion interrupt. + */ +static int8_t enable_no_motion_int(const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable no motion x, no motion y, no motion z + * in Int Enable 2 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + if (no_mot_int_cfg->no_motion_x == 1) + { + temp = data & ~BMI160_NO_MOTION_X_INT_EN_MASK; + + /* Adding No_motion x axis */ + data = temp | (1 & BMI160_NO_MOTION_X_INT_EN_MASK); + } + + if (no_mot_int_cfg->no_motion_y == 1) + { + temp = data & ~BMI160_NO_MOTION_Y_INT_EN_MASK; + + /* Adding No_motion x axis */ + data = temp | ((1 << 1) & BMI160_NO_MOTION_Y_INT_EN_MASK); + } + + if (no_mot_int_cfg->no_motion_z == 1) + { + temp = data & ~BMI160_NO_MOTION_Z_INT_EN_MASK; + + /* Adding No_motion x axis */ + data = temp | ((1 << 2) & BMI160_NO_MOTION_Z_INT_EN_MASK); + } + + /* write data to Int Enable 2 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the interrupt PIN setting for + * no motion/slow motion interrupt. + */ +static int8_t config_no_motion_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_no_motion_data_src(no_mot_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_no_motion_dur_thr(no_mot_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of interrupt for no motion. + */ +static int8_t config_no_motion_data_src(const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 1 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_MOTION_SRC_INT_MASK; + data = temp | ((no_mot_int_cfg->no_motion_src << 7) & BMI160_MOTION_SRC_INT_MASK); + + /* Write data to DATA 1 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the duration and threshold of + * no motion/slow motion interrupt along with selection of no/slow motion. + */ +static int8_t config_no_motion_dur_thr(const struct bmi160_acc_no_motion_int_cfg *no_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t temp_1 = 0; + uint8_t reg_addr; + uint8_t data_array[2] = { 0 }; + + /* Configuring INT_MOTION register */ + reg_addr = BMI160_INT_MOTION_0_ADDR; + rslt = bmi160_get_regs(reg_addr, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_NO_MOTION_INT_DUR_MASK; + + /* Adding no_motion duration */ + data = temp | ((no_mot_int_cfg->no_motion_dur << 2) & BMI160_NO_MOTION_INT_DUR_MASK); + + /* Write data to NO_MOTION 0 address */ + rslt = bmi160_set_regs(reg_addr, &data, 1, dev); + if (rslt == BMI160_OK) + { + reg_addr = BMI160_INT_MOTION_3_ADDR; + rslt = bmi160_get_regs(reg_addr, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_NO_MOTION_SEL_BIT_MASK; + + /* Adding no_motion_sel bit */ + temp_1 = (no_mot_int_cfg->no_motion_sel & BMI160_NO_MOTION_SEL_BIT_MASK); + data = (temp | temp_1); + data_array[1] = data; + + /* Adding no motion threshold */ + data_array[0] = no_mot_int_cfg->no_motion_thres; + reg_addr = BMI160_INT_MOTION_2_ADDR; + + /* writing data to INT_MOTION 2 and INT_MOTION 3 + * address simultaneously */ + rslt = bmi160_set_regs(reg_addr, data_array, 2, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API enables the sig-motion motion interrupt. + */ +static int8_t enable_sig_motion_int(const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* For significant motion,enable any motion x,any motion y, + * any motion z in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + if (sig_mot_int_cfg->sig_en == BMI160_ENABLE) + { + temp = data & ~BMI160_SIG_MOTION_INT_EN_MASK; + data = temp | (7 & BMI160_SIG_MOTION_INT_EN_MASK); + + /* sig-motion feature selected*/ + dev->any_sig_sel = BMI160_SIG_MOTION_ENABLED; + } + else + { + data = data & ~BMI160_SIG_MOTION_INT_EN_MASK; + + /* neither any-motion feature nor sig-motion selected */ + dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; + } + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the interrupt PIN setting for + * significant motion interrupt. + */ +static int8_t config_sig_motion_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_sig_motion_data_src(sig_mot_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_sig_dur_threshold(sig_mot_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for sig motion interrupt. + */ +static int8_t config_sig_motion_data_src(const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 1 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_MOTION_SRC_INT_MASK; + data = temp | ((sig_mot_int_cfg->sig_data_src << 7) & BMI160_MOTION_SRC_INT_MASK); + + /* Write data to DATA 1 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the threshold, skip and proof time of + * sig motion interrupt. + */ +static int8_t config_sig_dur_threshold(const struct bmi160_acc_sig_mot_int_cfg *sig_mot_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data; + uint8_t temp = 0; + + /* Configuring INT_MOTION registers */ + + /* Write significant motion threshold. + * This threshold is same as any motion threshold */ + data = sig_mot_int_cfg->sig_mot_thres; + + /* Write data to INT_MOTION 1 address */ + rslt = bmi160_set_regs(BMI160_INT_MOTION_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + rslt = bmi160_get_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_SIG_MOTION_SKIP_MASK; + + /* adding skip time of sig_motion interrupt*/ + data = temp | ((sig_mot_int_cfg->sig_mot_skip << 2) & BMI160_SIG_MOTION_SKIP_MASK); + temp = data & ~BMI160_SIG_MOTION_PROOF_MASK; + + /* adding proof time of sig_motion interrupt */ + data = temp | ((sig_mot_int_cfg->sig_mot_proof << 4) & BMI160_SIG_MOTION_PROOF_MASK); + + /* configure the int_sig_mot_sel bit to select + * significant motion interrupt */ + temp = data & ~BMI160_SIG_MOTION_SEL_MASK; + data = temp | ((sig_mot_int_cfg->sig_en << 1) & BMI160_SIG_MOTION_SEL_MASK); + rslt = bmi160_set_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API enables the step detector interrupt. + */ +static int8_t enable_step_detect_int(const struct bmi160_acc_step_detect_int_cfg *step_detect_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable data ready interrupt in Int Enable 2 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_STEP_DETECT_INT_EN_MASK; + data = temp | ((step_detect_int_cfg->step_detector_en << 3) & BMI160_STEP_DETECT_INT_EN_MASK); + + /* Writing data to INT ENABLE 2 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the step detector parameter. + */ +static int8_t config_step_detect(const struct bmi160_acc_step_detect_int_cfg *step_detect_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t data_array[2] = { 0 }; + + if (step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_NORMAL) + { + /* Normal mode setting */ + data_array[0] = 0x15; + data_array[1] = 0x03; + } + else if (step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_SENSITIVE) + { + /* Sensitive mode setting */ + data_array[0] = 0x2D; + data_array[1] = 0x00; + } + else if (step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_ROBUST) + { + /* Robust mode setting */ + data_array[0] = 0x1D; + data_array[1] = 0x07; + } + else if (step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_USER_DEFINE) + { + /* Non recommended User defined setting */ + /* Configuring STEP_CONFIG register */ + rslt = bmi160_get_regs(BMI160_INT_STEP_CONFIG_0_ADDR, &data_array[0], 2, dev); + if (rslt == BMI160_OK) + { + temp = data_array[0] & ~BMI160_STEP_DETECT_MIN_THRES_MASK; + + /* Adding min_threshold */ + data_array[0] = temp | ((step_detect_int_cfg->min_threshold << 3) & BMI160_STEP_DETECT_MIN_THRES_MASK); + temp = data_array[0] & ~BMI160_STEP_DETECT_STEPTIME_MIN_MASK; + + /* Adding steptime_min */ + data_array[0] = temp | ((step_detect_int_cfg->steptime_min) & BMI160_STEP_DETECT_STEPTIME_MIN_MASK); + temp = data_array[1] & ~BMI160_STEP_MIN_BUF_MASK; + + /* Adding steptime_min */ + data_array[1] = temp | ((step_detect_int_cfg->step_min_buf) & BMI160_STEP_MIN_BUF_MASK); + } + } + + /* Write data to STEP_CONFIG register */ + rslt = bmi160_set_regs(BMI160_INT_STEP_CONFIG_0_ADDR, data_array, 2, dev); + + return rslt; +} + +/*! + * @brief This API enables the single/double tap interrupt. + */ +static int8_t enable_tap_int(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_tap_int_cfg *tap_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable single tap or double tap interrupt in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + if (int_config->int_type == BMI160_ACC_SINGLE_TAP_INT) + { + temp = data & ~BMI160_SINGLE_TAP_INT_EN_MASK; + data = temp | ((tap_int_cfg->tap_en << 5) & BMI160_SINGLE_TAP_INT_EN_MASK); + } + else + { + temp = data & ~BMI160_DOUBLE_TAP_INT_EN_MASK; + data = temp | ((tap_int_cfg->tap_en << 4) & BMI160_DOUBLE_TAP_INT_EN_MASK); + } + + /* Write to Enable 0 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the interrupt PIN setting for + * tap interrupt. + */ +static int8_t config_tap_int_settg(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_tap_int_cfg *tap_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_feature_interrupt(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = config_tap_data_src(tap_int_cfg, dev); + if (rslt == BMI160_OK) + { + rslt = config_tap_param(int_config, tap_int_cfg, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for tap interrupt. + */ +static int8_t config_tap_data_src(const struct bmi160_acc_tap_int_cfg *tap_int_cfg, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 0 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_TAP_SRC_INT_MASK; + data = temp | ((tap_int_cfg->tap_data_src << 3) & BMI160_TAP_SRC_INT_MASK); + + /* Write data to Data 0 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the parameters of tap interrupt. + * Threshold, quite, shock, and duration. + */ +static int8_t config_tap_param(const struct bmi160_int_settg *int_config, + const struct bmi160_acc_tap_int_cfg *tap_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t data = 0; + uint8_t data_array[2] = { 0 }; + uint8_t count = 0; + uint8_t dur, shock, quiet, thres; + + /* Configure tap 0 register for tap shock,tap quiet duration + * in case of single tap interrupt */ + rslt = bmi160_get_regs(BMI160_INT_TAP_0_ADDR, data_array, 2, dev); + if (rslt == BMI160_OK) + { + data = data_array[count]; + if (int_config->int_type == BMI160_ACC_DOUBLE_TAP_INT) + { + dur = (uint8_t)tap_int_cfg->tap_dur; + temp = (data & ~BMI160_TAP_DUR_MASK); + + /* Add tap duration data in case of + * double tap interrupt */ + data = temp | (dur & BMI160_TAP_DUR_MASK); + } + + shock = (uint8_t)tap_int_cfg->tap_shock; + temp = data & ~BMI160_TAP_SHOCK_DUR_MASK; + data = temp | ((shock << 6) & BMI160_TAP_SHOCK_DUR_MASK); + quiet = (uint8_t)tap_int_cfg->tap_quiet; + temp = data & ~BMI160_TAP_QUIET_DUR_MASK; + data = temp | ((quiet << 7) & BMI160_TAP_QUIET_DUR_MASK); + data_array[count++] = data; + data = data_array[count]; + thres = (uint8_t)tap_int_cfg->tap_thr; + temp = data & ~BMI160_TAP_THRES_MASK; + data = temp | (thres & BMI160_TAP_THRES_MASK); + data_array[count++] = data; + + /* TAP 0 and TAP 1 address lie consecutively, + * hence writing data to respective registers at one go */ + + /* Writing to Tap 0 and Tap 1 Address simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_TAP_0_ADDR, data_array, count, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the secondary interface. + */ +static int8_t config_sec_if(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t if_conf = 0; + uint8_t cmd = BMI160_AUX_NORMAL_MODE; + + /* set the aux power mode to normal*/ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if (rslt == BMI160_OK) + { + /* 0.5ms delay - refer datasheet table 24*/ + dev->delay_ms(1); + rslt = bmi160_get_regs(BMI160_IF_CONF_ADDR, &if_conf, 1, dev); + if_conf |= (uint8_t)(1 << 5); + if (rslt == BMI160_OK) + { + /*enable the secondary interface also*/ + rslt = bmi160_set_regs(BMI160_IF_CONF_ADDR, &if_conf, 1, dev); + } + } + + return rslt; +} + +/*! + * @brief This API configure the ODR of the auxiliary sensor. + */ +static int8_t config_aux_odr(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t aux_odr; + + rslt = bmi160_get_regs(BMI160_AUX_ODR_ADDR, &aux_odr, 1, dev); + if (rslt == BMI160_OK) + { + aux_odr = (uint8_t)(dev->aux_cfg.aux_odr); + + /* Set the secondary interface ODR + * i.e polling rate of secondary sensor */ + rslt = bmi160_set_regs(BMI160_AUX_ODR_ADDR, &aux_odr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + } + + return rslt; +} + +/*! + * @brief This API maps the actual burst read length set by user. + */ +static int8_t map_read_len(uint16_t *len, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + switch (dev->aux_cfg.aux_rd_burst_len) + { + case BMI160_AUX_READ_LEN_0: + *len = 1; + break; + case BMI160_AUX_READ_LEN_1: + *len = 2; + break; + case BMI160_AUX_READ_LEN_2: + *len = 6; + break; + case BMI160_AUX_READ_LEN_3: + *len = 8; + break; + default: + rslt = BMI160_E_INVALID_INPUT; + break; + } + + return rslt; +} + +/*! + * @brief This API configure the settings of auxiliary sensor. + */ +static int8_t config_aux_settg(const struct bmi160_dev *dev) +{ + int8_t rslt; + + rslt = config_sec_if(dev); + if (rslt == BMI160_OK) + { + /* Configures the auxiliary interface settings */ + rslt = bmi160_config_aux_mode(dev); + } + + return rslt; +} + +/*! + * @brief This API extract the read data from auxiliary sensor. + */ +static int8_t extract_aux_read(uint16_t map_len, + uint8_t reg_addr, + uint8_t *aux_data, + uint16_t len, + const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + uint8_t data[8] = { 0, }; + uint8_t read_addr = BMI160_AUX_DATA_ADDR; + uint8_t count = 0; + uint8_t read_count; + uint8_t read_len = (uint8_t)map_len; + + for (; count < len;) + { + /* set address to read */ + rslt = bmi160_set_regs(BMI160_AUX_IF_2_ADDR, ®_addr, 1, dev); + dev->delay_ms(BMI160_AUX_COM_DELAY); + if (rslt == BMI160_OK) + { + rslt = bmi160_get_regs(read_addr, data, map_len, dev); + if (rslt == BMI160_OK) + { + read_count = 0; + + /* if read len is less the burst read len + * mention by user*/ + if (len < map_len) + { + read_len = (uint8_t)len; + } + else if ((len - count) < map_len) + { + read_len = (uint8_t)(len - count); + } + + for (; read_count < read_len; read_count++) + { + aux_data[count + read_count] = data[read_count]; + } + + reg_addr += (uint8_t)map_len; + count += (uint8_t)map_len; + } + else + { + rslt = BMI160_E_COM_FAIL; + break; + } + } + } + + return rslt; +} + +/*! + * @brief This API enables the orient interrupt. + */ +static int8_t enable_orient_int(const struct bmi160_acc_orient_int_cfg *orient_int_cfg, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable data ready interrupt in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_ORIENT_INT_EN_MASK; + data = temp | ((orient_int_cfg->orient_en << 6) & BMI160_ORIENT_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of orientation interrupt. + */ +static int8_t config_orient_int_settg(const struct bmi160_acc_orient_int_cfg *orient_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t data_array[2] = { 0, 0 }; + + /* Configuring INT_ORIENT registers */ + rslt = bmi160_get_regs(BMI160_INT_ORIENT_0_ADDR, data_array, 2, dev); + if (rslt == BMI160_OK) + { + data = data_array[0]; + temp = data & ~BMI160_ORIENT_MODE_MASK; + + /* Adding Orientation mode */ + data = temp | ((orient_int_cfg->orient_mode) & BMI160_ORIENT_MODE_MASK); + temp = data & ~BMI160_ORIENT_BLOCK_MASK; + + /* Adding Orientation blocking */ + data = temp | ((orient_int_cfg->orient_blocking << 2) & BMI160_ORIENT_BLOCK_MASK); + temp = data & ~BMI160_ORIENT_HYST_MASK; + + /* Adding Orientation hysteresis */ + data = temp | ((orient_int_cfg->orient_hyst << 4) & BMI160_ORIENT_HYST_MASK); + data_array[0] = data; + data = data_array[1]; + temp = data & ~BMI160_ORIENT_THETA_MASK; + + /* Adding Orientation threshold */ + data = temp | ((orient_int_cfg->orient_theta) & BMI160_ORIENT_THETA_MASK); + temp = data & ~BMI160_ORIENT_UD_ENABLE; + + /* Adding Orient_ud_en */ + data = temp | ((orient_int_cfg->orient_ud_en << 6) & BMI160_ORIENT_UD_ENABLE); + temp = data & ~BMI160_AXES_EN_MASK; + + /* Adding axes_en */ + data = temp | ((orient_int_cfg->axes_ex << 7) & BMI160_AXES_EN_MASK); + data_array[1] = data; + + /* Writing data to INT_ORIENT 0 and INT_ORIENT 1 + * registers simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_ORIENT_0_ADDR, data_array, 2, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the flat interrupt. + */ +static int8_t enable_flat_int(const struct bmi160_acc_flat_detect_int_cfg *flat_int, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable flat interrupt in Int Enable 0 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_FLAT_INT_EN_MASK; + data = temp | ((flat_int->flat_en << 7) & BMI160_FLAT_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of flat interrupt. + */ +static int8_t config_flat_int_settg(const struct bmi160_acc_flat_detect_int_cfg *flat_int, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + uint8_t data_array[2] = { 0, 0 }; + + /* Configuring INT_FLAT register */ + rslt = bmi160_get_regs(BMI160_INT_FLAT_0_ADDR, data_array, 2, dev); + if (rslt == BMI160_OK) + { + data = data_array[0]; + temp = data & ~BMI160_FLAT_THRES_MASK; + + /* Adding flat theta */ + data = temp | ((flat_int->flat_theta) & BMI160_FLAT_THRES_MASK); + data_array[0] = data; + data = data_array[1]; + temp = data & ~BMI160_FLAT_HOLD_TIME_MASK; + + /* Adding flat hold time */ + data = temp | ((flat_int->flat_hold_time << 4) & BMI160_FLAT_HOLD_TIME_MASK); + temp = data & ~BMI160_FLAT_HYST_MASK; + + /* Adding flat hysteresis */ + data = temp | ((flat_int->flat_hy) & BMI160_FLAT_HYST_MASK); + data_array[1] = data; + + /* Writing data to INT_FLAT 0 and INT_FLAT 1 + * registers simultaneously */ + rslt = bmi160_set_regs(BMI160_INT_FLAT_0_ADDR, data_array, 2, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the Low-g interrupt. + */ +static int8_t enable_low_g_int(const struct bmi160_acc_low_g_int_cfg *low_g_int, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable low-g interrupt in Int Enable 1 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_LOW_G_INT_EN_MASK; + data = temp | ((low_g_int->low_en << 3) & BMI160_LOW_G_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for low-g interrupt. + */ +static int8_t config_low_g_data_src(const struct bmi160_acc_low_g_int_cfg *low_g_int, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 0 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_LOW_HIGH_SRC_INT_MASK; + data = temp | ((low_g_int->low_data_src << 7) & BMI160_LOW_HIGH_SRC_INT_MASK); + + /* Write data to Data 0 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of low-g interrupt. + */ +static int8_t config_low_g_int_settg(const struct bmi160_acc_low_g_int_cfg *low_g_int, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t data_array[3] = { 0, 0, 0 }; + + /* Configuring INT_LOWHIGH register for low-g interrupt */ + rslt = bmi160_get_regs(BMI160_INT_LOWHIGH_2_ADDR, &data_array[2], 1, dev); + if (rslt == BMI160_OK) + { + temp = data_array[2] & ~BMI160_LOW_G_HYST_MASK; + + /* Adding low-g hysteresis */ + data_array[2] = temp | (low_g_int->low_hyst & BMI160_LOW_G_HYST_MASK); + temp = data_array[2] & ~BMI160_LOW_G_LOW_MODE_MASK; + + /* Adding low-mode */ + data_array[2] = temp | ((low_g_int->low_mode << 2) & BMI160_LOW_G_LOW_MODE_MASK); + + /* Adding low-g threshold */ + data_array[1] = low_g_int->low_thres; + + /* Adding low-g interrupt delay */ + data_array[0] = low_g_int->low_dur; + + /* Writing data to INT_LOWHIGH 0,1,2 registers simultaneously*/ + rslt = bmi160_set_regs(BMI160_INT_LOWHIGH_0_ADDR, data_array, 3, dev); + } + + return rslt; +} + +/*! + * @brief This API enables the high-g interrupt. + */ +static int8_t enable_high_g_int(const struct bmi160_acc_high_g_int_cfg *high_g_int_cfg, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Enable low-g interrupt in Int Enable 1 register */ + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* Adding high-g X-axis */ + temp = data & ~BMI160_HIGH_G_X_INT_EN_MASK; + data = temp | (high_g_int_cfg->high_g_x & BMI160_HIGH_G_X_INT_EN_MASK); + + /* Adding high-g Y-axis */ + temp = data & ~BMI160_HIGH_G_Y_INT_EN_MASK; + data = temp | ((high_g_int_cfg->high_g_y << 1) & BMI160_HIGH_G_Y_INT_EN_MASK); + + /* Adding high-g Z-axis */ + temp = data & ~BMI160_HIGH_G_Z_INT_EN_MASK; + data = temp | ((high_g_int_cfg->high_g_z << 2) & BMI160_HIGH_G_Z_INT_EN_MASK); + + /* write data to Int Enable 0 register */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the source of data(filter & pre-filter) + * for high-g interrupt. + */ +static int8_t config_high_g_data_src(const struct bmi160_acc_high_g_int_cfg *high_g_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + uint8_t temp = 0; + + /* Configure Int data 0 register to add source of interrupt */ + rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + temp = data & ~BMI160_LOW_HIGH_SRC_INT_MASK; + data = temp | ((high_g_int_cfg->high_data_src << 7) & BMI160_LOW_HIGH_SRC_INT_MASK); + + /* Write data to Data 0 address */ + rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the necessary setting of high-g interrupt. + */ +static int8_t config_high_g_int_settg(const struct bmi160_acc_high_g_int_cfg *high_g_int_cfg, + const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t data_array[3] = { 0, 0, 0 }; + + rslt = bmi160_get_regs(BMI160_INT_LOWHIGH_2_ADDR, &data_array[0], 1, dev); + if (rslt == BMI160_OK) + { + temp = data_array[0] & ~BMI160_HIGH_G_HYST_MASK; + + /* Adding high-g hysteresis */ + data_array[0] = temp | ((high_g_int_cfg->high_hy << 6) & BMI160_HIGH_G_HYST_MASK); + + /* Adding high-g duration */ + data_array[1] = high_g_int_cfg->high_dur; + + /* Adding high-g threshold */ + data_array[2] = high_g_int_cfg->high_thres; + rslt = bmi160_set_regs(BMI160_INT_LOWHIGH_2_ADDR, data_array, 3, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the behavioural setting of interrupt pin. + */ +static int8_t config_int_out_ctrl(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t data = 0; + + /* Configuration of output interrupt signals on pins INT1 and INT2 are + * done in BMI160_INT_OUT_CTRL_ADDR register*/ + rslt = bmi160_get_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* updating the interrupt pin structure to local structure */ + const struct bmi160_int_pin_settg *intr_pin_sett = &(int_config->int_pin_settg); + + /* Configuring channel 1 */ + if (int_config->int_channel == BMI160_INT_CHANNEL_1) + { + /* Output enable */ + temp = data & ~BMI160_INT1_OUTPUT_EN_MASK; + data = temp | ((intr_pin_sett->output_en << 3) & BMI160_INT1_OUTPUT_EN_MASK); + + /* Output mode */ + temp = data & ~BMI160_INT1_OUTPUT_MODE_MASK; + data = temp | ((intr_pin_sett->output_mode << 2) & BMI160_INT1_OUTPUT_MODE_MASK); + + /* Output type */ + temp = data & ~BMI160_INT1_OUTPUT_TYPE_MASK; + data = temp | ((intr_pin_sett->output_type << 1) & BMI160_INT1_OUTPUT_TYPE_MASK); + + /* edge control */ + temp = data & ~BMI160_INT1_EDGE_CTRL_MASK; + data = temp | ((intr_pin_sett->edge_ctrl) & BMI160_INT1_EDGE_CTRL_MASK); + } + else + { + /* Configuring channel 2 */ + /* Output enable */ + temp = data & ~BMI160_INT2_OUTPUT_EN_MASK; + data = temp | ((intr_pin_sett->output_en << 7) & BMI160_INT2_OUTPUT_EN_MASK); + + /* Output mode */ + temp = data & ~BMI160_INT2_OUTPUT_MODE_MASK; + data = temp | ((intr_pin_sett->output_mode << 6) & BMI160_INT2_OUTPUT_MODE_MASK); + + /* Output type */ + temp = data & ~BMI160_INT2_OUTPUT_TYPE_MASK; + data = temp | ((intr_pin_sett->output_type << 5) & BMI160_INT2_OUTPUT_TYPE_MASK); + + /* edge control */ + temp = data & ~BMI160_INT2_EDGE_CTRL_MASK; + data = temp | ((intr_pin_sett->edge_ctrl << 4) & BMI160_INT2_EDGE_CTRL_MASK); + } + + rslt = bmi160_set_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API configure the mode(input enable, latch or non-latch) of interrupt pin. + */ +static int8_t config_int_latch(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t temp = 0; + uint8_t data = 0; + + /* Configuration of latch on pins INT1 and INT2 are done in + * BMI160_INT_LATCH_ADDR register*/ + rslt = bmi160_get_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* updating the interrupt pin structure to local structure */ + const struct bmi160_int_pin_settg *intr_pin_sett = &(int_config->int_pin_settg); + if (int_config->int_channel == BMI160_INT_CHANNEL_1) + { + /* Configuring channel 1 */ + /* Input enable */ + temp = data & ~BMI160_INT1_INPUT_EN_MASK; + data = temp | ((intr_pin_sett->input_en << 4) & BMI160_INT1_INPUT_EN_MASK); + } + else + { + /* Configuring channel 2 */ + /* Input enable */ + temp = data & ~BMI160_INT2_INPUT_EN_MASK; + data = temp | ((intr_pin_sett->input_en << 5) & BMI160_INT2_INPUT_EN_MASK); + } + + /* In case of latch interrupt,update the latch duration */ + + /* Latching holds the interrupt for the amount of latch + * duration time */ + temp = data & ~BMI160_INT_LATCH_MASK; + data = temp | (intr_pin_sett->latch_dur & BMI160_INT_LATCH_MASK); + + /* OUT_CTRL_INT and LATCH_INT address lie consecutively, + * hence writing data to respective registers at one go */ + rslt = bmi160_set_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API performs the self test for accelerometer of BMI160 + */ +static int8_t perform_accel_self_test(struct bmi160_dev *dev) +{ + int8_t rslt; + struct bmi160_sensor_data accel_pos, accel_neg; + + /* Enable Gyro self test bit */ + rslt = enable_accel_self_test(dev); + if (rslt == BMI160_OK) + { + /* Perform accel self test with positive excitation */ + rslt = accel_self_test_positive_excitation(&accel_pos, dev); + if (rslt == BMI160_OK) + { + /* Perform accel self test with negative excitation */ + rslt = accel_self_test_negative_excitation(&accel_neg, dev); + if (rslt == BMI160_OK) + { + /* Validate the self test result */ + rslt = validate_accel_self_test(&accel_pos, &accel_neg); + } + } + } + + return rslt; +} + +/*! + * @brief This API enables to perform the accel self test by setting proper + * configurations to facilitate accel self test + */ +static int8_t enable_accel_self_test(struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t reg_data; + + /* Set the Accel power mode as normal mode */ + dev->accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; + + /* Set the sensor range configuration as 8G */ + dev->accel_cfg.range = BMI160_ACCEL_RANGE_8G; + rslt = bmi160_set_sens_conf(dev); + if (rslt == BMI160_OK) + { + /* Accel configurations are set to facilitate self test + * acc_odr - 1600Hz ; acc_bwp = 2 ; acc_us = 0 */ + reg_data = BMI160_ACCEL_SELF_TEST_CONFIG; + rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, ®_data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API performs accel self test with positive excitation + */ +static int8_t accel_self_test_positive_excitation(struct bmi160_sensor_data *accel_pos, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t reg_data; + + /* Enable accel self test with positive self-test excitation + * and with amplitude of deflection set as high */ + reg_data = BMI160_ACCEL_SELF_TEST_POSITIVE_EN; + rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if (rslt == BMI160_OK) + { + /* Read the data after a delay of 50ms - refer datasheet 2.8.1 accel self test*/ + dev->delay_ms(BMI160_ACCEL_SELF_TEST_DELAY); + rslt = bmi160_get_sensor_data(BMI160_ACCEL_ONLY, accel_pos, NULL, dev); + } + + return rslt; +} + +/*! + * @brief This API performs accel self test with negative excitation + */ +static int8_t accel_self_test_negative_excitation(struct bmi160_sensor_data *accel_neg, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t reg_data; + + /* Enable accel self test with negative self-test excitation + * and with amplitude of deflection set as high */ + reg_data = BMI160_ACCEL_SELF_TEST_NEGATIVE_EN; + rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if (rslt == BMI160_OK) + { + /* Read the data after a delay of 50ms */ + dev->delay_ms(BMI160_ACCEL_SELF_TEST_DELAY); + rslt = bmi160_get_sensor_data(BMI160_ACCEL_ONLY, accel_neg, NULL, dev); + } + + return rslt; +} + +/*! + * @brief This API validates the accel self test results + */ +static int8_t validate_accel_self_test(const struct bmi160_sensor_data *accel_pos, + const struct bmi160_sensor_data *accel_neg) +{ + int8_t rslt; + + /* Validate the results of self test */ + if (((accel_neg->x - accel_pos->x) > BMI160_ACCEL_SELF_TEST_LIMIT) && + ((accel_neg->y - accel_pos->y) > BMI160_ACCEL_SELF_TEST_LIMIT) && + ((accel_neg->z - accel_pos->z) > BMI160_ACCEL_SELF_TEST_LIMIT)) + { + /* Self test pass condition */ + rslt = BMI160_OK; + } + else + { + rslt = BMI160_W_ACCEl_SELF_TEST_FAIL; + } + + return rslt; +} + +/*! + * @brief This API performs the self test for gyroscope of BMI160 + */ +static int8_t perform_gyro_self_test(const struct bmi160_dev *dev) +{ + int8_t rslt; + + /* Enable Gyro self test bit */ + rslt = enable_gyro_self_test(dev); + if (rslt == BMI160_OK) + { + /* Validate the gyro self test a delay of 50ms */ + dev->delay_ms(50); + + /* Validate the gyro self test results */ + rslt = validate_gyro_self_test(dev); + } + + return rslt; +} + +/*! + * @brief This API enables the self test bit to trigger self test for Gyro + */ +static int8_t enable_gyro_self_test(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t reg_data; + + /* Enable the Gyro self test bit to trigger the self test */ + rslt = bmi160_get_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if (rslt == BMI160_OK) + { + reg_data = BMI160_SET_BITS(reg_data, BMI160_GYRO_SELF_TEST, 1); + rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); + if (rslt == BMI160_OK) + { + /* Delay to enable gyro self test */ + dev->delay_ms(15); + } + } + + return rslt; +} + +/*! + * @brief This API validates the self test results of Gyro + */ +static int8_t validate_gyro_self_test(const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t reg_data; + + /* Validate the Gyro self test result */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, ®_data, 1, dev); + if (rslt == BMI160_OK) + { + + reg_data = BMI160_GET_BITS(reg_data, BMI160_GYRO_SELF_TEST_STATUS); + if (reg_data == BMI160_ENABLE) + { + /* Gyro self test success case */ + rslt = BMI160_OK; + } + else + { + rslt = BMI160_W_GYRO_SELF_TEST_FAIL; + } + } + + return rslt; +} + +/*! + * @brief This API sets FIFO full interrupt of the sensor.This interrupt + * occurs when the FIFO is full and the next full data sample would cause + * a FIFO overflow, which may delete the old samples. + */ +static int8_t set_fifo_full_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + /* Null-pointer check */ + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /*enable the fifo full interrupt */ + rslt = enable_fifo_full_int(int_config, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_hardware_interrupt(int_config, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This enable the FIFO full interrupt engine. + */ +static int8_t enable_fifo_full_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + data = BMI160_SET_BITS(data, BMI160_FIFO_FULL_INT, int_config->fifo_full_int_en); + + /* Writing data to INT ENABLE 1 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API sets FIFO watermark interrupt of the sensor.The FIFO + * watermark interrupt is fired, when the FIFO fill level is above a fifo + * watermark. + */ +static int8_t set_fifo_watermark_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt = BMI160_OK; + + if ((dev == NULL) || (dev->delay_ms == NULL)) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Enable fifo-watermark interrupt in Int Enable 1 register */ + rslt = enable_fifo_wtm_int(int_config, dev); + if (rslt == BMI160_OK) + { + /* Configure Interrupt pins */ + rslt = set_intr_pin_config(int_config, dev); + if (rslt == BMI160_OK) + { + rslt = map_hardware_interrupt(int_config, dev); + } + } + } + + return rslt; +} + +/*! + * @brief This enable the FIFO watermark interrupt engine. + */ +static int8_t enable_fifo_wtm_int(const struct bmi160_int_settg *int_config, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data = 0; + + rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + data = BMI160_SET_BITS(data, BMI160_FIFO_WTM_INT, int_config->fifo_wtm_int_en); + + /* Writing data to INT ENABLE 1 Address */ + rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); + } + + return rslt; +} + +/*! + * @brief This API is used to reset the FIFO related configurations + * in the fifo_frame structure. + */ +static void reset_fifo_data_structure(const struct bmi160_dev *dev) +{ + /*Prepare for next FIFO read by resetting FIFO's + * internal data structures*/ + dev->fifo->accel_byte_start_idx = 0; + dev->fifo->gyro_byte_start_idx = 0; + dev->fifo->aux_byte_start_idx = 0; + dev->fifo->sensor_time = 0; + dev->fifo->skipped_frame_count = 0; +} + +/*! + * @brief This API is used to read fifo_byte_counter value (i.e) + * current fill-level in Fifo buffer. + */ +static int8_t get_fifo_byte_counter(uint16_t *bytes_to_read, struct bmi160_dev const *dev) +{ + int8_t rslt = 0; + uint8_t data[2]; + uint8_t addr = BMI160_FIFO_LENGTH_ADDR; + + rslt |= bmi160_get_regs(addr, data, 2, dev); + data[1] = data[1] & BMI160_FIFO_BYTE_COUNTER_MASK; + + /* Available data in FIFO is stored in bytes_to_read*/ + *bytes_to_read = (((uint16_t)data[1] << 8) | ((uint16_t)data[0])); + + return rslt; +} + +/*! + * @brief This API is used to compute the number of bytes of accel FIFO data + * which is to be parsed in header-less mode + */ +static void get_accel_len_to_parse(uint16_t *data_index, + uint16_t *data_read_length, + const uint8_t *acc_frame_count, + const struct bmi160_dev *dev) +{ + /* Data start index */ + *data_index = dev->fifo->accel_byte_start_idx; + if (dev->fifo->fifo_data_enable == BMI160_FIFO_A_ENABLE) + { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_A_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_G_A_ENABLE) + { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_GA_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_A_ENABLE) + { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_MA_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) + { + *data_read_length = (*acc_frame_count) * BMI160_FIFO_MGA_LENGTH; + } + else + { + /* When accel is not enabled ,there will be no accel data. + * so we update the data index as complete */ + *data_index = dev->fifo->length; + } + + if (*data_read_length > dev->fifo->length) + { + /* Handling the case where more data is requested + * than that is available*/ + *data_read_length = dev->fifo->length; + } +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static void unpack_accel_frame(struct bmi160_sensor_data *acc, + uint16_t *idx, + uint8_t *acc_idx, + uint8_t frame_info, + const struct bmi160_dev *dev) +{ + switch (frame_info) + { + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_A_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into the structure instance "acc" */ + unpack_accel_data(&acc[*acc_idx], *idx, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_A_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_GA_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_G_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_GA_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_M_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_MA_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_M_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MA_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_M_G_A: + case BMI160_FIFO_M_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "acc"*/ + unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_MG_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MGA_LENGTH; + (*acc_idx)++; + break; + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_M_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_M_LENGTH; + break; + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_G_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; + break; + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_M_G_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + */ +static void unpack_accel_data(struct bmi160_sensor_data *accel_data, + uint16_t data_start_index, + const struct bmi160_dev *dev) +{ + uint16_t data_lsb; + uint16_t data_msb; + + /* Accel raw x data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + accel_data->x = (int16_t)((data_msb << 8) | data_lsb); + + /* Accel raw y data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + accel_data->y = (int16_t)((data_msb << 8) | data_lsb); + + /* Accel raw z data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + accel_data->z = (int16_t)((data_msb << 8) | data_lsb); +} + +/*! + * @brief This API is used to parse the accelerometer data from the + * FIFO data in header mode. + */ +static void extract_accel_header_mode(struct bmi160_sensor_data *accel_data, + uint8_t *accel_length, + const struct bmi160_dev *dev) +{ + uint8_t frame_header = 0; + uint16_t data_index; + uint8_t accel_index = 0; + + for (data_index = dev->fifo->accel_byte_start_idx; data_index < dev->fifo->length;) + { + /* extracting Frame header */ + frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch (frame_header) + { + /* Accel frame */ + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_HEAD_M_G_A: + unpack_accel_frame(accel_data, &data_index, &accel_index, frame_header, dev); + break; + case BMI160_FIFO_HEAD_M: + move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_G: + move_next_frame(&data_index, BMI160_FIFO_G_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_M_G: + move_next_frame(&data_index, BMI160_FIFO_MG_LENGTH, dev); + break; + + /* Sensor time frame */ + case BMI160_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, dev); + break; + + /* Skip frame */ + case BMI160_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, dev); + break; + + /* Input config frame */ + case BMI160_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, dev); + break; + case BMI160_FIFO_HEAD_OVER_READ: + + /* Update the data index as complete in case of Over read */ + data_index = dev->fifo->length; + break; + default: + break; + } + if (*accel_length == accel_index) + { + /* Number of frames to read completed */ + break; + } + } + + /*Update number of accel data read*/ + *accel_length = accel_index; + + /*Update the accel frame index*/ + dev->fifo->accel_byte_start_idx = data_index; +} + +/*! + * @brief This API computes the number of bytes of gyro FIFO data + * which is to be parsed in header-less mode + */ +static void get_gyro_len_to_parse(uint16_t *data_index, + uint16_t *data_read_length, + const uint8_t *gyro_frame_count, + const struct bmi160_dev *dev) +{ + /* Data start index */ + *data_index = dev->fifo->gyro_byte_start_idx; + if (dev->fifo->fifo_data_enable == BMI160_FIFO_G_ENABLE) + { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_G_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_G_A_ENABLE) + { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_GA_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_ENABLE) + { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_MG_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) + { + *data_read_length = (*gyro_frame_count) * BMI160_FIFO_MGA_LENGTH; + } + else + { + /* When gyro is not enabled ,there will be no gyro data. + * so we update the data index as complete */ + *data_index = dev->fifo->length; + } + + if (*data_read_length > dev->fifo->length) + { + /* Handling the case where more data is requested + * than that is available*/ + *data_read_length = dev->fifo->length; + } +} + +/*! + * @brief This API is used to parse the gyroscope's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed. + */ +static void unpack_gyro_frame(struct bmi160_sensor_data *gyro, + uint16_t *idx, + uint8_t *gyro_idx, + uint8_t frame_info, + const struct bmi160_dev *dev) +{ + switch (frame_info) + { + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_G_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_G_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "gyro"*/ + unpack_gyro_data(&gyro[*gyro_idx], *idx, dev); + + /*Move the data index*/ + (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_GA_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance "gyro" */ + unpack_gyro_data(&gyro[*gyro_idx], *idx, dev); + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_GA_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_M_G_A: + case BMI160_FIFO_M_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "gyro"*/ + unpack_gyro_data(&gyro[*gyro_idx], *idx + BMI160_FIFO_M_LENGTH, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MGA_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_M_A_ENABLE: + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_MA_LENGTH; + break; + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_M_ENABLE: + (*idx) = (*idx) + BMI160_FIFO_M_LENGTH; + break; + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_M_G_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_MG_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *idx = dev->fifo->length; + break; + } + + /*Unpack the data array into structure instance "gyro"*/ + unpack_gyro_data(&gyro[*gyro_idx], *idx + BMI160_FIFO_M_LENGTH, dev); + + /*Move the data index*/ + (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; + (*gyro_idx)++; + break; + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_A_ENABLE: + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_A_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data and store it in the instance of the structure bmi160_sensor_data. + */ +static void unpack_gyro_data(struct bmi160_sensor_data *gyro_data, + uint16_t data_start_index, + const struct bmi160_dev *dev) +{ + uint16_t data_lsb; + uint16_t data_msb; + + /* Gyro raw x data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + gyro_data->x = (int16_t)((data_msb << 8) | data_lsb); + + /* Gyro raw y data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + gyro_data->y = (int16_t)((data_msb << 8) | data_lsb); + + /* Gyro raw z data */ + data_lsb = dev->fifo->data[data_start_index++]; + data_msb = dev->fifo->data[data_start_index++]; + gyro_data->z = (int16_t)((data_msb << 8) | data_lsb); +} + +/*! + * @brief This API is used to parse the gyro data from the + * FIFO data in header mode. + */ +static void extract_gyro_header_mode(struct bmi160_sensor_data *gyro_data, + uint8_t *gyro_length, + const struct bmi160_dev *dev) +{ + uint8_t frame_header = 0; + uint16_t data_index; + uint8_t gyro_index = 0; + + for (data_index = dev->fifo->gyro_byte_start_idx; data_index < dev->fifo->length;) + { + /* extracting Frame header */ + frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch (frame_header) + { + /* GYRO frame */ + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_HEAD_M_G_A: + unpack_gyro_frame(gyro_data, &data_index, &gyro_index, frame_header, dev); + break; + case BMI160_FIFO_HEAD_A: + move_next_frame(&data_index, BMI160_FIFO_A_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_M: + move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_M_A: + move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); + break; + + /* Sensor time frame */ + case BMI160_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, dev); + break; + + /* Skip frame */ + case BMI160_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, dev); + break; + + /* Input config frame */ + case BMI160_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, dev); + break; + case BMI160_FIFO_HEAD_OVER_READ: + + /* Update the data index as complete in case of over read */ + data_index = dev->fifo->length; + break; + default: + break; + } + if (*gyro_length == gyro_index) + { + /*Number of frames to read completed*/ + break; + } + } + + /*Update number of gyro data read*/ + *gyro_length = gyro_index; + + /*Update the gyro frame index*/ + dev->fifo->gyro_byte_start_idx = data_index; +} + +/*! + * @brief This API computes the number of bytes of aux FIFO data + * which is to be parsed in header-less mode + */ +static void get_aux_len_to_parse(uint16_t *data_index, + uint16_t *data_read_length, + const uint8_t *aux_frame_count, + const struct bmi160_dev *dev) +{ + /* Data start index */ + *data_index = dev->fifo->gyro_byte_start_idx; + if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_ENABLE) + { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_M_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_A_ENABLE) + { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_MA_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_ENABLE) + { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_MG_LENGTH; + } + else if (dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) + { + *data_read_length = (*aux_frame_count) * BMI160_FIFO_MGA_LENGTH; + } + else + { + /* When aux is not enabled ,there will be no aux data. + * so we update the data index as complete */ + *data_index = dev->fifo->length; + } + + if (*data_read_length > dev->fifo->length) + { + /* Handling the case where more data is requested + * than that is available */ + *data_read_length = dev->fifo->length; + } +} + +/*! + * @brief This API is used to parse the aux's data from the + * FIFO data in both header mode and header-less mode. + * It updates the idx value which is used to store the index of + * the current data byte which is parsed + */ +static void unpack_aux_frame(struct bmi160_aux_data *aux_data, + uint16_t *idx, + uint8_t *aux_index, + uint8_t frame_info, + const struct bmi160_dev *dev) +{ + switch (frame_info) + { + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_M_ENABLE: + + /* Partial read, then skip the data */ + if ((*idx + BMI160_FIFO_M_LENGTH) > dev->fifo->length) + { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_M_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_M_A_ENABLE: + + /* Partial read, then skip the data */ + if ((*idx + BMI160_FIFO_MA_LENGTH) > dev->fifo->length) + { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_MA_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_M_G_ENABLE: + + /* Partial read, then skip the data */ + if ((*idx + BMI160_FIFO_MG_LENGTH) > dev->fifo->length) + { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /* Move the data index */ + (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_M_G_A: + case BMI160_FIFO_M_G_A_ENABLE: + + /*Partial read, then skip the data*/ + if ((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) + { + /* Update the data index as complete */ + *idx = dev->fifo->length; + break; + } + + /* Unpack the data array into structure instance */ + unpack_aux_data(&aux_data[*aux_index], *idx, dev); + + /*Move the data index*/ + *idx = *idx + BMI160_FIFO_MGA_LENGTH; + (*aux_index)++; + break; + case BMI160_FIFO_HEAD_G: + case BMI160_FIFO_G_ENABLE: + + /* Move the data index */ + (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; + break; + case BMI160_FIFO_HEAD_G_A: + case BMI160_FIFO_G_A_ENABLE: + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_GA_LENGTH; + break; + case BMI160_FIFO_HEAD_A: + case BMI160_FIFO_A_ENABLE: + + /* Move the data index */ + *idx = *idx + BMI160_FIFO_A_LENGTH; + break; + default: + break; + } +} + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data and store it in the instance of the structure bmi160_aux_data. + */ +static void unpack_aux_data(struct bmi160_aux_data *aux_data, uint16_t data_start_index, const struct bmi160_dev *dev) +{ + /* Aux data bytes */ + aux_data->data[0] = dev->fifo->data[data_start_index++]; + aux_data->data[1] = dev->fifo->data[data_start_index++]; + aux_data->data[2] = dev->fifo->data[data_start_index++]; + aux_data->data[3] = dev->fifo->data[data_start_index++]; + aux_data->data[4] = dev->fifo->data[data_start_index++]; + aux_data->data[5] = dev->fifo->data[data_start_index++]; + aux_data->data[6] = dev->fifo->data[data_start_index++]; + aux_data->data[7] = dev->fifo->data[data_start_index++]; +} + +/*! + * @brief This API is used to parse the aux data from the + * FIFO data in header mode. + */ +static void extract_aux_header_mode(struct bmi160_aux_data *aux_data, uint8_t *aux_length, const struct bmi160_dev *dev) +{ + uint8_t frame_header = 0; + uint16_t data_index; + uint8_t aux_index = 0; + + for (data_index = dev->fifo->aux_byte_start_idx; data_index < dev->fifo->length;) + { + /* extracting Frame header */ + frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); + + /*Index is moved to next byte where the data is starting*/ + data_index++; + switch (frame_header) + { + /* Aux frame */ + case BMI160_FIFO_HEAD_M: + case BMI160_FIFO_HEAD_M_A: + case BMI160_FIFO_HEAD_M_G: + case BMI160_FIFO_HEAD_M_G_A: + unpack_aux_frame(aux_data, &data_index, &aux_index, frame_header, dev); + break; + case BMI160_FIFO_HEAD_G: + move_next_frame(&data_index, BMI160_FIFO_G_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_G_A: + move_next_frame(&data_index, BMI160_FIFO_GA_LENGTH, dev); + break; + case BMI160_FIFO_HEAD_A: + move_next_frame(&data_index, BMI160_FIFO_A_LENGTH, dev); + break; + + /* Sensor time frame */ + case BMI160_FIFO_HEAD_SENSOR_TIME: + unpack_sensortime_frame(&data_index, dev); + break; + + /* Skip frame */ + case BMI160_FIFO_HEAD_SKIP_FRAME: + unpack_skipped_frame(&data_index, dev); + break; + + /* Input config frame */ + case BMI160_FIFO_HEAD_INPUT_CONFIG: + move_next_frame(&data_index, 1, dev); + break; + case BMI160_FIFO_HEAD_OVER_READ: + + /* Update the data index as complete in case + * of over read */ + data_index = dev->fifo->length; + break; + default: + + /* Update the data index as complete in case of + * getting other headers like 0x00 */ + data_index = dev->fifo->length; + break; + } + if (*aux_length == aux_index) + { + /*Number of frames to read completed*/ + break; + } + } + + /* Update number of aux data read */ + *aux_length = aux_index; + + /* Update the aux frame index */ + dev->fifo->aux_byte_start_idx = data_index; +} + +/*! + * @brief This API checks the presence of non-valid frames in the read fifo data. + */ +static void check_frame_validity(uint16_t *data_index, const struct bmi160_dev *dev) +{ + if ((*data_index + 2) < dev->fifo->length) + { + /* Check if FIFO is empty */ + if ((dev->fifo->data[*data_index] == FIFO_CONFIG_MSB_CHECK) && + (dev->fifo->data[*data_index + 1] == FIFO_CONFIG_LSB_CHECK)) + { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } + } +} + +/*! + * @brief This API is used to move the data index ahead of the + * current_frame_length parameter when unnecessary FIFO data appears while + * extracting the user specified data. + */ +static void move_next_frame(uint16_t *data_index, uint8_t current_frame_length, const struct bmi160_dev *dev) +{ + /*Partial read, then move the data index to last data*/ + if ((*data_index + current_frame_length) > dev->fifo->length) + { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } + else + { + /*Move the data index to next frame*/ + *data_index = *data_index + current_frame_length; + } +} + +/*! + * @brief This API is used to parse and store the sensor time from the + * FIFO data in the structure instance dev. + */ +static void unpack_sensortime_frame(uint16_t *data_index, const struct bmi160_dev *dev) +{ + uint32_t sensor_time_byte3 = 0; + uint16_t sensor_time_byte2 = 0; + uint8_t sensor_time_byte1 = 0; + + /*Partial read, then move the data index to last data*/ + if ((*data_index + BMI160_SENSOR_TIME_LENGTH) > dev->fifo->length) + { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } + else + { + sensor_time_byte3 = dev->fifo->data[(*data_index) + BMI160_SENSOR_TIME_MSB_BYTE] << 16; + sensor_time_byte2 = dev->fifo->data[(*data_index) + BMI160_SENSOR_TIME_XLSB_BYTE] << 8; + sensor_time_byte1 = dev->fifo->data[(*data_index)]; + + /* Sensor time */ + dev->fifo->sensor_time = (uint32_t)(sensor_time_byte3 | sensor_time_byte2 | sensor_time_byte1); + *data_index = (*data_index) + BMI160_SENSOR_TIME_LENGTH; + } +} + +/*! + * @brief This API is used to parse and store the skipped_frame_count from + * the FIFO data in the structure instance dev. + */ +static void unpack_skipped_frame(uint16_t *data_index, const struct bmi160_dev *dev) +{ + /*Partial read, then move the data index to last data*/ + if (*data_index >= dev->fifo->length) + { + /*Update the data index as complete*/ + *data_index = dev->fifo->length; + } + else + { + dev->fifo->skipped_frame_count = dev->fifo->data[*data_index]; + + /*Move the data index*/ + *data_index = (*data_index) + 1; + } +} + +/*! + * @brief This API is used to get the FOC status from the sensor + */ +static int8_t get_foc_status(uint8_t *foc_status, struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + + /* Read the FOC status from sensor */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* Get the foc_status bit */ + *foc_status = BMI160_GET_BITS(data, BMI160_FOC_STATUS); + } + + return rslt; +} + +/*! + * @brief This API is used to configure the offset enable bits in the sensor + */ +static int8_t configure_offset_enable(const struct bmi160_foc_conf *foc_conf, struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + if (rslt != BMI160_OK) + { + rslt = BMI160_E_NULL_PTR; + } + else + { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) + { + /* Set the offset enable/disable for gyro */ + data = BMI160_SET_BITS(data, BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); + + /* Set the offset enable/disable for accel */ + data = BMI160_SET_BITS(data, BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); + + /* Set the offset config in the sensor */ + rslt = bmi160_set_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +static int8_t trigger_foc(struct bmi160_offsets *offset, struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t foc_status = BMI160_ENABLE; + uint8_t cmd = BMI160_START_FOC_CMD; + uint8_t timeout = 0; + uint8_t data_array[20]; + + /* Start the FOC process */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if (rslt == BMI160_OK) + { + /* Check the FOC status*/ + rslt = get_foc_status(&foc_status, dev); + + if ((rslt != BMI160_OK) || (foc_status != BMI160_ENABLE)) + { + while ((foc_status != BMI160_ENABLE) && (timeout < 11)) + { + /* Maximum time of 250ms is given in 10 + * steps of 25ms each - 250ms refer datasheet 2.9.1 */ + dev->delay_ms(25); + + /* Check the FOC status*/ + rslt = get_foc_status(&foc_status, dev); + timeout++; + } + + if ((rslt == BMI160_OK) && (foc_status == BMI160_ENABLE)) + { + /* Get offset values from sensor */ + rslt = bmi160_get_offsets(offset, dev); + } + else + { + /* FOC failure case */ + rslt = BMI160_E_FOC_FAILURE; + } + } + + if (rslt == BMI160_OK) + { + /* Read registers 0x04-0x17 */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 20, dev); + } + } + + return rslt; +} diff --git a/non_catalog_apps/airmouse/tracking/imu/bmi160.h b/non_catalog_apps/airmouse/lib/bmi160-api/bmi160.h similarity index 89% rename from non_catalog_apps/airmouse/tracking/imu/bmi160.h rename to non_catalog_apps/airmouse/lib/bmi160-api/bmi160.h index d4d98094cf3..d30978f22b9 100644 --- a/non_catalog_apps/airmouse/tracking/imu/bmi160.h +++ b/non_catalog_apps/airmouse/lib/bmi160-api/bmi160.h @@ -1,992 +1,969 @@ -/** -* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. -* -* BSD-3-Clause -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -* -* @file bmi160.h -* @date 2021-10-05 -* @version v3.9.2 -* -*/ - -/*! - * @defgroup bmi160 BMI160 - */ - -#ifndef BMI160_H_ -#define BMI160_H_ - -/*************************** C++ guard macro *****************************/ -#ifdef __cplusplus -extern "C" { -#endif - -#include "bmi160_defs.h" -#ifdef __KERNEL__ -#include -#else -#include -#include -#include -#endif - -/*********************** User function prototypes ************************/ - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiInit Initialization - * @brief Initialize the sensor and device structure - */ - -/*! - * \ingroup bmi160ApiInit - * \page bmi160_api_bmi160_init bmi160_init - * \code - * int8_t bmi160_init(struct bmi160_dev *dev); - * \endcode - * @details This API is the entry point for sensor.It performs - * the selection of I2C/SPI read mechanism according to the - * selected interface and reads the chip-id of bmi160 sensor. - * - * @param[in,out] dev : Structure instance of bmi160_dev - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_init(struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiRegs Registers - * @brief Read data from the given register address of sensor - */ - -/*! - * \ingroup bmi160ApiRegs - * \page bmi160_api_bmi160_get_regs bmi160_get_regs - * \code - * int8_t bmi160_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); - * \endcode - * @details This API reads the data from the given register address of sensor. - * - * @param[in] reg_addr : Register address from where the data to be read - * @param[out] data : Pointer to data buffer to store the read data. - * @param[in] len : No of bytes of data to be read. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note For most of the registers auto address increment applies, with the - * exception of a few special registers, which trap the address. For e.g., - * Register address - 0x24(BMI160_FIFO_DATA_ADDR) - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t - bmi160_get_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiRegs - * \page bmi160_api_bmi160_set_regs bmi160_set_regs - * \code - * int8_t bmi160_set_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); - * \endcode - * @details This API writes the given data to the register address - * of sensor. - * - * @param[in] reg_addr : Register address from where the data to be written. - * @param[in] data : Pointer to data buffer which is to be written - * in the sensor. - * @param[in] len : No of bytes of data to write.. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t - bmi160_set_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiSoftreset Soft reset - * @brief Perform soft reset of the sensor - */ - -/*! - * \ingroup bmi160ApiSoftreset - * \page bmi160_api_bmi160_soft_reset bmi160_soft_reset - * \code - * int8_t bmi160_soft_reset(struct bmi160_dev *dev); - * \endcode - * @details This API resets and restarts the device. - * All register values are overwritten with default parameters. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_soft_reset(struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiConfig Configuration - * @brief Configuration of the sensor - */ - -/*! - * \ingroup bmi160ApiConfig - * \page bmi160_api_bmi160_set_sens_conf bmi160_set_sens_conf - * \code - * int8_t bmi160_set_sens_conf(struct bmi160_dev *dev); - * \endcode - * @details This API configures the power mode, range and bandwidth - * of sensor. - * - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_set_sens_conf(struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiConfig - * \page bmi160_api_bmi160_get_sens_conf bmi160_get_sens_conf - * \code - * int8_t bmi160_get_sens_conf(struct bmi160_dev *dev); - * \endcode - * @details This API gets accel and gyro configurations. - * - * @param[out] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_get_sens_conf(struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiPowermode Power mode - * @brief Set / Get power mode of the sensor - */ - -/*! - * \ingroup bmi160ApiPowermode - * \page bmi160_api_bmi160_set_power_mode bmi160_set_power_mode - * \code - * int8_t bmi160_set_power_mode(struct bmi160_dev *dev); - * \endcode - * @details This API sets the power mode of the sensor. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_set_power_mode(struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiPowermode - * \page bmi160_api_bmi160_get_power_mode bmi160_get_power_mode - * \code - * int8_t bmi160_get_power_mode(struct bmi160_dev *dev); - * \endcode - * @details This API gets the power mode of the sensor. - * - * @param[in] dev : Structure instance of bmi160_dev - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_get_power_mode(struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiData Sensor Data - * @brief Read sensor data - */ - -/*! - * \ingroup bmi160ApiData - * \page bmi160_api_bmi160_get_sensor_data bmi160_get_sensor_data - * \code - * int8_t bmi160_get_sensor_data(uint8_t select_sensor, - * struct bmi160_sensor_data *accel, - * struct bmi160_sensor_data *gyro, - * const struct bmi160_dev *dev); - * - * \endcode - * @details This API reads sensor data, stores it in - * the bmi160_sensor_data structure pointer passed by the user. - * The user can ask for accel data ,gyro data or both sensor - * data using bmi160_select_sensor enum - * - * @param[in] select_sensor : enum to choose accel,gyro or both sensor data - * @param[out] accel : Structure pointer to store accel data - * @param[out] gyro : Structure pointer to store gyro data - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_get_sensor_data( - uint8_t select_sensor, - struct bmi160_sensor_data* accel, - struct bmi160_sensor_data* gyro, - const struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiInt Interrupt configuration - * @brief Set interrupt configuration of the sensor - */ - -/*! - * \ingroup bmi160ApiInt - * \page bmi160_api_bmi160_set_int_config bmi160_set_int_config - * \code - * int8_t bmi160_set_int_config(struct bmi160_int_settg *int_config, struct bmi160_dev *dev); - * \endcode - * @details This API configures the necessary interrupt based on - * the user settings in the bmi160_int_settg structure instance. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_set_int_config(struct bmi160_int_settg* int_config, struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiStepC Step counter - * @brief Step counter operations - */ - -/*! - * \ingroup bmi160ApiStepC - * \page bmi160_api_bmi160_set_step_counter bmi160_set_step_counter - * \code - * int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev *dev); - * \endcode - * @details This API enables the step counter feature. - * - * @param[in] step_cnt_enable : value to enable or disable - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiStepC - * \page bmi160_api_bmi160_read_step_counter bmi160_read_step_counter - * \code - * int8_t bmi160_read_step_counter(uint16_t *step_val, const struct bmi160_dev *dev); - * \endcode - * @details This API reads the step counter value. - * - * @param[in] step_val : Pointer to store the step counter value. - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_read_step_counter(uint16_t* step_val, const struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiAux Auxiliary sensor - * @brief Auxiliary sensor operations - */ - -/*! - * \ingroup bmi160ApiAux - * \page bmi160_api_bmi160_aux_read bmi160_aux_read - * \code - * int8_t bmi160_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); - * \endcode - * @details This API reads the mention no of byte of data from the given - * register address of auxiliary sensor. - * - * @param[in] reg_addr : Address of register to read. - * @param[in] aux_data : Pointer to store the read data. - * @param[in] len : No of bytes to read. - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_aux_read( - uint8_t reg_addr, - uint8_t* aux_data, - uint16_t len, - const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiAux - * \page bmi160_api_bmi160_aux_write bmi160_aux_write - * \code - * int8_t bmi160_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); - * \endcode - * @details This API writes the mention no of byte of data to the given - * register address of auxiliary sensor. - * - * @param[in] reg_addr : Address of register to write. - * @param[in] aux_data : Pointer to write data. - * @param[in] len : No of bytes to write. - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_aux_write( - uint8_t reg_addr, - uint8_t* aux_data, - uint16_t len, - const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiAux - * \page bmi160_api_bmi160_aux_init bmi160_aux_init - * \code - * int8_t bmi160_aux_init(const struct bmi160_dev *dev); - * \endcode - * @details This API initialize the auxiliary sensor - * in order to access it. - * - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_aux_init(const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiAux - * \page bmi160_api_bmi160_set_aux_auto_mode bmi160_set_aux_auto_mode - * \code - * int8_t bmi160_set_aux_auto_mode(uint8_t *data_addr, struct bmi160_dev *dev); - * \endcode - * @details This API is used to setup the auxiliary sensor of bmi160 in auto mode - * Thus enabling the auto update of 8 bytes of data from auxiliary sensor - * to BMI160 register address 0x04 to 0x0B - * - * @param[in] data_addr : Starting address of aux. sensor's data register - * (BMI160 registers 0x04 to 0x0B will be updated - * with 8 bytes of data from auxiliary sensor - * starting from this register address.) - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note : Set the value of auxiliary polling rate by setting - * dev->aux_cfg.aux_odr to the required value from the table - * before calling this API - * - *@verbatim - * dev->aux_cfg.aux_odr | Auxiliary ODR (Hz) - * -----------------------|----------------------- - * BMI160_AUX_ODR_0_78HZ | 25/32 - * BMI160_AUX_ODR_1_56HZ | 25/16 - * BMI160_AUX_ODR_3_12HZ | 25/8 - * BMI160_AUX_ODR_6_25HZ | 25/4 - * BMI160_AUX_ODR_12_5HZ | 25/2 - * BMI160_AUX_ODR_25HZ | 25 - * BMI160_AUX_ODR_50HZ | 50 - * BMI160_AUX_ODR_100HZ | 100 - * BMI160_AUX_ODR_200HZ | 200 - * BMI160_AUX_ODR_400HZ | 400 - * BMI160_AUX_ODR_800HZ | 800 - *@endverbatim - * - * @note : Other values of dev->aux_cfg.aux_odr are reserved and not for use - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_set_aux_auto_mode(uint8_t* data_addr, struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiAux - * \page bmi160_api_bmi160_config_aux_mode bmi160_config_aux_mode - * \code - * int8_t bmi160_config_aux_mode(const struct bmi160_dev *dev); - * \endcode - * @details This API configures the 0x4C register and settings like - * Auxiliary sensor manual enable/ disable and aux burst read length. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_config_aux_mode(const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiAux - * \page bmi160_api_bmi160_read_aux_data_auto_mode bmi160_read_aux_data_auto_mode - * \code - * int8_t bmi160_read_aux_data_auto_mode(uint8_t *aux_data, const struct bmi160_dev *dev); - * \endcode - * @details This API is used to read the raw uncompensated auxiliary sensor - * data of 8 bytes from BMI160 register address 0x04 to 0x0B - * - * @param[in] aux_data : Pointer to user array of length 8 bytes - * Ensure that the aux_data array is of - * length 8 bytes - * @param[in] dev : Structure instance of bmi160_dev - * - * @retval zero -> Success / -ve value -> Error - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_read_aux_data_auto_mode(uint8_t* aux_data, const struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiSelfTest Self test - * @brief Perform self test of the sensor - */ - -/*! - * \ingroup bmi160ApiSelfTest - * \page bmi160_api_bmi160_perform_self_test bmi160_perform_self_test - * \code - * int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev *dev); - * \endcode - * @details This is used to perform self test of accel/gyro of the BMI160 sensor - * - * @param[in] select_sensor : enum to choose accel or gyro for self test - * @param[in] dev : Structure instance of bmi160_dev - * - * @note self test can be performed either for accel/gyro at any instant. - * - *@verbatim - * value of select_sensor | Inference - *----------------------------------|-------------------------------- - * BMI160_ACCEL_ONLY | Accel self test enabled - * BMI160_GYRO_ONLY | Gyro self test enabled - * BMI160_BOTH_ACCEL_AND_GYRO | NOT TO BE USED - *@endverbatim - * - * @note The return value of this API gives us the result of self test. - * - * @note Performing self test does soft reset of the sensor, User can - * set the desired settings after performing the self test. - * - * @return Result of API execution status - * @retval BMI160_OK Self test success - * @retval BMI160_W_GYRO_SELF_TEST_FAIL Gyro self test fail - * @retval BMI160_W_ACCEl_SELF_TEST_FAIL Accel self test fail - */ -int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiFIFO FIFO - * @brief FIFO operations of the sensor - */ - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_get_fifo_data bmi160_get_fifo_data - * \code - * int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev); - * \endcode - * @details This API reads data from the fifo buffer. - * - * @note User has to allocate the FIFO buffer along with - * corresponding fifo length from his side before calling this API - * as mentioned in the readme.md - * - * @note User must specify the number of bytes to read from the FIFO in - * dev->fifo->length , It will be updated by the number of bytes actually - * read from FIFO after calling this API - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval Zero Success - * @retval Negative Error - */ -int8_t bmi160_get_fifo_data(struct bmi160_dev const* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_set_fifo_flush bmi160_set_fifo_flush - * \code - * int8_t bmi160_set_fifo_flush(const struct bmi160_dev *dev); - * \endcode - * @details This API writes fifo_flush command to command register.This - * action clears all data in the Fifo without changing fifo configuration - * settings. - * - * @param[in] dev : Structure instance of bmi160_dev - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_set_fifo_flush(const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_set_fifo_config bmi160_set_fifo_config - * \code - * int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const *dev); - * \endcode - * @details This API sets the FIFO configuration in the sensor. - * - * @param[in] config : variable used to specify the FIFO - * configurations which are to be enabled or disabled in the sensor. - * - * @note : User can set either set one or more or all FIFO configurations - * by ORing the below mentioned macros. - * - *@verbatim - * config | Value - * ------------------------|--------------------------- - * BMI160_FIFO_TIME | 0x02 - * BMI160_FIFO_TAG_INT2 | 0x04 - * BMI160_FIFO_TAG_INT1 | 0x08 - * BMI160_FIFO_HEADER | 0x10 - * BMI160_FIFO_AUX | 0x20 - * BMI160_FIFO_ACCEL | 0x40 - * BMI160_FIFO_GYRO | 0x80 - *@endverbatim - * - * @param[in] enable : Parameter used to enable or disable the above - * FIFO configuration - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return status of bus communication result - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_set_fifo_down bmi160_set_fifo_down - * \code - * int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev *dev); - * \endcode - * @details This API is used to configure the down sampling ratios of - * the accel and gyro data for FIFO.Also, it configures filtered or - * pre-filtered data for the fifo for accel and gyro. - * - * @param[in] fifo_down : variable used to specify the FIFO down - * configurations which are to be enabled or disabled in the sensor. - * - * @note The user must select one among the following macros to - * select down-sampling ratio for accel - * - *@verbatim - * config | Value - * -------------------------------------|--------------------------- - * BMI160_ACCEL_FIFO_DOWN_ZERO | 0x00 - * BMI160_ACCEL_FIFO_DOWN_ONE | 0x10 - * BMI160_ACCEL_FIFO_DOWN_TWO | 0x20 - * BMI160_ACCEL_FIFO_DOWN_THREE | 0x30 - * BMI160_ACCEL_FIFO_DOWN_FOUR | 0x40 - * BMI160_ACCEL_FIFO_DOWN_FIVE | 0x50 - * BMI160_ACCEL_FIFO_DOWN_SIX | 0x60 - * BMI160_ACCEL_FIFO_DOWN_SEVEN | 0x70 - *@endverbatim - * - * @note The user must select one among the following macros to - * select down-sampling ratio for gyro - * - *@verbatim - * config | Value - * -------------------------------------|--------------------------- - * BMI160_GYRO_FIFO_DOWN_ZERO | 0x00 - * BMI160_GYRO_FIFO_DOWN_ONE | 0x01 - * BMI160_GYRO_FIFO_DOWN_TWO | 0x02 - * BMI160_GYRO_FIFO_DOWN_THREE | 0x03 - * BMI160_GYRO_FIFO_DOWN_FOUR | 0x04 - * BMI160_GYRO_FIFO_DOWN_FIVE | 0x05 - * BMI160_GYRO_FIFO_DOWN_SIX | 0x06 - * BMI160_GYRO_FIFO_DOWN_SEVEN | 0x07 - *@endverbatim - * - * @note The user can enable filtered accel data by the following macro - * - *@verbatim - * config | Value - * -------------------------------------|--------------------------- - * BMI160_ACCEL_FIFO_FILT_EN | 0x80 - *@endverbatim - * - * @note The user can enable filtered gyro data by the following macro - * - *@verbatim - * config | Value - * -------------------------------------|--------------------------- - * BMI160_GYRO_FIFO_FILT_EN | 0x08 - *@endverbatim - * - * @note : By ORing the above mentioned macros, the user can select - * the required FIFO down config settings - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return status of bus communication result - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_set_fifo_wm bmi160_set_fifo_wm - * \code - * int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev *dev); - * \endcode - * @details This API sets the FIFO watermark level in the sensor. - * - * @note The FIFO watermark is issued when the FIFO fill level is - * equal or above the watermark level and units of watermark is 4 bytes. - * - * @param[in] fifo_wm : Variable used to set the FIFO water mark level - * @param[in] dev : Structure instance of bmi160_dev - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_extract_accel bmi160_extract_accel - * \code - * int8_t bmi160_extract_accel(struct bmi160_sensor_data *accel_data, uint8_t *accel_length, struct bmi160_dev const - **dev); - * \endcode - * @details This API parses and extracts the accelerometer frames from - * FIFO data read by the "bmi160_get_fifo_data" API and stores it in - * the "accel_data" structure instance. - * - * @note The bmi160_extract_accel API should be called only after - * reading the FIFO data by calling the bmi160_get_fifo_data() API. - * - * @param[out] accel_data : Structure instance of bmi160_sensor_data - * where the accelerometer data in FIFO is stored. - * @param[in,out] accel_length : Number of valid accelerometer frames - * (x,y,z axes data) read out from fifo. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note accel_length is updated with the number of valid accelerometer - * frames extracted from fifo (1 accel frame = 6 bytes) at the end of - * execution of this API. - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_extract_accel( - struct bmi160_sensor_data* accel_data, - uint8_t* accel_length, - struct bmi160_dev const* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_extract_gyro bmi160_extract_gyro - * \code - * int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_length, struct bmi160_dev const *dev); - * \endcode - * @details This API parses and extracts the gyro frames from - * FIFO data read by the "bmi160_get_fifo_data" API and stores it in - * the "gyro_data" structure instance. - * - * @note The bmi160_extract_gyro API should be called only after - * reading the FIFO data by calling the bmi160_get_fifo_data() API. - * - * @param[out] gyro_data : Structure instance of bmi160_sensor_data - * where the gyro data in FIFO is stored. - * @param[in,out] gyro_length : Number of valid gyro frames - * (x,y,z axes data) read out from fifo. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note gyro_length is updated with the number of valid gyro - * frames extracted from fifo (1 gyro frame = 6 bytes) at the end of - * execution of this API. - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_extract_gyro( - struct bmi160_sensor_data* gyro_data, - uint8_t* gyro_length, - struct bmi160_dev const* dev); - -/*! - * \ingroup bmi160ApiFIFO - * \page bmi160_api_bmi160_extract_aux bmi160_extract_aux - * \code - * int8_t bmi160_extract_aux(struct bmi160_aux_data *aux_data, uint8_t *aux_len, struct bmi160_dev const *dev); - * \endcode - * @details This API parses and extracts the aux frames from - * FIFO data read by the "bmi160_get_fifo_data" API and stores it in - * the bmi160_aux_data structure instance. - * - * @note The bmi160_extract_aux API should be called only after - * reading the FIFO data by calling the bmi160_get_fifo_data() API. - * - * @param[out] aux_data : Structure instance of bmi160_aux_data - * where the aux data in FIFO is stored. - * @param[in,out] aux_len : Number of valid aux frames (8bytes) - * read out from FIFO. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note aux_len is updated with the number of valid aux - * frames extracted from fifo (1 aux frame = 8 bytes) at the end of - * execution of this API. - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - * - */ -int8_t bmi160_extract_aux( - struct bmi160_aux_data* aux_data, - uint8_t* aux_len, - struct bmi160_dev const* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiFOC FOC - * @brief Start FOC of accel and gyro sensors - */ - -/*! - * \ingroup bmi160ApiFOC - * \page bmi160_api_bmi160_start_foc bmi160_start_foc - * \code - * int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, - * \endcode - * @details This API starts the FOC of accel and gyro - * - * @note FOC should not be used in low-power mode of sensor - * - * @note Accel FOC targets values of +1g , 0g , -1g - * Gyro FOC always targets value of 0 dps - * - * @param[in] foc_conf : Structure instance of bmi160_foc_conf which - * has the FOC configuration - * @param[in,out] offset : Structure instance to store Offset - * values read from sensor - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note Pre-requisites for triggering FOC in accel , Set the following, - * Enable the acc_off_en - * Ex : foc_conf.acc_off_en = BMI160_ENABLE; - * - * Set the desired target values of FOC to each axes (x,y,z) by using the - * following macros - * - BMI160_FOC_ACCEL_DISABLED - * - BMI160_FOC_ACCEL_POSITIVE_G - * - BMI160_FOC_ACCEL_NEGATIVE_G - * - BMI160_FOC_ACCEL_0G - * - * Ex : foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G; - * foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G; - * foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G; - * - * @note Pre-requisites for triggering FOC in gyro , - * Set the following parameters, - * - * Ex : foc_conf.foc_gyr_en = BMI160_ENABLE; - * foc_conf.gyro_off_en = BMI160_ENABLE; - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - */ -int8_t bmi160_start_foc( - const struct bmi160_foc_conf* foc_conf, - struct bmi160_offsets* offset, - struct bmi160_dev const* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiOffsets Offsets - * @brief Set / Get offset values of accel and gyro sensors - */ - -/*! - * \ingroup bmi160ApiOffsets - * \page bmi160_api_bmi160_get_offsets bmi160_get_offsets - * \code - * int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev); - * \endcode - * @details This API reads and stores the offset values of accel and gyro - * - * @param[in,out] offset : Structure instance of bmi160_offsets in which - * the offset values are read and stored - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - */ -int8_t bmi160_get_offsets(struct bmi160_offsets* offset, const struct bmi160_dev* dev); - -/*! - * \ingroup bmi160ApiOffsets - * \page bmi160_api_bmi160_set_offsets bmi160_set_offsets - * \code - * int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, - * const struct bmi160_offsets *offset, - * struct bmi160_dev const *dev); - * \endcode - * @details This API writes the offset values of accel and gyro to - * the sensor but these values will be reset on POR or soft reset. - * - * @param[in] foc_conf : Structure instance of bmi160_foc_conf which - * has the FOC configuration - * @param[in] offset : Structure instance in which user updates offset - * values which are to be written in the sensor - * @param[in] dev : Structure instance of bmi160_dev. - * - * @note Offsets can be set by user like offset->off_acc_x = 10; - * where 1LSB = 3.9mg and for gyro 1LSB = 0.061degrees/second - * - * @note BMI160 offset values for xyz axes of accel should be within range of - * BMI160_ACCEL_MIN_OFFSET (-128) to BMI160_ACCEL_MAX_OFFSET (127) - * - * @note BMI160 offset values for xyz axes of gyro should be within range of - * BMI160_GYRO_MIN_OFFSET (-512) to BMI160_GYRO_MAX_OFFSET (511) - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - */ -int8_t bmi160_set_offsets( - const struct bmi160_foc_conf* foc_conf, - const struct bmi160_offsets* offset, - struct bmi160_dev const* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiNVM NVM - * @brief Write image registers values to NVM - */ - -/*! - * \ingroup bmi160ApiNVM - * \page bmi160_api_bmi160_update_nvm bmi160_update_nvm - * \code - * int8_t bmi160_update_nvm(struct bmi160_dev const *dev); - * \endcode - * @details This API writes the image registers values to NVM which is - * stored even after POR or soft reset - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - */ -int8_t bmi160_update_nvm(struct bmi160_dev const* dev); - -/** - * \ingroup bmi160 - * \defgroup bmi160ApiInts Interrupt status - * @brief Read interrupt status from the sensor - */ - -/*! - * \ingroup bmi160ApiInts - * \page bmi160_api_bmi160_get_int_status bmi160_get_int_status - * \code - * int8_t bmi160_get_int_status(enum bmi160_int_status_sel int_status_sel, - * union bmi160_int_status *int_status, - * struct bmi160_dev const *dev); - * \endcode - * @details This API gets the interrupt status from the sensor. - * - * @param[in] int_status_sel : Enum variable to select either individual or all the - * interrupt status bits. - * @param[in] int_status : pointer variable to get the interrupt status - * from the sensor. - * param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval 0 -> Success - * @retval Any non zero value -> Fail - */ -int8_t bmi160_get_int_status( - enum bmi160_int_status_sel int_status_sel, - union bmi160_int_status* int_status, - struct bmi160_dev const* dev); - -/*************************** C++ guard macro *****************************/ -#ifdef __cplusplus -} -#endif - -#endif /* BMI160_H_ */ +/** +* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* @file bmi160.h +* @date 2021-10-05 +* @version v3.9.2 +* +*/ + +/*! + * @defgroup bmi160 BMI160 + */ + +#ifndef BMI160_H_ +#define BMI160_H_ + +/*************************** C++ guard macro *****************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "bmi160_defs.h" +#ifdef __KERNEL__ +#include +#else +#include +#include +#include +#endif + +/*********************** User function prototypes ************************/ + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup bmi160ApiInit + * \page bmi160_api_bmi160_init bmi160_init + * \code + * int8_t bmi160_init(struct bmi160_dev *dev); + * \endcode + * @details This API is the entry point for sensor.It performs + * the selection of I2C/SPI read mechanism according to the + * selected interface and reads the chip-id of bmi160 sensor. + * + * @param[in,out] dev : Structure instance of bmi160_dev + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_init(struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiRegs Registers + * @brief Read data from the given register address of sensor + */ + +/*! + * \ingroup bmi160ApiRegs + * \page bmi160_api_bmi160_get_regs bmi160_get_regs + * \code + * int8_t bmi160_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API reads the data from the given register address of sensor. + * + * @param[in] reg_addr : Register address from where the data to be read + * @param[out] data : Pointer to data buffer to store the read data. + * @param[in] len : No of bytes of data to be read. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note For most of the registers auto address increment applies, with the + * exception of a few special registers, which trap the address. For e.g., + * Register address - 0x24(BMI160_FIFO_DATA_ADDR) + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiRegs + * \page bmi160_api_bmi160_set_regs bmi160_set_regs + * \code + * int8_t bmi160_set_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API writes the given data to the register address + * of sensor. + * + * @param[in] reg_addr : Register address from where the data to be written. + * @param[in] data : Pointer to data buffer which is to be written + * in the sensor. + * @param[in] len : No of bytes of data to write.. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiSoftreset Soft reset + * @brief Perform soft reset of the sensor + */ + +/*! + * \ingroup bmi160ApiSoftreset + * \page bmi160_api_bmi160_soft_reset bmi160_soft_reset + * \code + * int8_t bmi160_soft_reset(struct bmi160_dev *dev); + * \endcode + * @details This API resets and restarts the device. + * All register values are overwritten with default parameters. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_soft_reset(struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiConfig Configuration + * @brief Configuration of the sensor + */ + +/*! + * \ingroup bmi160ApiConfig + * \page bmi160_api_bmi160_set_sens_conf bmi160_set_sens_conf + * \code + * int8_t bmi160_set_sens_conf(struct bmi160_dev *dev); + * \endcode + * @details This API configures the power mode, range and bandwidth + * of sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_sens_conf(struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiConfig + * \page bmi160_api_bmi160_get_sens_conf bmi160_get_sens_conf + * \code + * int8_t bmi160_get_sens_conf(struct bmi160_dev *dev); + * \endcode + * @details This API gets accel and gyro configurations. + * + * @param[out] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_sens_conf(struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiPowermode Power mode + * @brief Set / Get power mode of the sensor + */ + +/*! + * \ingroup bmi160ApiPowermode + * \page bmi160_api_bmi160_set_power_mode bmi160_set_power_mode + * \code + * int8_t bmi160_set_power_mode(struct bmi160_dev *dev); + * \endcode + * @details This API sets the power mode of the sensor. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_power_mode(struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiPowermode + * \page bmi160_api_bmi160_get_power_mode bmi160_get_power_mode + * \code + * int8_t bmi160_get_power_mode(struct bmi160_dev *dev); + * \endcode + * @details This API gets the power mode of the sensor. + * + * @param[in] dev : Structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_power_mode(struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiData Sensor Data + * @brief Read sensor data + */ + +/*! + * \ingroup bmi160ApiData + * \page bmi160_api_bmi160_get_sensor_data bmi160_get_sensor_data + * \code + * int8_t bmi160_get_sensor_data(uint8_t select_sensor, + * struct bmi160_sensor_data *accel, + * struct bmi160_sensor_data *gyro, + * const struct bmi160_dev *dev); + * + * \endcode + * @details This API reads sensor data, stores it in + * the bmi160_sensor_data structure pointer passed by the user. + * The user can ask for accel data ,gyro data or both sensor + * data using bmi160_select_sensor enum + * + * @param[in] select_sensor : enum to choose accel,gyro or both sensor data + * @param[out] accel : Structure pointer to store accel data + * @param[out] gyro : Structure pointer to store gyro data + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_sensor_data(uint8_t select_sensor, + struct bmi160_sensor_data *accel, + struct bmi160_sensor_data *gyro, + const struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiInt Interrupt configuration + * @brief Set interrupt configuration of the sensor + */ + +/*! + * \ingroup bmi160ApiInt + * \page bmi160_api_bmi160_set_int_config bmi160_set_int_config + * \code + * int8_t bmi160_set_int_config(struct bmi160_int_settg *int_config, struct bmi160_dev *dev); + * \endcode + * @details This API configures the necessary interrupt based on + * the user settings in the bmi160_int_settg structure instance. + * + * @param[in] int_config : Structure instance of bmi160_int_settg. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_int_config(struct bmi160_int_settg *int_config, struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiStepC Step counter + * @brief Step counter operations + */ + +/*! + * \ingroup bmi160ApiStepC + * \page bmi160_api_bmi160_set_step_counter bmi160_set_step_counter + * \code + * int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev *dev); + * \endcode + * @details This API enables the step counter feature. + * + * @param[in] step_cnt_enable : value to enable or disable + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiStepC + * \page bmi160_api_bmi160_read_step_counter bmi160_read_step_counter + * \code + * int8_t bmi160_read_step_counter(uint16_t *step_val, const struct bmi160_dev *dev); + * \endcode + * @details This API reads the step counter value. + * + * @param[in] step_val : Pointer to store the step counter value. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_read_step_counter(uint16_t *step_val, const struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiAux Auxiliary sensor + * @brief Auxiliary sensor operations + */ + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_aux_read bmi160_aux_read + * \code + * int8_t bmi160_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API reads the mention no of byte of data from the given + * register address of auxiliary sensor. + * + * @param[in] reg_addr : Address of register to read. + * @param[in] aux_data : Pointer to store the read data. + * @param[in] len : No of bytes to read. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_aux_write bmi160_aux_write + * \code + * int8_t bmi160_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); + * \endcode + * @details This API writes the mention no of byte of data to the given + * register address of auxiliary sensor. + * + * @param[in] reg_addr : Address of register to write. + * @param[in] aux_data : Pointer to write data. + * @param[in] len : No of bytes to write. + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_aux_init bmi160_aux_init + * \code + * int8_t bmi160_aux_init(const struct bmi160_dev *dev); + * \endcode + * @details This API initialize the auxiliary sensor + * in order to access it. + * + * @param[in] dev : Structure instance of bmi160_dev. + * @note : Refer user guide for detailed info. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_aux_init(const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_set_aux_auto_mode bmi160_set_aux_auto_mode + * \code + * int8_t bmi160_set_aux_auto_mode(uint8_t *data_addr, struct bmi160_dev *dev); + * \endcode + * @details This API is used to setup the auxiliary sensor of bmi160 in auto mode + * Thus enabling the auto update of 8 bytes of data from auxiliary sensor + * to BMI160 register address 0x04 to 0x0B + * + * @param[in] data_addr : Starting address of aux. sensor's data register + * (BMI160 registers 0x04 to 0x0B will be updated + * with 8 bytes of data from auxiliary sensor + * starting from this register address.) + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note : Set the value of auxiliary polling rate by setting + * dev->aux_cfg.aux_odr to the required value from the table + * before calling this API + * + *@verbatim + * dev->aux_cfg.aux_odr | Auxiliary ODR (Hz) + * -----------------------|----------------------- + * BMI160_AUX_ODR_0_78HZ | 25/32 + * BMI160_AUX_ODR_1_56HZ | 25/16 + * BMI160_AUX_ODR_3_12HZ | 25/8 + * BMI160_AUX_ODR_6_25HZ | 25/4 + * BMI160_AUX_ODR_12_5HZ | 25/2 + * BMI160_AUX_ODR_25HZ | 25 + * BMI160_AUX_ODR_50HZ | 50 + * BMI160_AUX_ODR_100HZ | 100 + * BMI160_AUX_ODR_200HZ | 200 + * BMI160_AUX_ODR_400HZ | 400 + * BMI160_AUX_ODR_800HZ | 800 + *@endverbatim + * + * @note : Other values of dev->aux_cfg.aux_odr are reserved and not for use + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_set_aux_auto_mode(uint8_t *data_addr, struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_config_aux_mode bmi160_config_aux_mode + * \code + * int8_t bmi160_config_aux_mode(const struct bmi160_dev *dev); + * \endcode + * @details This API configures the 0x4C register and settings like + * Auxiliary sensor manual enable/ disable and aux burst read length. + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_config_aux_mode(const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiAux + * \page bmi160_api_bmi160_read_aux_data_auto_mode bmi160_read_aux_data_auto_mode + * \code + * int8_t bmi160_read_aux_data_auto_mode(uint8_t *aux_data, const struct bmi160_dev *dev); + * \endcode + * @details This API is used to read the raw uncompensated auxiliary sensor + * data of 8 bytes from BMI160 register address 0x04 to 0x0B + * + * @param[in] aux_data : Pointer to user array of length 8 bytes + * Ensure that the aux_data array is of + * length 8 bytes + * @param[in] dev : Structure instance of bmi160_dev + * + * @retval zero -> Success / -ve value -> Error + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_read_aux_data_auto_mode(uint8_t *aux_data, const struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiSelfTest Self test + * @brief Perform self test of the sensor + */ + +/*! + * \ingroup bmi160ApiSelfTest + * \page bmi160_api_bmi160_perform_self_test bmi160_perform_self_test + * \code + * int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev *dev); + * \endcode + * @details This is used to perform self test of accel/gyro of the BMI160 sensor + * + * @param[in] select_sensor : enum to choose accel or gyro for self test + * @param[in] dev : Structure instance of bmi160_dev + * + * @note self test can be performed either for accel/gyro at any instant. + * + *@verbatim + * value of select_sensor | Inference + *----------------------------------|-------------------------------- + * BMI160_ACCEL_ONLY | Accel self test enabled + * BMI160_GYRO_ONLY | Gyro self test enabled + * BMI160_BOTH_ACCEL_AND_GYRO | NOT TO BE USED + *@endverbatim + * + * @note The return value of this API gives us the result of self test. + * + * @note Performing self test does soft reset of the sensor, User can + * set the desired settings after performing the self test. + * + * @return Result of API execution status + * @retval BMI160_OK Self test success + * @retval BMI160_W_GYRO_SELF_TEST_FAIL Gyro self test fail + * @retval BMI160_W_ACCEl_SELF_TEST_FAIL Accel self test fail + */ +int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiFIFO FIFO + * @brief FIFO operations of the sensor + */ + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_get_fifo_data bmi160_get_fifo_data + * \code + * int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev); + * \endcode + * @details This API reads data from the fifo buffer. + * + * @note User has to allocate the FIFO buffer along with + * corresponding fifo length from his side before calling this API + * as mentioned in the readme.md + * + * @note User must specify the number of bytes to read from the FIFO in + * dev->fifo->length , It will be updated by the number of bytes actually + * read from FIFO after calling this API + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval Zero Success + * @retval Negative Error + */ +int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_flush bmi160_set_fifo_flush + * \code + * int8_t bmi160_set_fifo_flush(const struct bmi160_dev *dev); + * \endcode + * @details This API writes fifo_flush command to command register.This + * action clears all data in the Fifo without changing fifo configuration + * settings. + * + * @param[in] dev : Structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_flush(const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_config bmi160_set_fifo_config + * \code + * int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const *dev); + * \endcode + * @details This API sets the FIFO configuration in the sensor. + * + * @param[in] config : variable used to specify the FIFO + * configurations which are to be enabled or disabled in the sensor. + * + * @note : User can set either set one or more or all FIFO configurations + * by ORing the below mentioned macros. + * + *@verbatim + * config | Value + * ------------------------|--------------------------- + * BMI160_FIFO_TIME | 0x02 + * BMI160_FIFO_TAG_INT2 | 0x04 + * BMI160_FIFO_TAG_INT1 | 0x08 + * BMI160_FIFO_HEADER | 0x10 + * BMI160_FIFO_AUX | 0x20 + * BMI160_FIFO_ACCEL | 0x40 + * BMI160_FIFO_GYRO | 0x80 + *@endverbatim + * + * @param[in] enable : Parameter used to enable or disable the above + * FIFO configuration + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return status of bus communication result + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_down bmi160_set_fifo_down + * \code + * int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev *dev); + * \endcode + * @details This API is used to configure the down sampling ratios of + * the accel and gyro data for FIFO.Also, it configures filtered or + * pre-filtered data for the fifo for accel and gyro. + * + * @param[in] fifo_down : variable used to specify the FIFO down + * configurations which are to be enabled or disabled in the sensor. + * + * @note The user must select one among the following macros to + * select down-sampling ratio for accel + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_ACCEL_FIFO_DOWN_ZERO | 0x00 + * BMI160_ACCEL_FIFO_DOWN_ONE | 0x10 + * BMI160_ACCEL_FIFO_DOWN_TWO | 0x20 + * BMI160_ACCEL_FIFO_DOWN_THREE | 0x30 + * BMI160_ACCEL_FIFO_DOWN_FOUR | 0x40 + * BMI160_ACCEL_FIFO_DOWN_FIVE | 0x50 + * BMI160_ACCEL_FIFO_DOWN_SIX | 0x60 + * BMI160_ACCEL_FIFO_DOWN_SEVEN | 0x70 + *@endverbatim + * + * @note The user must select one among the following macros to + * select down-sampling ratio for gyro + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_GYRO_FIFO_DOWN_ZERO | 0x00 + * BMI160_GYRO_FIFO_DOWN_ONE | 0x01 + * BMI160_GYRO_FIFO_DOWN_TWO | 0x02 + * BMI160_GYRO_FIFO_DOWN_THREE | 0x03 + * BMI160_GYRO_FIFO_DOWN_FOUR | 0x04 + * BMI160_GYRO_FIFO_DOWN_FIVE | 0x05 + * BMI160_GYRO_FIFO_DOWN_SIX | 0x06 + * BMI160_GYRO_FIFO_DOWN_SEVEN | 0x07 + *@endverbatim + * + * @note The user can enable filtered accel data by the following macro + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_ACCEL_FIFO_FILT_EN | 0x80 + *@endverbatim + * + * @note The user can enable filtered gyro data by the following macro + * + *@verbatim + * config | Value + * -------------------------------------|--------------------------- + * BMI160_GYRO_FIFO_FILT_EN | 0x08 + *@endverbatim + * + * @note : By ORing the above mentioned macros, the user can select + * the required FIFO down config settings + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return status of bus communication result + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_set_fifo_wm bmi160_set_fifo_wm + * \code + * int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev *dev); + * \endcode + * @details This API sets the FIFO watermark level in the sensor. + * + * @note The FIFO watermark is issued when the FIFO fill level is + * equal or above the watermark level and units of watermark is 4 bytes. + * + * @param[in] fifo_wm : Variable used to set the FIFO water mark level + * @param[in] dev : Structure instance of bmi160_dev + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_extract_accel bmi160_extract_accel + * \code + * int8_t bmi160_extract_accel(struct bmi160_sensor_data *accel_data, uint8_t *accel_length, struct bmi160_dev const + **dev); + * \endcode + * @details This API parses and extracts the accelerometer frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "accel_data" structure instance. + * + * @note The bmi160_extract_accel API should be called only after + * reading the FIFO data by calling the bmi160_get_fifo_data() API. + * + * @param[out] accel_data : Structure instance of bmi160_sensor_data + * where the accelerometer data in FIFO is stored. + * @param[in,out] accel_length : Number of valid accelerometer frames + * (x,y,z axes data) read out from fifo. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note accel_length is updated with the number of valid accelerometer + * frames extracted from fifo (1 accel frame = 6 bytes) at the end of + * execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_extract_accel(struct bmi160_sensor_data *accel_data, uint8_t *accel_length, struct bmi160_dev const *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_extract_gyro bmi160_extract_gyro + * \code + * int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_length, struct bmi160_dev const *dev); + * \endcode + * @details This API parses and extracts the gyro frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the "gyro_data" structure instance. + * + * @note The bmi160_extract_gyro API should be called only after + * reading the FIFO data by calling the bmi160_get_fifo_data() API. + * + * @param[out] gyro_data : Structure instance of bmi160_sensor_data + * where the gyro data in FIFO is stored. + * @param[in,out] gyro_length : Number of valid gyro frames + * (x,y,z axes data) read out from fifo. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note gyro_length is updated with the number of valid gyro + * frames extracted from fifo (1 gyro frame = 6 bytes) at the end of + * execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_length, struct bmi160_dev const *dev); + +/*! + * \ingroup bmi160ApiFIFO + * \page bmi160_api_bmi160_extract_aux bmi160_extract_aux + * \code + * int8_t bmi160_extract_aux(struct bmi160_aux_data *aux_data, uint8_t *aux_len, struct bmi160_dev const *dev); + * \endcode + * @details This API parses and extracts the aux frames from + * FIFO data read by the "bmi160_get_fifo_data" API and stores it in + * the bmi160_aux_data structure instance. + * + * @note The bmi160_extract_aux API should be called only after + * reading the FIFO data by calling the bmi160_get_fifo_data() API. + * + * @param[out] aux_data : Structure instance of bmi160_aux_data + * where the aux data in FIFO is stored. + * @param[in,out] aux_len : Number of valid aux frames (8bytes) + * read out from FIFO. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note aux_len is updated with the number of valid aux + * frames extracted from fifo (1 aux frame = 8 bytes) at the end of + * execution of this API. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + * + */ +int8_t bmi160_extract_aux(struct bmi160_aux_data *aux_data, uint8_t *aux_len, struct bmi160_dev const *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiFOC FOC + * @brief Start FOC of accel and gyro sensors + */ + +/*! + * \ingroup bmi160ApiFOC + * \page bmi160_api_bmi160_start_foc bmi160_start_foc + * \code + * int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, + * \endcode + * @details This API starts the FOC of accel and gyro + * + * @note FOC should not be used in low-power mode of sensor + * + * @note Accel FOC targets values of +1g , 0g , -1g + * Gyro FOC always targets value of 0 dps + * + * @param[in] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC configuration + * @param[in,out] offset : Structure instance to store Offset + * values read from sensor + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note Pre-requisites for triggering FOC in accel , Set the following, + * Enable the acc_off_en + * Ex : foc_conf.acc_off_en = BMI160_ENABLE; + * + * Set the desired target values of FOC to each axes (x,y,z) by using the + * following macros + * - BMI160_FOC_ACCEL_DISABLED + * - BMI160_FOC_ACCEL_POSITIVE_G + * - BMI160_FOC_ACCEL_NEGATIVE_G + * - BMI160_FOC_ACCEL_0G + * + * Ex : foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G; + * foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G; + * foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G; + * + * @note Pre-requisites for triggering FOC in gyro , + * Set the following parameters, + * + * Ex : foc_conf.foc_gyr_en = BMI160_ENABLE; + * foc_conf.gyro_off_en = BMI160_ENABLE; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, + struct bmi160_offsets *offset, + struct bmi160_dev const *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiOffsets Offsets + * @brief Set / Get offset values of accel and gyro sensors + */ + +/*! + * \ingroup bmi160ApiOffsets + * \page bmi160_api_bmi160_get_offsets bmi160_get_offsets + * \code + * int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev); + * \endcode + * @details This API reads and stores the offset values of accel and gyro + * + * @param[in,out] offset : Structure instance of bmi160_offsets in which + * the offset values are read and stored + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev); + +/*! + * \ingroup bmi160ApiOffsets + * \page bmi160_api_bmi160_set_offsets bmi160_set_offsets + * \code + * int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, + * const struct bmi160_offsets *offset, + * struct bmi160_dev const *dev); + * \endcode + * @details This API writes the offset values of accel and gyro to + * the sensor but these values will be reset on POR or soft reset. + * + * @param[in] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC configuration + * @param[in] offset : Structure instance in which user updates offset + * values which are to be written in the sensor + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note Offsets can be set by user like offset->off_acc_x = 10; + * where 1LSB = 3.9mg and for gyro 1LSB = 0.061degrees/second + * + * @note BMI160 offset values for xyz axes of accel should be within range of + * BMI160_ACCEL_MIN_OFFSET (-128) to BMI160_ACCEL_MAX_OFFSET (127) + * + * @note BMI160 offset values for xyz axes of gyro should be within range of + * BMI160_GYRO_MIN_OFFSET (-512) to BMI160_GYRO_MAX_OFFSET (511) + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, + const struct bmi160_offsets *offset, + struct bmi160_dev const *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiNVM NVM + * @brief Write image registers values to NVM + */ + +/*! + * \ingroup bmi160ApiNVM + * \page bmi160_api_bmi160_update_nvm bmi160_update_nvm + * \code + * int8_t bmi160_update_nvm(struct bmi160_dev const *dev); + * \endcode + * @details This API writes the image registers values to NVM which is + * stored even after POR or soft reset + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_update_nvm(struct bmi160_dev const *dev); + +/** + * \ingroup bmi160 + * \defgroup bmi160ApiInts Interrupt status + * @brief Read interrupt status from the sensor + */ + +/*! + * \ingroup bmi160ApiInts + * \page bmi160_api_bmi160_get_int_status bmi160_get_int_status + * \code + * int8_t bmi160_get_int_status(enum bmi160_int_status_sel int_status_sel, + * union bmi160_int_status *int_status, + * struct bmi160_dev const *dev); + * \endcode + * @details This API gets the interrupt status from the sensor. + * + * @param[in] int_status_sel : Enum variable to select either individual or all the + * interrupt status bits. + * @param[in] int_status : pointer variable to get the interrupt status + * from the sensor. + * param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_get_int_status(enum bmi160_int_status_sel int_status_sel, + union bmi160_int_status *int_status, + struct bmi160_dev const *dev); + +/*************************** C++ guard macro *****************************/ +#ifdef __cplusplus +} +#endif + +#endif /* BMI160_H_ */ diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/bmi160_defs.h b/non_catalog_apps/airmouse/lib/bmi160-api/bmi160_defs.h new file mode 100644 index 00000000000..b4b8682747d --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/bmi160_defs.h @@ -0,0 +1,1647 @@ +/** +* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. +* +* BSD-3-Clause +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* @file bmi160_defs.h +* @date 2021-10-05 +* @version v3.9.2 +* +*/ + +#ifndef BMI160_DEFS_H_ +#define BMI160_DEFS_H_ + +/*************************** C types headers *****************************/ +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +/*************************** Common macros *****************************/ + +#if !defined(UINT8_C) && !defined(INT8_C) +#define INT8_C(x) S8_C(x) +#define UINT8_C(x) U8_C(x) +#endif + +#if !defined(UINT16_C) && !defined(INT16_C) +#define INT16_C(x) S16_C(x) +#define UINT16_C(x) U16_C(x) +#endif + +#if !defined(INT32_C) && !defined(UINT32_C) +#define INT32_C(x) S32_C(x) +#define UINT32_C(x) U32_C(x) +#endif + +#if !defined(INT64_C) && !defined(UINT64_C) +#define INT64_C(x) S64_C(x) +#define UINT64_C(x) U64_C(x) +#endif + +/**@}*/ +/**\name C standard macros */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +/*************************** Sensor macros *****************************/ +/* Test for an endian machine */ +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ 0 +#endif + +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1 +#endif +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 1 +#endif +#else +#error "Code does not support Endian format of the processor" +#endif + +/** Mask definitions */ +#define BMI160_ACCEL_BW_MASK UINT8_C(0x70) +#define BMI160_ACCEL_ODR_MASK UINT8_C(0x0F) +#define BMI160_ACCEL_UNDERSAMPLING_MASK UINT8_C(0x80) +#define BMI160_ACCEL_RANGE_MASK UINT8_C(0x0F) +#define BMI160_GYRO_BW_MASK UINT8_C(0x30) +#define BMI160_GYRO_ODR_MASK UINT8_C(0x0F) +#define BMI160_GYRO_RANGE_MASK UINT8_C(0x07) + +#define BMI160_ACCEL_BW_POS UINT8_C(4) +#define BMI160_GYRO_BW_POS UINT8_C(4) + +/** Mask definitions for INT_EN registers */ +#define BMI160_ANY_MOTION_X_INT_EN_MASK UINT8_C(0x01) +#define BMI160_HIGH_G_X_INT_EN_MASK UINT8_C(0x01) +#define BMI160_NO_MOTION_X_INT_EN_MASK UINT8_C(0x01) +#define BMI160_ANY_MOTION_Y_INT_EN_MASK UINT8_C(0x02) +#define BMI160_HIGH_G_Y_INT_EN_MASK UINT8_C(0x02) +#define BMI160_NO_MOTION_Y_INT_EN_MASK UINT8_C(0x02) +#define BMI160_ANY_MOTION_Z_INT_EN_MASK UINT8_C(0x04) +#define BMI160_HIGH_G_Z_INT_EN_MASK UINT8_C(0x04) +#define BMI160_NO_MOTION_Z_INT_EN_MASK UINT8_C(0x04) +#define BMI160_SIG_MOTION_INT_EN_MASK UINT8_C(0x07) +#define BMI160_ANY_MOTION_ALL_INT_EN_MASK UINT8_C(0x07) +#define BMI160_STEP_DETECT_INT_EN_MASK UINT8_C(0x08) +#define BMI160_DOUBLE_TAP_INT_EN_MASK UINT8_C(0x10) +#define BMI160_SINGLE_TAP_INT_EN_MASK UINT8_C(0x20) +#define BMI160_FIFO_FULL_INT_EN_MASK UINT8_C(0x20) +#define BMI160_ORIENT_INT_EN_MASK UINT8_C(0x40) +#define BMI160_FIFO_WATERMARK_INT_EN_MASK UINT8_C(0x40) +#define BMI160_LOW_G_INT_EN_MASK UINT8_C(0x08) +#define BMI160_STEP_DETECT_EN_MASK UINT8_C(0x08) +#define BMI160_FLAT_INT_EN_MASK UINT8_C(0x80) +#define BMI160_DATA_RDY_INT_EN_MASK UINT8_C(0x10) + +/** PMU status Macros */ +#define BMI160_AUX_PMU_SUSPEND UINT8_C(0x00) +#define BMI160_AUX_PMU_NORMAL UINT8_C(0x01) +#define BMI160_AUX_PMU_LOW_POWER UINT8_C(0x02) + +#define BMI160_GYRO_PMU_SUSPEND UINT8_C(0x00) +#define BMI160_GYRO_PMU_NORMAL UINT8_C(0x01) +#define BMI160_GYRO_PMU_FSU UINT8_C(0x03) + +#define BMI160_ACCEL_PMU_SUSPEND UINT8_C(0x00) +#define BMI160_ACCEL_PMU_NORMAL UINT8_C(0x01) +#define BMI160_ACCEL_PMU_LOW_POWER UINT8_C(0x02) + +/** Mask definitions for INT_OUT_CTRL register */ +#define BMI160_INT1_EDGE_CTRL_MASK UINT8_C(0x01) +#define BMI160_INT1_OUTPUT_MODE_MASK UINT8_C(0x04) +#define BMI160_INT1_OUTPUT_TYPE_MASK UINT8_C(0x02) +#define BMI160_INT1_OUTPUT_EN_MASK UINT8_C(0x08) +#define BMI160_INT2_EDGE_CTRL_MASK UINT8_C(0x10) +#define BMI160_INT2_OUTPUT_MODE_MASK UINT8_C(0x40) +#define BMI160_INT2_OUTPUT_TYPE_MASK UINT8_C(0x20) +#define BMI160_INT2_OUTPUT_EN_MASK UINT8_C(0x80) + +/** Mask definitions for INT_LATCH register */ +#define BMI160_INT1_INPUT_EN_MASK UINT8_C(0x10) +#define BMI160_INT2_INPUT_EN_MASK UINT8_C(0x20) +#define BMI160_INT_LATCH_MASK UINT8_C(0x0F) + +/** Mask definitions for INT_MAP register */ +#define BMI160_INT1_LOW_G_MASK UINT8_C(0x01) +#define BMI160_INT1_HIGH_G_MASK UINT8_C(0x02) +#define BMI160_INT1_SLOPE_MASK UINT8_C(0x04) +#define BMI160_INT1_NO_MOTION_MASK UINT8_C(0x08) +#define BMI160_INT1_DOUBLE_TAP_MASK UINT8_C(0x10) +#define BMI160_INT1_SINGLE_TAP_MASK UINT8_C(0x20) +#define BMI160_INT1_FIFO_FULL_MASK UINT8_C(0x20) +#define BMI160_INT1_FIFO_WM_MASK UINT8_C(0x40) +#define BMI160_INT1_ORIENT_MASK UINT8_C(0x40) +#define BMI160_INT1_FLAT_MASK UINT8_C(0x80) +#define BMI160_INT1_DATA_READY_MASK UINT8_C(0x80) +#define BMI160_INT2_LOW_G_MASK UINT8_C(0x01) +#define BMI160_INT1_LOW_STEP_DETECT_MASK UINT8_C(0x01) +#define BMI160_INT2_LOW_STEP_DETECT_MASK UINT8_C(0x01) +#define BMI160_INT2_HIGH_G_MASK UINT8_C(0x02) +#define BMI160_INT2_FIFO_FULL_MASK UINT8_C(0x02) +#define BMI160_INT2_FIFO_WM_MASK UINT8_C(0x04) +#define BMI160_INT2_SLOPE_MASK UINT8_C(0x04) +#define BMI160_INT2_DATA_READY_MASK UINT8_C(0x08) +#define BMI160_INT2_NO_MOTION_MASK UINT8_C(0x08) +#define BMI160_INT2_DOUBLE_TAP_MASK UINT8_C(0x10) +#define BMI160_INT2_SINGLE_TAP_MASK UINT8_C(0x20) +#define BMI160_INT2_ORIENT_MASK UINT8_C(0x40) +#define BMI160_INT2_FLAT_MASK UINT8_C(0x80) + +/** Mask definitions for INT_DATA register */ +#define BMI160_TAP_SRC_INT_MASK UINT8_C(0x08) +#define BMI160_LOW_HIGH_SRC_INT_MASK UINT8_C(0x80) +#define BMI160_MOTION_SRC_INT_MASK UINT8_C(0x80) + +/** Mask definitions for INT_MOTION register */ +#define BMI160_SLOPE_INT_DUR_MASK UINT8_C(0x03) +#define BMI160_NO_MOTION_INT_DUR_MASK UINT8_C(0xFC) +#define BMI160_NO_MOTION_SEL_BIT_MASK UINT8_C(0x01) + +/** Mask definitions for INT_TAP register */ +#define BMI160_TAP_DUR_MASK UINT8_C(0x07) +#define BMI160_TAP_SHOCK_DUR_MASK UINT8_C(0x40) +#define BMI160_TAP_QUIET_DUR_MASK UINT8_C(0x80) +#define BMI160_TAP_THRES_MASK UINT8_C(0x1F) + +/** Mask definitions for INT_FLAT register */ +#define BMI160_FLAT_THRES_MASK UINT8_C(0x3F) +#define BMI160_FLAT_HOLD_TIME_MASK UINT8_C(0x30) +#define BMI160_FLAT_HYST_MASK UINT8_C(0x07) + +/** Mask definitions for INT_LOWHIGH register */ +#define BMI160_LOW_G_HYST_MASK UINT8_C(0x03) +#define BMI160_LOW_G_LOW_MODE_MASK UINT8_C(0x04) +#define BMI160_HIGH_G_HYST_MASK UINT8_C(0xC0) + +/** Mask definitions for INT_SIG_MOTION register */ +#define BMI160_SIG_MOTION_SEL_MASK UINT8_C(0x02) +#define BMI160_SIG_MOTION_SKIP_MASK UINT8_C(0x0C) +#define BMI160_SIG_MOTION_PROOF_MASK UINT8_C(0x30) + +/** Mask definitions for INT_ORIENT register */ +#define BMI160_ORIENT_MODE_MASK UINT8_C(0x03) +#define BMI160_ORIENT_BLOCK_MASK UINT8_C(0x0C) +#define BMI160_ORIENT_HYST_MASK UINT8_C(0xF0) +#define BMI160_ORIENT_THETA_MASK UINT8_C(0x3F) +#define BMI160_ORIENT_UD_ENABLE UINT8_C(0x40) +#define BMI160_AXES_EN_MASK UINT8_C(0x80) + +/** Mask definitions for FIFO_CONFIG register */ +#define BMI160_FIFO_GYRO UINT8_C(0x80) +#define BMI160_FIFO_ACCEL UINT8_C(0x40) +#define BMI160_FIFO_AUX UINT8_C(0x20) +#define BMI160_FIFO_TAG_INT1 UINT8_C(0x08) +#define BMI160_FIFO_TAG_INT2 UINT8_C(0x04) +#define BMI160_FIFO_TIME UINT8_C(0x02) +#define BMI160_FIFO_HEADER UINT8_C(0x10) +#define BMI160_FIFO_CONFIG_1_MASK UINT8_C(0xFE) + +/** Mask definitions for STEP_CONF register */ +#define BMI160_STEP_COUNT_EN_BIT_MASK UINT8_C(0x08) +#define BMI160_STEP_DETECT_MIN_THRES_MASK UINT8_C(0x18) +#define BMI160_STEP_DETECT_STEPTIME_MIN_MASK UINT8_C(0x07) +#define BMI160_STEP_MIN_BUF_MASK UINT8_C(0x07) + +/** Mask definition for FIFO Header Data Tag */ +#define BMI160_FIFO_TAG_INTR_MASK UINT8_C(0xFC) + +/** Fifo byte counter mask definitions */ +#define BMI160_FIFO_BYTE_COUNTER_MASK UINT8_C(0x07) + +/** Enable/disable bit value */ +#define BMI160_ENABLE UINT8_C(0x01) +#define BMI160_DISABLE UINT8_C(0x00) + +/** Latch Duration */ +#define BMI160_LATCH_DUR_NONE UINT8_C(0x00) +#define BMI160_LATCH_DUR_312_5_MICRO_SEC UINT8_C(0x01) +#define BMI160_LATCH_DUR_625_MICRO_SEC UINT8_C(0x02) +#define BMI160_LATCH_DUR_1_25_MILLI_SEC UINT8_C(0x03) +#define BMI160_LATCH_DUR_2_5_MILLI_SEC UINT8_C(0x04) +#define BMI160_LATCH_DUR_5_MILLI_SEC UINT8_C(0x05) +#define BMI160_LATCH_DUR_10_MILLI_SEC UINT8_C(0x06) +#define BMI160_LATCH_DUR_20_MILLI_SEC UINT8_C(0x07) +#define BMI160_LATCH_DUR_40_MILLI_SEC UINT8_C(0x08) +#define BMI160_LATCH_DUR_80_MILLI_SEC UINT8_C(0x09) +#define BMI160_LATCH_DUR_160_MILLI_SEC UINT8_C(0x0A) +#define BMI160_LATCH_DUR_320_MILLI_SEC UINT8_C(0x0B) +#define BMI160_LATCH_DUR_640_MILLI_SEC UINT8_C(0x0C) +#define BMI160_LATCH_DUR_1_28_SEC UINT8_C(0x0D) +#define BMI160_LATCH_DUR_2_56_SEC UINT8_C(0x0E) +#define BMI160_LATCHED UINT8_C(0x0F) + +/** BMI160 Register map */ +#define BMI160_CHIP_ID_ADDR UINT8_C(0x00) +#define BMI160_ERROR_REG_ADDR UINT8_C(0x02) +#define BMI160_PMU_STATUS_ADDR UINT8_C(0x03) +#define BMI160_AUX_DATA_ADDR UINT8_C(0x04) +#define BMI160_GYRO_DATA_ADDR UINT8_C(0x0C) +#define BMI160_ACCEL_DATA_ADDR UINT8_C(0x12) +#define BMI160_STATUS_ADDR UINT8_C(0x1B) +#define BMI160_INT_STATUS_ADDR UINT8_C(0x1C) +#define BMI160_FIFO_LENGTH_ADDR UINT8_C(0x22) +#define BMI160_FIFO_DATA_ADDR UINT8_C(0x24) +#define BMI160_ACCEL_CONFIG_ADDR UINT8_C(0x40) +#define BMI160_ACCEL_RANGE_ADDR UINT8_C(0x41) +#define BMI160_GYRO_CONFIG_ADDR UINT8_C(0x42) +#define BMI160_GYRO_RANGE_ADDR UINT8_C(0x43) +#define BMI160_AUX_ODR_ADDR UINT8_C(0x44) +#define BMI160_FIFO_DOWN_ADDR UINT8_C(0x45) +#define BMI160_FIFO_CONFIG_0_ADDR UINT8_C(0x46) +#define BMI160_FIFO_CONFIG_1_ADDR UINT8_C(0x47) +#define BMI160_AUX_IF_0_ADDR UINT8_C(0x4B) +#define BMI160_AUX_IF_1_ADDR UINT8_C(0x4C) +#define BMI160_AUX_IF_2_ADDR UINT8_C(0x4D) +#define BMI160_AUX_IF_3_ADDR UINT8_C(0x4E) +#define BMI160_AUX_IF_4_ADDR UINT8_C(0x4F) +#define BMI160_INT_ENABLE_0_ADDR UINT8_C(0x50) +#define BMI160_INT_ENABLE_1_ADDR UINT8_C(0x51) +#define BMI160_INT_ENABLE_2_ADDR UINT8_C(0x52) +#define BMI160_INT_OUT_CTRL_ADDR UINT8_C(0x53) +#define BMI160_INT_LATCH_ADDR UINT8_C(0x54) +#define BMI160_INT_MAP_0_ADDR UINT8_C(0x55) +#define BMI160_INT_MAP_1_ADDR UINT8_C(0x56) +#define BMI160_INT_MAP_2_ADDR UINT8_C(0x57) +#define BMI160_INT_DATA_0_ADDR UINT8_C(0x58) +#define BMI160_INT_DATA_1_ADDR UINT8_C(0x59) +#define BMI160_INT_LOWHIGH_0_ADDR UINT8_C(0x5A) +#define BMI160_INT_LOWHIGH_1_ADDR UINT8_C(0x5B) +#define BMI160_INT_LOWHIGH_2_ADDR UINT8_C(0x5C) +#define BMI160_INT_LOWHIGH_3_ADDR UINT8_C(0x5D) +#define BMI160_INT_LOWHIGH_4_ADDR UINT8_C(0x5E) +#define BMI160_INT_MOTION_0_ADDR UINT8_C(0x5F) +#define BMI160_INT_MOTION_1_ADDR UINT8_C(0x60) +#define BMI160_INT_MOTION_2_ADDR UINT8_C(0x61) +#define BMI160_INT_MOTION_3_ADDR UINT8_C(0x62) +#define BMI160_INT_TAP_0_ADDR UINT8_C(0x63) +#define BMI160_INT_TAP_1_ADDR UINT8_C(0x64) +#define BMI160_INT_ORIENT_0_ADDR UINT8_C(0x65) +#define BMI160_INT_ORIENT_1_ADDR UINT8_C(0x66) +#define BMI160_INT_FLAT_0_ADDR UINT8_C(0x67) +#define BMI160_INT_FLAT_1_ADDR UINT8_C(0x68) +#define BMI160_FOC_CONF_ADDR UINT8_C(0x69) +#define BMI160_CONF_ADDR UINT8_C(0x6A) + +#define BMI160_IF_CONF_ADDR UINT8_C(0x6B) +#define BMI160_SELF_TEST_ADDR UINT8_C(0x6D) +#define BMI160_OFFSET_ADDR UINT8_C(0x71) +#define BMI160_OFFSET_CONF_ADDR UINT8_C(0x77) +#define BMI160_INT_STEP_CNT_0_ADDR UINT8_C(0x78) +#define BMI160_INT_STEP_CONFIG_0_ADDR UINT8_C(0x7A) +#define BMI160_INT_STEP_CONFIG_1_ADDR UINT8_C(0x7B) +#define BMI160_COMMAND_REG_ADDR UINT8_C(0x7E) +#define BMI160_SPI_COMM_TEST_ADDR UINT8_C(0x7F) +#define BMI160_INTL_PULLUP_CONF_ADDR UINT8_C(0x85) + +/** Error code definitions */ +#define BMI160_OK INT8_C(0) +#define BMI160_E_NULL_PTR INT8_C(-1) +#define BMI160_E_COM_FAIL INT8_C(-2) +#define BMI160_E_DEV_NOT_FOUND INT8_C(-3) +#define BMI160_E_OUT_OF_RANGE INT8_C(-4) +#define BMI160_E_INVALID_INPUT INT8_C(-5) +#define BMI160_E_ACCEL_ODR_BW_INVALID INT8_C(-6) +#define BMI160_E_GYRO_ODR_BW_INVALID INT8_C(-7) +#define BMI160_E_LWP_PRE_FLTR_INT_INVALID INT8_C(-8) +#define BMI160_E_LWP_PRE_FLTR_INVALID INT8_C(-9) +#define BMI160_E_AUX_NOT_FOUND INT8_C(-10) +#define BMI160_E_FOC_FAILURE INT8_C(-11) +#define BMI160_E_READ_WRITE_LENGTH_INVALID INT8_C(-12) +#define BMI160_E_INVALID_CONFIG INT8_C(-13) + +/**\name API warning codes */ +#define BMI160_W_GYRO_SELF_TEST_FAIL INT8_C(1) +#define BMI160_W_ACCEl_SELF_TEST_FAIL INT8_C(2) + +/** BMI160 unique chip identifier */ +#define BMI160_CHIP_ID UINT8_C(0xD1) + +/** Soft reset command */ +#define BMI160_SOFT_RESET_CMD UINT8_C(0xb6) +#define BMI160_SOFT_RESET_DELAY_MS UINT8_C(1) + +/** Start FOC command */ +#define BMI160_START_FOC_CMD UINT8_C(0x03) + +/** NVM backup enabling command */ +#define BMI160_NVM_BACKUP_EN UINT8_C(0xA0) + +/* Delay in ms settings */ +#define BMI160_ACCEL_DELAY_MS UINT8_C(5) +#define BMI160_GYRO_DELAY_MS UINT8_C(80) +#define BMI160_ONE_MS_DELAY UINT8_C(1) +#define BMI160_AUX_COM_DELAY UINT8_C(10) +#define BMI160_GYRO_SELF_TEST_DELAY UINT8_C(20) +#define BMI160_ACCEL_SELF_TEST_DELAY UINT8_C(50) + +/** Self test configurations */ +#define BMI160_ACCEL_SELF_TEST_CONFIG UINT8_C(0x2C) +#define BMI160_ACCEL_SELF_TEST_POSITIVE_EN UINT8_C(0x0D) +#define BMI160_ACCEL_SELF_TEST_NEGATIVE_EN UINT8_C(0x09) +#define BMI160_ACCEL_SELF_TEST_LIMIT UINT16_C(8192) + +/** Power mode settings */ +/* Accel power mode */ +#define BMI160_ACCEL_NORMAL_MODE UINT8_C(0x11) +#define BMI160_ACCEL_LOWPOWER_MODE UINT8_C(0x12) +#define BMI160_ACCEL_SUSPEND_MODE UINT8_C(0x10) + +/* Gyro power mode */ +#define BMI160_GYRO_SUSPEND_MODE UINT8_C(0x14) +#define BMI160_GYRO_NORMAL_MODE UINT8_C(0x15) +#define BMI160_GYRO_FASTSTARTUP_MODE UINT8_C(0x17) + +/* Aux power mode */ +#define BMI160_AUX_SUSPEND_MODE UINT8_C(0x18) +#define BMI160_AUX_NORMAL_MODE UINT8_C(0x19) +#define BMI160_AUX_LOWPOWER_MODE UINT8_C(0x1A) + +/** Range settings */ +/* Accel Range */ +#define BMI160_ACCEL_RANGE_2G UINT8_C(0x03) +#define BMI160_ACCEL_RANGE_4G UINT8_C(0x05) +#define BMI160_ACCEL_RANGE_8G UINT8_C(0x08) +#define BMI160_ACCEL_RANGE_16G UINT8_C(0x0C) + +/* Gyro Range */ +#define BMI160_GYRO_RANGE_2000_DPS UINT8_C(0x00) +#define BMI160_GYRO_RANGE_1000_DPS UINT8_C(0x01) +#define BMI160_GYRO_RANGE_500_DPS UINT8_C(0x02) +#define BMI160_GYRO_RANGE_250_DPS UINT8_C(0x03) +#define BMI160_GYRO_RANGE_125_DPS UINT8_C(0x04) + +/** Bandwidth settings */ +/* Accel Bandwidth */ +#define BMI160_ACCEL_BW_OSR4_AVG1 UINT8_C(0x00) +#define BMI160_ACCEL_BW_OSR2_AVG2 UINT8_C(0x01) +#define BMI160_ACCEL_BW_NORMAL_AVG4 UINT8_C(0x02) +#define BMI160_ACCEL_BW_RES_AVG8 UINT8_C(0x03) +#define BMI160_ACCEL_BW_RES_AVG16 UINT8_C(0x04) +#define BMI160_ACCEL_BW_RES_AVG32 UINT8_C(0x05) +#define BMI160_ACCEL_BW_RES_AVG64 UINT8_C(0x06) +#define BMI160_ACCEL_BW_RES_AVG128 UINT8_C(0x07) + +#define BMI160_GYRO_BW_OSR4_MODE UINT8_C(0x00) +#define BMI160_GYRO_BW_OSR2_MODE UINT8_C(0x01) +#define BMI160_GYRO_BW_NORMAL_MODE UINT8_C(0x02) + +/* Output Data Rate settings */ +/* Accel Output data rate */ +#define BMI160_ACCEL_ODR_RESERVED UINT8_C(0x00) +#define BMI160_ACCEL_ODR_0_78HZ UINT8_C(0x01) +#define BMI160_ACCEL_ODR_1_56HZ UINT8_C(0x02) +#define BMI160_ACCEL_ODR_3_12HZ UINT8_C(0x03) +#define BMI160_ACCEL_ODR_6_25HZ UINT8_C(0x04) +#define BMI160_ACCEL_ODR_12_5HZ UINT8_C(0x05) +#define BMI160_ACCEL_ODR_25HZ UINT8_C(0x06) +#define BMI160_ACCEL_ODR_50HZ UINT8_C(0x07) +#define BMI160_ACCEL_ODR_100HZ UINT8_C(0x08) +#define BMI160_ACCEL_ODR_200HZ UINT8_C(0x09) +#define BMI160_ACCEL_ODR_400HZ UINT8_C(0x0A) +#define BMI160_ACCEL_ODR_800HZ UINT8_C(0x0B) +#define BMI160_ACCEL_ODR_1600HZ UINT8_C(0x0C) +#define BMI160_ACCEL_ODR_RESERVED0 UINT8_C(0x0D) +#define BMI160_ACCEL_ODR_RESERVED1 UINT8_C(0x0E) +#define BMI160_ACCEL_ODR_RESERVED2 UINT8_C(0x0F) + +/* Gyro Output data rate */ +#define BMI160_GYRO_ODR_RESERVED UINT8_C(0x00) +#define BMI160_GYRO_ODR_25HZ UINT8_C(0x06) +#define BMI160_GYRO_ODR_50HZ UINT8_C(0x07) +#define BMI160_GYRO_ODR_100HZ UINT8_C(0x08) +#define BMI160_GYRO_ODR_200HZ UINT8_C(0x09) +#define BMI160_GYRO_ODR_400HZ UINT8_C(0x0A) +#define BMI160_GYRO_ODR_800HZ UINT8_C(0x0B) +#define BMI160_GYRO_ODR_1600HZ UINT8_C(0x0C) +#define BMI160_GYRO_ODR_3200HZ UINT8_C(0x0D) + +/* Auxiliary sensor Output data rate */ +#define BMI160_AUX_ODR_RESERVED UINT8_C(0x00) +#define BMI160_AUX_ODR_0_78HZ UINT8_C(0x01) +#define BMI160_AUX_ODR_1_56HZ UINT8_C(0x02) +#define BMI160_AUX_ODR_3_12HZ UINT8_C(0x03) +#define BMI160_AUX_ODR_6_25HZ UINT8_C(0x04) +#define BMI160_AUX_ODR_12_5HZ UINT8_C(0x05) +#define BMI160_AUX_ODR_25HZ UINT8_C(0x06) +#define BMI160_AUX_ODR_50HZ UINT8_C(0x07) +#define BMI160_AUX_ODR_100HZ UINT8_C(0x08) +#define BMI160_AUX_ODR_200HZ UINT8_C(0x09) +#define BMI160_AUX_ODR_400HZ UINT8_C(0x0A) +#define BMI160_AUX_ODR_800HZ UINT8_C(0x0B) + +/** FIFO_CONFIG Definitions */ +#define BMI160_FIFO_TIME_ENABLE UINT8_C(0x02) +#define BMI160_FIFO_TAG_INT2_ENABLE UINT8_C(0x04) +#define BMI160_FIFO_TAG_INT1_ENABLE UINT8_C(0x08) +#define BMI160_FIFO_HEAD_ENABLE UINT8_C(0x10) +#define BMI160_FIFO_M_ENABLE UINT8_C(0x20) +#define BMI160_FIFO_A_ENABLE UINT8_C(0x40) +#define BMI160_FIFO_M_A_ENABLE UINT8_C(0x60) +#define BMI160_FIFO_G_ENABLE UINT8_C(0x80) +#define BMI160_FIFO_M_G_ENABLE UINT8_C(0xA0) +#define BMI160_FIFO_G_A_ENABLE UINT8_C(0xC0) +#define BMI160_FIFO_M_G_A_ENABLE UINT8_C(0xE0) + +/* Macro to specify the number of bytes over-read from the + * FIFO in order to get the sensor time at the end of FIFO */ +#ifndef BMI160_FIFO_BYTES_OVERREAD +#define BMI160_FIFO_BYTES_OVERREAD UINT8_C(25) +#endif + +/* Accel, gyro and aux. sensor length and also their combined + * length definitions in FIFO */ +#define BMI160_FIFO_G_LENGTH UINT8_C(6) +#define BMI160_FIFO_A_LENGTH UINT8_C(6) +#define BMI160_FIFO_M_LENGTH UINT8_C(8) +#define BMI160_FIFO_GA_LENGTH UINT8_C(12) +#define BMI160_FIFO_MA_LENGTH UINT8_C(14) +#define BMI160_FIFO_MG_LENGTH UINT8_C(14) +#define BMI160_FIFO_MGA_LENGTH UINT8_C(20) + +/** FIFO Header Data definitions */ +#define BMI160_FIFO_HEAD_SKIP_FRAME UINT8_C(0x40) +#define BMI160_FIFO_HEAD_SENSOR_TIME UINT8_C(0x44) +#define BMI160_FIFO_HEAD_INPUT_CONFIG UINT8_C(0x48) +#define BMI160_FIFO_HEAD_OVER_READ UINT8_C(0x80) +#define BMI160_FIFO_HEAD_A UINT8_C(0x84) +#define BMI160_FIFO_HEAD_G UINT8_C(0x88) +#define BMI160_FIFO_HEAD_G_A UINT8_C(0x8C) +#define BMI160_FIFO_HEAD_M UINT8_C(0x90) +#define BMI160_FIFO_HEAD_M_A UINT8_C(0x94) +#define BMI160_FIFO_HEAD_M_G UINT8_C(0x98) +#define BMI160_FIFO_HEAD_M_G_A UINT8_C(0x9C) + +/** FIFO sensor time length definitions */ +#define BMI160_SENSOR_TIME_LENGTH UINT8_C(3) + +/** FIFO DOWN selection */ +/* Accel fifo down-sampling values*/ +#define BMI160_ACCEL_FIFO_DOWN_ZERO UINT8_C(0x00) +#define BMI160_ACCEL_FIFO_DOWN_ONE UINT8_C(0x10) +#define BMI160_ACCEL_FIFO_DOWN_TWO UINT8_C(0x20) +#define BMI160_ACCEL_FIFO_DOWN_THREE UINT8_C(0x30) +#define BMI160_ACCEL_FIFO_DOWN_FOUR UINT8_C(0x40) +#define BMI160_ACCEL_FIFO_DOWN_FIVE UINT8_C(0x50) +#define BMI160_ACCEL_FIFO_DOWN_SIX UINT8_C(0x60) +#define BMI160_ACCEL_FIFO_DOWN_SEVEN UINT8_C(0x70) + +/* Gyro fifo down-smapling values*/ +#define BMI160_GYRO_FIFO_DOWN_ZERO UINT8_C(0x00) +#define BMI160_GYRO_FIFO_DOWN_ONE UINT8_C(0x01) +#define BMI160_GYRO_FIFO_DOWN_TWO UINT8_C(0x02) +#define BMI160_GYRO_FIFO_DOWN_THREE UINT8_C(0x03) +#define BMI160_GYRO_FIFO_DOWN_FOUR UINT8_C(0x04) +#define BMI160_GYRO_FIFO_DOWN_FIVE UINT8_C(0x05) +#define BMI160_GYRO_FIFO_DOWN_SIX UINT8_C(0x06) +#define BMI160_GYRO_FIFO_DOWN_SEVEN UINT8_C(0x07) + +/* Accel Fifo filter enable*/ +#define BMI160_ACCEL_FIFO_FILT_EN UINT8_C(0x80) + +/* Gyro Fifo filter enable*/ +#define BMI160_GYRO_FIFO_FILT_EN UINT8_C(0x08) + +/** Definitions to check validity of FIFO frames */ +#define FIFO_CONFIG_MSB_CHECK UINT8_C(0x80) +#define FIFO_CONFIG_LSB_CHECK UINT8_C(0x00) + +/*! BMI160 accel FOC configurations */ +#define BMI160_FOC_ACCEL_DISABLED UINT8_C(0x00) +#define BMI160_FOC_ACCEL_POSITIVE_G UINT8_C(0x01) +#define BMI160_FOC_ACCEL_NEGATIVE_G UINT8_C(0x02) +#define BMI160_FOC_ACCEL_0G UINT8_C(0x03) + +/** Array Parameter DefinItions */ +#define BMI160_SENSOR_TIME_LSB_BYTE UINT8_C(0) +#define BMI160_SENSOR_TIME_XLSB_BYTE UINT8_C(1) +#define BMI160_SENSOR_TIME_MSB_BYTE UINT8_C(2) + +/** Interface settings */ +#define BMI160_SPI_INTF UINT8_C(1) +#define BMI160_I2C_INTF UINT8_C(0) +#define BMI160_SPI_RD_MASK UINT8_C(0x80) +#define BMI160_SPI_WR_MASK UINT8_C(0x7F) + +/* Sensor & time select definition*/ +#define BMI160_ACCEL_SEL UINT8_C(0x01) +#define BMI160_GYRO_SEL UINT8_C(0x02) +#define BMI160_TIME_SEL UINT8_C(0x04) + +/* Sensor select mask*/ +#define BMI160_SEN_SEL_MASK UINT8_C(0x07) + +/* Error code mask */ +#define BMI160_ERR_REG_MASK UINT8_C(0x0F) + +/* BMI160 I2C address */ +#define BMI160_I2C_ADDR UINT8_C(0x68) + +/* BMI160 secondary IF address */ +#define BMI160_AUX_BMM150_I2C_ADDR UINT8_C(0x10) + +/** BMI160 Length definitions */ +#define BMI160_ONE UINT8_C(1) +#define BMI160_TWO UINT8_C(2) +#define BMI160_THREE UINT8_C(3) +#define BMI160_FOUR UINT8_C(4) +#define BMI160_FIVE UINT8_C(5) + +/** BMI160 fifo level Margin */ +#define BMI160_FIFO_LEVEL_MARGIN UINT8_C(16) + +/** BMI160 fifo flush Command */ +#define BMI160_FIFO_FLUSH_VALUE UINT8_C(0xB0) + +/** BMI160 offset values for xyz axes of accel */ +#define BMI160_ACCEL_MIN_OFFSET INT8_C(-128) +#define BMI160_ACCEL_MAX_OFFSET INT8_C(127) + +/** BMI160 offset values for xyz axes of gyro */ +#define BMI160_GYRO_MIN_OFFSET INT16_C(-512) +#define BMI160_GYRO_MAX_OFFSET INT16_C(511) + +/** BMI160 fifo full interrupt position and mask */ +#define BMI160_FIFO_FULL_INT_POS UINT8_C(5) +#define BMI160_FIFO_FULL_INT_MSK UINT8_C(0x20) +#define BMI160_FIFO_WTM_INT_POS UINT8_C(6) +#define BMI160_FIFO_WTM_INT_MSK UINT8_C(0x40) + +#define BMI160_FIFO_FULL_INT_PIN1_POS UINT8_C(5) +#define BMI160_FIFO_FULL_INT_PIN1_MSK UINT8_C(0x20) +#define BMI160_FIFO_FULL_INT_PIN2_POS UINT8_C(1) +#define BMI160_FIFO_FULL_INT_PIN2_MSK UINT8_C(0x02) + +#define BMI160_FIFO_WTM_INT_PIN1_POS UINT8_C(6) +#define BMI160_FIFO_WTM_INT_PIN1_MSK UINT8_C(0x40) +#define BMI160_FIFO_WTM_INT_PIN2_POS UINT8_C(2) +#define BMI160_FIFO_WTM_INT_PIN2_MSK UINT8_C(0x04) + +#define BMI160_MANUAL_MODE_EN_POS UINT8_C(7) +#define BMI160_MANUAL_MODE_EN_MSK UINT8_C(0x80) +#define BMI160_AUX_READ_BURST_POS UINT8_C(0) +#define BMI160_AUX_READ_BURST_MSK UINT8_C(0x03) + +#define BMI160_GYRO_SELF_TEST_POS UINT8_C(4) +#define BMI160_GYRO_SELF_TEST_MSK UINT8_C(0x10) +#define BMI160_GYRO_SELF_TEST_STATUS_POS UINT8_C(1) +#define BMI160_GYRO_SELF_TEST_STATUS_MSK UINT8_C(0x02) + +#define BMI160_GYRO_FOC_EN_POS UINT8_C(6) +#define BMI160_GYRO_FOC_EN_MSK UINT8_C(0x40) + +#define BMI160_ACCEL_FOC_X_CONF_POS UINT8_C(4) +#define BMI160_ACCEL_FOC_X_CONF_MSK UINT8_C(0x30) + +#define BMI160_ACCEL_FOC_Y_CONF_POS UINT8_C(2) +#define BMI160_ACCEL_FOC_Y_CONF_MSK UINT8_C(0x0C) + +#define BMI160_ACCEL_FOC_Z_CONF_MSK UINT8_C(0x03) + +#define BMI160_FOC_STATUS_POS UINT8_C(3) +#define BMI160_FOC_STATUS_MSK UINT8_C(0x08) + +#define BMI160_GYRO_OFFSET_X_MSK UINT8_C(0x03) + +#define BMI160_GYRO_OFFSET_Y_POS UINT8_C(2) +#define BMI160_GYRO_OFFSET_Y_MSK UINT8_C(0x0C) + +#define BMI160_GYRO_OFFSET_Z_POS UINT8_C(4) +#define BMI160_GYRO_OFFSET_Z_MSK UINT8_C(0x30) + +#define BMI160_GYRO_OFFSET_EN_POS UINT8_C(7) +#define BMI160_GYRO_OFFSET_EN_MSK UINT8_C(0x80) + +#define BMI160_ACCEL_OFFSET_EN_POS UINT8_C(6) +#define BMI160_ACCEL_OFFSET_EN_MSK UINT8_C(0x40) + +#define BMI160_GYRO_OFFSET_POS UINT16_C(8) +#define BMI160_GYRO_OFFSET_MSK UINT16_C(0x0300) + +#define BMI160_NVM_UPDATE_POS UINT8_C(1) +#define BMI160_NVM_UPDATE_MSK UINT8_C(0x02) + +#define BMI160_NVM_STATUS_POS UINT8_C(4) +#define BMI160_NVM_STATUS_MSK UINT8_C(0x10) + +#define BMI160_MAG_POWER_MODE_MSK UINT8_C(0x03) + +#define BMI160_ACCEL_POWER_MODE_MSK UINT8_C(0x30) +#define BMI160_ACCEL_POWER_MODE_POS UINT8_C(4) + +#define BMI160_GYRO_POWER_MODE_MSK UINT8_C(0x0C) +#define BMI160_GYRO_POWER_MODE_POS UINT8_C(2) + +/* BIT SLICE GET AND SET FUNCTIONS */ +#define BMI160_GET_BITS(regvar, bitname) \ + ((regvar & bitname##_MSK) >> bitname##_POS) +#define BMI160_SET_BITS(regvar, bitname, val) \ + ((regvar & ~bitname##_MSK) | \ + ((val << bitname##_POS) & bitname##_MSK)) + +#define BMI160_SET_BITS_POS_0(reg_data, bitname, data) \ + ((reg_data & ~(bitname##_MSK)) | \ + (data & bitname##_MSK)) + +#define BMI160_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) + +/**\name UTILITY MACROS */ +#define BMI160_SET_LOW_BYTE UINT16_C(0x00FF) +#define BMI160_SET_HIGH_BYTE UINT16_C(0xFF00) + +#define BMI160_GET_LSB(var) (uint8_t)(var & BMI160_SET_LOW_BYTE) +#define BMI160_GET_MSB(var) (uint8_t)((var & BMI160_SET_HIGH_BYTE) >> 8) + +/*****************************************************************************/ +/* type definitions */ + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific read functions of the user + */ +typedef int8_t (*bmi160_read_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len); + +/*! + * @brief Bus communication function pointer which should be mapped to + * the platform specific write functions of the user + */ +typedef int8_t (*bmi160_write_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *read_data, uint16_t len); +typedef void (*bmi160_delay_fptr_t)(uint32_t period); + +/*************************** Data structures *********************************/ + +/*! + * @brief bmi160 interrupt status selection enum. + */ +enum bmi160_int_status_sel { + BMI160_INT_STATUS_0 = 1, + BMI160_INT_STATUS_1 = 2, + BMI160_INT_STATUS_2 = 4, + BMI160_INT_STATUS_3 = 8, + BMI160_INT_STATUS_ALL = 15 +}; + +/*! + * @brief bmi160 interrupt status bits structure + */ +struct bmi160_int_status_bits +{ +#ifdef LITTLE_ENDIAN + + uint32_t step : 1; + uint32_t sigmot : 1; + uint32_t anym : 1; + + /* pmu trigger will be handled later */ + uint32_t pmu_trigger_reserved : 1; + uint32_t d_tap : 1; + uint32_t s_tap : 1; + uint32_t orient : 1; + uint32_t flat_int : 1; + uint32_t reserved : 2; + uint32_t high_g : 1; + uint32_t low_g : 1; + uint32_t drdy : 1; + uint32_t ffull : 1; + uint32_t fwm : 1; + uint32_t nomo : 1; + uint32_t anym_first_x : 1; + uint32_t anym_first_y : 1; + uint32_t anym_first_z : 1; + uint32_t anym_sign : 1; + uint32_t tap_first_x : 1; + uint32_t tap_first_y : 1; + uint32_t tap_first_z : 1; + uint32_t tap_sign : 1; + uint32_t high_first_x : 1; + uint32_t high_first_y : 1; + uint32_t high_first_z : 1; + uint32_t high_sign : 1; + uint32_t orient_1_0 : 2; + uint32_t orient_2 : 1; + uint32_t flat : 1; +#else + uint32_t high_first_x : 1; + uint32_t high_first_y : 1; + uint32_t high_first_z : 1; + uint32_t high_sign : 1; + uint32_t orient_1_0 : 2; + uint32_t orient_2 : 1; + uint32_t flat : 1; + uint32_t anym_first_x : 1; + uint32_t anym_first_y : 1; + uint32_t anym_first_z : 1; + uint32_t anym_sign : 1; + uint32_t tap_first_x : 1; + uint32_t tap_first_y : 1; + uint32_t tap_first_z : 1; + uint32_t tap_sign : 1; + uint32_t reserved : 2; + uint32_t high_g : 1; + uint32_t low_g : 1; + uint32_t drdy : 1; + uint32_t ffull : 1; + uint32_t fwm : 1; + uint32_t nomo : 1; + uint32_t step : 1; + uint32_t sigmot : 1; + uint32_t anym : 1; + + /* pmu trigger will be handled later */ + uint32_t pmu_trigger_reserved : 1; + uint32_t d_tap : 1; + uint32_t s_tap : 1; + uint32_t orient : 1; + uint32_t flat_int : 1; +#endif +}; + +/*! + * @brief bmi160 interrupt status structure + */ +union bmi160_int_status +{ + uint8_t data[4]; + struct bmi160_int_status_bits bit; +}; + +/*! + * @brief bmi160 sensor data structure which comprises of accel data + */ +struct bmi160_sensor_data +{ + /*! X-axis sensor data */ + int16_t x; + + /*! Y-axis sensor data */ + int16_t y; + + /*! Z-axis sensor data */ + int16_t z; + + /*! sensor time */ + uint32_t sensortime; +}; + +/*! + * @brief bmi160 aux data structure which comprises of 8 bytes of accel data + */ +struct bmi160_aux_data +{ + /*! Auxiliary data */ + uint8_t data[8]; +}; + +/*! + * @brief bmi160 FOC configuration structure + */ +struct bmi160_foc_conf +{ + /*! Enabling FOC in gyro + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t foc_gyr_en; + + /*! Accel FOC configurations + * Assignable macros : + * - BMI160_FOC_ACCEL_DISABLED + * - BMI160_FOC_ACCEL_POSITIVE_G + * - BMI160_FOC_ACCEL_NEGATIVE_G + * - BMI160_FOC_ACCEL_0G + */ + uint8_t foc_acc_x; + uint8_t foc_acc_y; + uint8_t foc_acc_z; + + /*! Enabling offset compensation for accel in data registers + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t acc_off_en; + + /*! Enabling offset compensation for gyro in data registers + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t gyro_off_en; +}; + +/*! + * @brief bmi160 accel gyro offsets + */ +struct bmi160_offsets +{ + /*! Accel offset for x axis */ + int8_t off_acc_x; + + /*! Accel offset for y axis */ + int8_t off_acc_y; + + /*! Accel offset for z axis */ + int8_t off_acc_z; + + /*! Gyro offset for x axis */ + int16_t off_gyro_x; + + /*! Gyro offset for y axis */ + int16_t off_gyro_y; + + /*! Gyro offset for z axis */ + int16_t off_gyro_z; +}; + +/*! + * @brief FIFO aux. sensor data structure + */ +struct bmi160_aux_fifo_data +{ + /*! The value of aux. sensor x LSB data */ + uint8_t aux_x_lsb; + + /*! The value of aux. sensor x MSB data */ + uint8_t aux_x_msb; + + /*! The value of aux. sensor y LSB data */ + uint8_t aux_y_lsb; + + /*! The value of aux. sensor y MSB data */ + uint8_t aux_y_msb; + + /*! The value of aux. sensor z LSB data */ + uint8_t aux_z_lsb; + + /*! The value of aux. sensor z MSB data */ + uint8_t aux_z_msb; + + /*! The value of aux. sensor r for BMM150 LSB data */ + uint8_t aux_r_y2_lsb; + + /*! The value of aux. sensor r for BMM150 MSB data */ + uint8_t aux_r_y2_msb; +}; + +/*! + * @brief bmi160 sensor select structure + */ +enum bmi160_select_sensor { + BMI160_ACCEL_ONLY = 1, + BMI160_GYRO_ONLY, + BMI160_BOTH_ACCEL_AND_GYRO +}; + +/*! + * @brief bmi160 sensor step detector mode structure + */ +enum bmi160_step_detect_mode { + BMI160_STEP_DETECT_NORMAL, + BMI160_STEP_DETECT_SENSITIVE, + BMI160_STEP_DETECT_ROBUST, + + /*! Non recommended User defined setting */ + BMI160_STEP_DETECT_USER_DEFINE +}; + +/*! + * @brief enum for auxiliary burst read selection + */ +enum bmi160_aux_read_len { + BMI160_AUX_READ_LEN_0, + BMI160_AUX_READ_LEN_1, + BMI160_AUX_READ_LEN_2, + BMI160_AUX_READ_LEN_3 +}; + +/*! + * @brief bmi160 sensor configuration structure + */ +struct bmi160_cfg +{ + /*! power mode */ + uint8_t power; + + /*! output data rate */ + uint8_t odr; + + /*! range */ + uint8_t range; + + /*! bandwidth */ + uint8_t bw; +}; + +/*! + * @brief Aux sensor configuration structure + */ +struct bmi160_aux_cfg +{ + /*! Aux sensor, 1 - enable 0 - disable */ + uint8_t aux_sensor_enable : 1; + + /*! Aux manual/auto mode status */ + uint8_t manual_enable : 1; + + /*! Aux read burst length */ + uint8_t aux_rd_burst_len : 2; + + /*! output data rate */ + uint8_t aux_odr : 4; + + /*! i2c addr of auxiliary sensor */ + uint8_t aux_i2c_addr; +}; + +/*! + * @brief bmi160 interrupt channel selection structure + */ +enum bmi160_int_channel { + /*! Un-map both channels */ + BMI160_INT_CHANNEL_NONE, + + /*! interrupt Channel 1 */ + BMI160_INT_CHANNEL_1, + + /*! interrupt Channel 2 */ + BMI160_INT_CHANNEL_2, + + /*! Map both channels */ + BMI160_INT_CHANNEL_BOTH +}; +enum bmi160_int_types { + /*! Slope/Any-motion interrupt */ + BMI160_ACC_ANY_MOTION_INT, + + /*! Significant motion interrupt */ + BMI160_ACC_SIG_MOTION_INT, + + /*! Step detector interrupt */ + BMI160_STEP_DETECT_INT, + + /*! double tap interrupt */ + BMI160_ACC_DOUBLE_TAP_INT, + + /*! single tap interrupt */ + BMI160_ACC_SINGLE_TAP_INT, + + /*! orientation interrupt */ + BMI160_ACC_ORIENT_INT, + + /*! flat interrupt */ + BMI160_ACC_FLAT_INT, + + /*! high-g interrupt */ + BMI160_ACC_HIGH_G_INT, + + /*! low-g interrupt */ + BMI160_ACC_LOW_G_INT, + + /*! slow/no-motion interrupt */ + BMI160_ACC_SLOW_NO_MOTION_INT, + + /*! data ready interrupt */ + BMI160_ACC_GYRO_DATA_RDY_INT, + + /*! fifo full interrupt */ + BMI160_ACC_GYRO_FIFO_FULL_INT, + + /*! fifo watermark interrupt */ + BMI160_ACC_GYRO_FIFO_WATERMARK_INT, + + /*! fifo tagging feature support */ + BMI160_FIFO_TAG_INT_PIN +}; + +/*! + * @brief bmi160 active state of any & sig motion interrupt. + */ +enum bmi160_any_sig_motion_active_interrupt_state { + /*! Both any & sig motion are disabled */ + BMI160_BOTH_ANY_SIG_MOTION_DISABLED = -1, + + /*! Any-motion selected */ + BMI160_ANY_MOTION_ENABLED, + + /*! Sig-motion selected */ + BMI160_SIG_MOTION_ENABLED +}; +struct bmi160_acc_tap_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! tap threshold */ + uint16_t tap_thr : 5; + + /*! tap shock */ + uint16_t tap_shock : 1; + + /*! tap quiet */ + uint16_t tap_quiet : 1; + + /*! tap duration */ + uint16_t tap_dur : 3; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t tap_data_src : 1; + + /*! tap enable, 1 - enable, 0 - disable */ + uint16_t tap_en : 1; +#else + + /*! tap enable, 1 - enable, 0 - disable */ + uint16_t tap_en : 1; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t tap_data_src : 1; + + /*! tap duration */ + uint16_t tap_dur : 3; + + /*! tap quiet */ + uint16_t tap_quiet : 1; + + /*! tap shock */ + uint16_t tap_shock : 1; + + /*! tap threshold */ + uint16_t tap_thr : 5; +#endif +}; +struct bmi160_acc_any_mot_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! 1 any-motion enable, 0 - any-motion disable */ + uint8_t anymotion_en : 1; + + /*! slope interrupt x, 1 - enable, 0 - disable */ + uint8_t anymotion_x : 1; + + /*! slope interrupt y, 1 - enable, 0 - disable */ + uint8_t anymotion_y : 1; + + /*! slope interrupt z, 1 - enable, 0 - disable */ + uint8_t anymotion_z : 1; + + /*! slope duration */ + uint8_t anymotion_dur : 2; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t anymotion_data_src : 1; + + /*! slope threshold */ + uint8_t anymotion_thr; +#else + + /*! slope threshold */ + uint8_t anymotion_thr; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t anymotion_data_src : 1; + + /*! slope duration */ + uint8_t anymotion_dur : 2; + + /*! slope interrupt z, 1 - enable, 0 - disable */ + uint8_t anymotion_z : 1; + + /*! slope interrupt y, 1 - enable, 0 - disable */ + uint8_t anymotion_y : 1; + + /*! slope interrupt x, 1 - enable, 0 - disable */ + uint8_t anymotion_x : 1; + + /*! 1 any-motion enable, 0 - any-motion disable */ + uint8_t anymotion_en : 1; +#endif +}; +struct bmi160_acc_sig_mot_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! skip time of sig-motion interrupt */ + uint8_t sig_mot_skip : 2; + + /*! proof time of sig-motion interrupt */ + uint8_t sig_mot_proof : 2; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t sig_data_src : 1; + + /*! 1 - enable sig, 0 - disable sig & enable anymotion */ + uint8_t sig_en : 1; + + /*! sig-motion threshold */ + uint8_t sig_mot_thres; +#else + + /*! sig-motion threshold */ + uint8_t sig_mot_thres; + + /*! 1 - enable sig, 0 - disable sig & enable anymotion */ + uint8_t sig_en : 1; + + /*! data source 0- filter & 1 pre-filter*/ + uint8_t sig_data_src : 1; + + /*! proof time of sig-motion interrupt */ + uint8_t sig_mot_proof : 2; + + /*! skip time of sig-motion interrupt */ + uint8_t sig_mot_skip : 2; +#endif +}; +struct bmi160_acc_step_detect_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! 1- step detector enable, 0- step detector disable */ + uint16_t step_detector_en : 1; + + /*! minimum threshold */ + uint16_t min_threshold : 2; + + /*! minimal detectable step time */ + uint16_t steptime_min : 3; + + /*! enable step counter mode setting */ + uint16_t step_detector_mode : 2; + + /*! minimum step buffer size*/ + uint16_t step_min_buf : 3; +#else + + /*! minimum step buffer size*/ + uint16_t step_min_buf : 3; + + /*! enable step counter mode setting */ + uint16_t step_detector_mode : 2; + + /*! minimal detectable step time */ + uint16_t steptime_min : 3; + + /*! minimum threshold */ + uint16_t min_threshold : 2; + + /*! 1- step detector enable, 0- step detector disable */ + uint16_t step_detector_en : 1; +#endif +}; +struct bmi160_acc_no_motion_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! no motion interrupt x */ + uint16_t no_motion_x : 1; + + /*! no motion interrupt y */ + uint16_t no_motion_y : 1; + + /*! no motion interrupt z */ + uint16_t no_motion_z : 1; + + /*! no motion duration */ + uint16_t no_motion_dur : 6; + + /*! no motion sel , 1 - enable no-motion ,0- enable slow-motion */ + uint16_t no_motion_sel : 1; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t no_motion_src : 1; + + /*! no motion threshold */ + uint8_t no_motion_thres; +#else + + /*! no motion threshold */ + uint8_t no_motion_thres; + + /*! data source 0- filter & 1 pre-filter*/ + uint16_t no_motion_src : 1; + + /*! no motion sel , 1 - enable no-motion ,0- enable slow-motion */ + uint16_t no_motion_sel : 1; + + /*! no motion duration */ + uint16_t no_motion_dur : 6; + + /* no motion interrupt z */ + uint16_t no_motion_z : 1; + + /*! no motion interrupt y */ + uint16_t no_motion_y : 1; + + /*! no motion interrupt x */ + uint16_t no_motion_x : 1; +#endif +}; +struct bmi160_acc_orient_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! thresholds for switching between the different orientations */ + uint16_t orient_mode : 2; + + /*! blocking_mode */ + uint16_t orient_blocking : 2; + + /*! Orientation interrupt hysteresis */ + uint16_t orient_hyst : 4; + + /*! Orientation interrupt theta */ + uint16_t orient_theta : 6; + + /*! Enable/disable Orientation interrupt */ + uint16_t orient_ud_en : 1; + + /*! exchange x- and z-axis in algorithm ,0 - z, 1 - x */ + uint16_t axes_ex : 1; + + /*! 1 - orient enable, 0 - orient disable */ + uint8_t orient_en : 1; +#else + + /*! 1 - orient enable, 0 - orient disable */ + uint8_t orient_en : 1; + + /*! exchange x- and z-axis in algorithm ,0 - z, 1 - x */ + uint16_t axes_ex : 1; + + /*! Enable/disable Orientation interrupt */ + uint16_t orient_ud_en : 1; + + /*! Orientation interrupt theta */ + uint16_t orient_theta : 6; + + /*! Orientation interrupt hysteresis */ + uint16_t orient_hyst : 4; + + /*! blocking_mode */ + uint16_t orient_blocking : 2; + + /*! thresholds for switching between the different orientations */ + uint16_t orient_mode : 2; +#endif +}; +struct bmi160_acc_flat_detect_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! flat threshold */ + uint16_t flat_theta : 6; + + /*! flat interrupt hysteresis */ + uint16_t flat_hy : 3; + + /*! delay time for which the flat value must remain stable for the + * flat interrupt to be generated */ + uint16_t flat_hold_time : 2; + + /*! 1 - flat enable, 0 - flat disable */ + uint16_t flat_en : 1; +#else + + /*! 1 - flat enable, 0 - flat disable */ + uint16_t flat_en : 1; + + /*! delay time for which the flat value must remain stable for the + * flat interrupt to be generated */ + uint16_t flat_hold_time : 2; + + /*! flat interrupt hysteresis */ + uint16_t flat_hy : 3; + + /*! flat threshold */ + uint16_t flat_theta : 6; +#endif +}; +struct bmi160_acc_low_g_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! low-g interrupt trigger delay */ + uint8_t low_dur; + + /*! low-g interrupt trigger threshold */ + uint8_t low_thres; + + /*! hysteresis of low-g interrupt */ + uint8_t low_hyst : 2; + + /*! 0 - single-axis mode ,1 - axis-summing mode */ + uint8_t low_mode : 1; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t low_data_src : 1; + + /*! 1 - enable low-g, 0 - disable low-g */ + uint8_t low_en : 1; +#else + + /*! 1 - enable low-g, 0 - disable low-g */ + uint8_t low_en : 1; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t low_data_src : 1; + + /*! 0 - single-axis mode ,1 - axis-summing mode */ + uint8_t low_mode : 1; + + /*! hysteresis of low-g interrupt */ + uint8_t low_hyst : 2; + + /*! low-g interrupt trigger threshold */ + uint8_t low_thres; + + /*! low-g interrupt trigger delay */ + uint8_t low_dur; +#endif +}; +struct bmi160_acc_high_g_int_cfg +{ +#ifdef LITTLE_ENDIAN + + /*! High-g interrupt x, 1 - enable, 0 - disable */ + uint8_t high_g_x : 1; + + /*! High-g interrupt y, 1 - enable, 0 - disable */ + uint8_t high_g_y : 1; + + /*! High-g interrupt z, 1 - enable, 0 - disable */ + uint8_t high_g_z : 1; + + /*! High-g hysteresis */ + uint8_t high_hy : 2; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t high_data_src : 1; + + /*! High-g threshold */ + uint8_t high_thres; + + /*! High-g duration */ + uint8_t high_dur; +#else + + /*! High-g duration */ + uint8_t high_dur; + + /*! High-g threshold */ + uint8_t high_thres; + + /*! data source 0- filter & 1 pre-filter */ + uint8_t high_data_src : 1; + + /*! High-g hysteresis */ + uint8_t high_hy : 2; + + /*! High-g interrupt z, 1 - enable, 0 - disable */ + uint8_t high_g_z : 1; + + /*! High-g interrupt y, 1 - enable, 0 - disable */ + uint8_t high_g_y : 1; + + /*! High-g interrupt x, 1 - enable, 0 - disable */ + uint8_t high_g_x : 1; +#endif +}; +struct bmi160_int_pin_settg +{ +#ifdef LITTLE_ENDIAN + + /*! To enable either INT1 or INT2 pin as output. + * 0- output disabled ,1- output enabled */ + uint16_t output_en : 1; + + /*! 0 - push-pull 1- open drain,only valid if output_en is set 1 */ + uint16_t output_mode : 1; + + /*! 0 - active low , 1 - active high level. + * if output_en is 1,this applies to interrupts,else PMU_trigger */ + uint16_t output_type : 1; + + /*! 0 - level trigger , 1 - edge trigger */ + uint16_t edge_ctrl : 1; + + /*! To enable either INT1 or INT2 pin as input. + * 0 - input disabled ,1 - input enabled */ + uint16_t input_en : 1; + + /*! latch duration*/ + uint16_t latch_dur : 4; +#else + + /*! latch duration*/ + uint16_t latch_dur : 4; + + /*! Latched,non-latched or temporary interrupt modes */ + uint16_t input_en : 1; + + /*! 1 - edge trigger, 0 - level trigger */ + uint16_t edge_ctrl : 1; + + /*! 0 - active low , 1 - active high level. + * if output_en is 1,this applies to interrupts,else PMU_trigger */ + uint16_t output_type : 1; + + /*! 0 - push-pull , 1 - open drain,only valid if output_en is set 1 */ + uint16_t output_mode : 1; + + /*! To enable either INT1 or INT2 pin as output. + * 0 - output disabled , 1 - output enabled */ + uint16_t output_en : 1; +#endif +}; +union bmi160_int_type_cfg +{ + /*! Tap interrupt structure */ + struct bmi160_acc_tap_int_cfg acc_tap_int; + + /*! Slope interrupt structure */ + struct bmi160_acc_any_mot_int_cfg acc_any_motion_int; + + /*! Significant motion interrupt structure */ + struct bmi160_acc_sig_mot_int_cfg acc_sig_motion_int; + + /*! Step detector interrupt structure */ + struct bmi160_acc_step_detect_int_cfg acc_step_detect_int; + + /*! No motion interrupt structure */ + struct bmi160_acc_no_motion_int_cfg acc_no_motion_int; + + /*! Orientation interrupt structure */ + struct bmi160_acc_orient_int_cfg acc_orient_int; + + /*! Flat interrupt structure */ + struct bmi160_acc_flat_detect_int_cfg acc_flat_int; + + /*! Low-g interrupt structure */ + struct bmi160_acc_low_g_int_cfg acc_low_g_int; + + /*! High-g interrupt structure */ + struct bmi160_acc_high_g_int_cfg acc_high_g_int; +}; +struct bmi160_int_settg +{ + /*! Interrupt channel */ + enum bmi160_int_channel int_channel; + + /*! Select Interrupt */ + enum bmi160_int_types int_type; + + /*! Structure configuring Interrupt pins */ + struct bmi160_int_pin_settg int_pin_settg; + + /*! Union configures required interrupt */ + union bmi160_int_type_cfg int_type_cfg; + + /*! FIFO FULL INT 1-enable, 0-disable */ + uint8_t fifo_full_int_en : 1; + + /*! FIFO WTM INT 1-enable, 0-disable */ + uint8_t fifo_wtm_int_en : 1; +}; + +/*! + * @brief This structure holds the information for usage of + * FIFO by the user. + */ +struct bmi160_fifo_frame +{ + /*! Data buffer of user defined length is to be mapped here */ + uint8_t *data; + + /*! While calling the API "bmi160_get_fifo_data" , length stores + * number of bytes in FIFO to be read (specified by user as input) + * and after execution of the API ,number of FIFO data bytes + * available is provided as an output to user + */ + uint16_t length; + + /*! FIFO time enable */ + uint8_t fifo_time_enable; + + /*! Enabling of the FIFO header to stream in header mode */ + uint8_t fifo_header_enable; + + /*! Streaming of the Accelerometer, Gyroscope + * sensor data or both in FIFO */ + uint8_t fifo_data_enable; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t accel_byte_start_idx; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t gyro_byte_start_idx; + + /*! Will be equal to length when no more frames are there to parse */ + uint16_t aux_byte_start_idx; + + /*! Value of FIFO sensor time time */ + uint32_t sensor_time; + + /*! Value of Skipped frame counts */ + uint8_t skipped_frame_count; +}; +struct bmi160_dev +{ + /*! Chip Id */ + uint8_t chip_id; + + /*! Device Id */ + uint8_t id; + + /*! 0 - I2C , 1 - SPI Interface */ + uint8_t intf; + + /*! Hold active interrupts status for any and sig motion + * 0 - Any-motion enable, 1 - Sig-motion enable, + * -1 neither any-motion nor sig-motion selected */ + enum bmi160_any_sig_motion_active_interrupt_state any_sig_sel; + + /*! Structure to configure Accel sensor */ + struct bmi160_cfg accel_cfg; + + /*! Structure to hold previous/old accel config parameters. + * This is used at driver level to prevent overwriting of same + * data, hence user does not change it in the code */ + struct bmi160_cfg prev_accel_cfg; + + /*! Structure to configure Gyro sensor */ + struct bmi160_cfg gyro_cfg; + + /*! Structure to hold previous/old gyro config parameters. + * This is used at driver level to prevent overwriting of same + * data, hence user does not change it in the code */ + struct bmi160_cfg prev_gyro_cfg; + + /*! Structure to configure the auxiliary sensor */ + struct bmi160_aux_cfg aux_cfg; + + /*! Structure to hold previous/old aux config parameters. + * This is used at driver level to prevent overwriting of same + * data, hence user does not change it in the code */ + struct bmi160_aux_cfg prev_aux_cfg; + + /*! FIFO related configurations */ + struct bmi160_fifo_frame *fifo; + + /*! Read function pointer */ + bmi160_read_fptr_t read; + + /*! Write function pointer */ + bmi160_write_fptr_t write; + + /*! Delay function pointer */ + bmi160_delay_fptr_t delay_ms; + + /*! User set read/write length */ + uint16_t read_write_len; +}; + +#endif /* BMI160_DEFS_H_ */ diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/Makefile b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/Makefile new file mode 100644 index 00000000000..41bff4e5f42 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/Makefile @@ -0,0 +1,13 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= read_chip_id.c + +API_LOCATION ?= ../.. + +C_SRCS += \ +$(API_LOCATION)/bmi160.c + +INCLUDEPATHS += \ +$(API_LOCATION) + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/read_chip_id.c b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/read_chip_id.c new file mode 100644 index 00000000000..29207e17895 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_chip_id/read_chip_id.c @@ -0,0 +1,237 @@ +/** + * Copyright (C) 2021 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************/ +/* system header files */ +/*********************************************************************/ +#include +#include +#include + +/*********************************************************************/ +/* own header files */ +/*********************************************************************/ +#include "coines.h" +#include "bmi160.h" + +/*********************************************************************/ +/* local macro definitions */ +/*! i2c interface communication, 1 - Enable; 0- Disable */ +#define BMI160_INTERFACE_I2C 1 + +/*! spi interface communication, 1 - Enable; 0- Disable */ +#define BMI160_INTERFACE_SPI 0 + +#if (!((BMI160_INTERFACE_I2C == 1) && (BMI160_INTERFACE_SPI == 0)) && \ + (!((BMI160_INTERFACE_I2C == 0) && (BMI160_INTERFACE_SPI == 1)))) +#error "Invalid value given for the macros BMI160_INTERFACE_I2C / BMI160_INTERFACE_SPI" +#endif + +/*! bmi160 shuttle id */ +#define BMI160_SHUTTLE_ID 0x38 + +/*! bmi160 Device address */ +#define BMI160_DEV_ADDR BMI160_I2C_ADDR + +/*********************************************************************/ +/* global variables */ +/*********************************************************************/ + +/*! @brief This structure containing relevant bmi160 info */ +struct bmi160_dev bmi160dev; + +/*! @brief variable to hold the bmi160 accel data */ +struct bmi160_sensor_data bmi160_accel; + +/*! @brief variable to hold the bmi160 gyro data */ +struct bmi160_sensor_data bmi160_gyro; + +/*********************************************************************/ +/* static function declarations */ +/*********************************************************************/ + +/*! + * @brief internal API is used to initialize the sensor interface + */ +static void init_sensor_interface(void); + +/*! + * @brief This internal API is used to initialize the bmi160 sensor with default + */ +static void init_bmi160(void); + +/*! + * @brief This internal API is used to initialize the sensor driver interface + */ +static void init_bmi160_sensor_driver_interface(void); + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief This internal API is used to initialize the sensor interface depending + * on selection either SPI or I2C. + * + * @param[in] void + * + * @return void + * + */ +static void init_sensor_interface(void) +{ + /* Switch VDD for sensor off */ + coines_set_shuttleboard_vdd_vddio_config(0, 0); + + /* wait until the sensor goes off */ + coines_delay_msec(10); +#if BMI160_INTERFACE_I2C == 1 + + /* SDO pin is made low for selecting I2C address 0x68 */ + coines_set_pin_config(COINES_SHUTTLE_PIN_15, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* set the sensor interface as I2C */ + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + coines_delay_msec(10); + + /* CSB pin is made high for selecting I2C protocol*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); +#endif +#if BMI160_INTERFACE_SPI == 1 + + /* CSB pin is made low for selecting SPI protocol*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + coines_delay_msec(10); + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); +#endif + coines_delay_msec(10); + + /* Switch VDD for sensor on */ + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + +#if BMI160_INTERFACE_SPI == 1 + coines_delay_msec(10); + + /* CSB pin is made high for selecting SPI protocol + * Note: CSB has to see rising after power up, to switch to SPI protocol */ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); +#endif +} + +/*! + * @brief This internal API is used to initializes the bmi160 sensor + * settings like power mode and OSRS settings. + * + * @param[in] void + * + * @return void + * + */ +static void init_bmi160(void) +{ + int8_t rslt; + + rslt = bmi160_init(&bmi160dev); + + if (rslt == BMI160_OK) + { + printf("BMI160 initialization success !\n"); + printf("Chip ID 0x%X\n", bmi160dev.chip_id); + } + else + { + printf("BMI160 initialization failure !\n"); + exit(COINES_E_FAILURE); + } +} + +/*! + * @brief This internal API is used to set the sensor driver interface to + * read/write the data. + * + * @param[in] void + * + * @return void + * + */ +static void init_bmi160_sensor_driver_interface(void) +{ +#if BMI160_INTERFACE_I2C == 1 + + /* I2C setup */ + + /* link read/write/delay function of host system to appropriate + * bmi160 function call prototypes */ + bmi160dev.write = coines_write_i2c; + bmi160dev.read = coines_read_i2c; + bmi160dev.delay_ms = coines_delay_msec; + + /* set correct i2c address */ + bmi160dev.id = BMI160_DEV_ADDR; + bmi160dev.intf = BMI160_I2C_INTF; +#endif +#if BMI160_INTERFACE_SPI == 1 + + /* SPI setup */ + + /* link read/write/delay function of host system to appropriate + * bmi160 function call prototypes */ + bmi160dev.write = coines_write_spi; + bmi160dev.read = coines_read_spi; + bmi160dev.delay_ms = coines_delay_msec; + bmi160dev.id = COINES_SHUTTLE_PIN_7; + bmi160dev.intf = BMI160_SPI_INTF; +#endif +} + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(int argc, char *argv[]) +{ + struct coines_board_info board_info; + int16_t rslt; + + init_bmi160_sensor_driver_interface(); + + rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); + + if (rslt < 0) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(rslt); + } + + rslt = coines_get_board_info(&board_info); + + if (rslt == COINES_SUCCESS) + { + if (board_info.shuttle_id != BMI160_SHUTTLE_ID) + { + + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + init_sensor_interface(); + + /* After sensor init introduce 200 msec sleep */ + coines_delay_msec(200); + init_bmi160(); + coines_close_comm_intf(COINES_COMM_INTF_USB); + + return EXIT_SUCCESS; +} diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/Makefile b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/Makefile new file mode 100644 index 00000000000..fdf2597ab92 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/Makefile @@ -0,0 +1,13 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= read_sensor_data.c + +API_LOCATION ?= ../.. + +C_SRCS += \ +$(API_LOCATION)/bmi160.c + +INCLUDEPATHS += \ +$(API_LOCATION) + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/read_sensor_data.c b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/read_sensor_data.c new file mode 100644 index 00000000000..7462e0fd0d7 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/examples/read_sensor_data/read_sensor_data.c @@ -0,0 +1,271 @@ +/** + * Copyright (C) 2021 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************/ +/* system header files */ +/*********************************************************************/ +#include +#include +#include + +/*********************************************************************/ +/* own header files */ +/*********************************************************************/ +#include "coines.h" +#include "bmi160.h" + +/*********************************************************************/ +/* local macro definitions */ +/*! I2C interface communication, 1 - Enable; 0- Disable */ +#define BMI160_INTERFACE_I2C 1 + +/*! SPI interface communication, 1 - Enable; 0- Disable */ +#define BMI160_INTERFACE_SPI 0 + +#if (!((BMI160_INTERFACE_I2C == 1) && (BMI160_INTERFACE_SPI == 0)) && \ + (!((BMI160_INTERFACE_I2C == 0) && (BMI160_INTERFACE_SPI == 1)))) +#error "Invalid value given for the macros BMI160_INTERFACE_I2C / BMI160_INTERFACE_SPI" +#endif + +/*! bmi160 shuttle id */ +#define BMI160_SHUTTLE_ID 0x38 + +/*! bmi160 Device address */ +#define BMI160_DEV_ADDR BMI160_I2C_ADDR + +/*********************************************************************/ +/* global variables */ +/*********************************************************************/ + +/*! @brief This structure containing relevant bmi160 info */ +struct bmi160_dev bmi160dev; + +/*! @brief variable to hold the bmi160 accel data */ +struct bmi160_sensor_data bmi160_accel; + +/*! @brief variable to hold the bmi160 gyro data */ +struct bmi160_sensor_data bmi160_gyro; + +/*********************************************************************/ +/* static function declarations */ +/*********************************************************************/ + +/*! + * @brief internal API is used to initialize the sensor interface + */ +static void init_sensor_interface(void); + +/*! + * @brief This internal API is used to initialize the bmi160 sensor with default + */ +static void init_bmi160(void); + +/*! + * @brief This internal API is used to initialize the sensor driver interface + */ +static void init_bmi160_sensor_driver_interface(void); + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief This internal API is used to initialize the sensor interface depending + * on selection either SPI or I2C. + * + * @param[in] void + * + * @return void + * + */ +static void init_sensor_interface(void) +{ + /* Switch VDD for sensor off */ + coines_set_shuttleboard_vdd_vddio_config(0, 0); + + /* wait until the sensor goes off */ + coines_delay_msec(10); +#if BMI160_INTERFACE_I2C == 1 + + /* SDO pin is made low for selecting I2C address 0x68 */ + coines_set_pin_config(COINES_SHUTTLE_PIN_15, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* set the sensor interface as I2C */ + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + coines_delay_msec(10); + + /* CSB pin is made high for selecting I2C protocol*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); +#endif +#if BMI160_INTERFACE_SPI == 1 + + /* CSB pin is made low for selecting SPI protocol*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + coines_delay_msec(10); + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); +#endif + coines_delay_msec(10); + + /* Switch VDD for sensor on */ + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + +#if BMI160_INTERFACE_SPI == 1 + coines_delay_msec(10); + + /* CSB pin is made high for selecting SPI protocol + * Note: CSB has to see rising after power up, to switch to SPI protocol */ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); +#endif +} + +/*! + * @brief This internal API is used to initializes the bmi160 sensor + * settings like power mode and OSRS settings. + * + * @param[in] void + * + * @return void + * + */ +static void init_bmi160(void) +{ + int8_t rslt; + + rslt = bmi160_init(&bmi160dev); + + if (rslt == BMI160_OK) + { + printf("BMI160 initialization success !\n"); + printf("Chip ID 0x%X\n", bmi160dev.chip_id); + } + else + { + printf("BMI160 initialization failure !\n"); + exit(COINES_E_FAILURE); + } + + /* Select the Output data rate, range of accelerometer sensor */ + bmi160dev.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ; + bmi160dev.accel_cfg.range = BMI160_ACCEL_RANGE_16G; + bmi160dev.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; + + /* Select the power mode of accelerometer sensor */ + bmi160dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; + + /* Select the Output data rate, range of Gyroscope sensor */ + bmi160dev.gyro_cfg.odr = BMI160_GYRO_ODR_3200HZ; + bmi160dev.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; + bmi160dev.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; + + /* Select the power mode of Gyroscope sensor */ + bmi160dev.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; + + /* Set the sensor configuration */ + rslt = bmi160_set_sens_conf(&bmi160dev); +} + +/*! + * @brief This internal API is used to set the sensor driver interface to + * read/write the data. + * + * @param[in] void + * + * @return void + * + */ +static void init_bmi160_sensor_driver_interface(void) +{ +#if BMI160_INTERFACE_I2C == 1 + + /* I2C setup */ + + /* link read/write/delay function of host system to appropriate + * bmi160 function call prototypes */ + bmi160dev.write = coines_write_i2c; + bmi160dev.read = coines_read_i2c; + bmi160dev.delay_ms = coines_delay_msec; + + /* set correct i2c address */ + bmi160dev.id = BMI160_DEV_ADDR; + bmi160dev.intf = BMI160_I2C_INTF; +#endif +#if BMI160_INTERFACE_SPI == 1 + + /* SPI setup */ + + /* link read/write/delay function of host system to appropriate + * bmi160 function call prototypes */ + bmi160dev.write = coines_write_spi; + bmi160dev.read = coines_read_spi; + bmi160dev.delay_ms = coines_delay_msec; + bmi160dev.id = COINES_SHUTTLE_PIN_7; + bmi160dev.intf = BMI160_SPI_INTF; +#endif +} + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(int argc, char *argv[]) +{ + struct coines_board_info board_info; + int16_t rslt; + int times_to_read = 0; + + init_bmi160_sensor_driver_interface(); + + rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); + + if (rslt < 0) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(rslt); + } + + rslt = coines_get_board_info(&board_info); + + if (rslt == COINES_SUCCESS) + { + if (board_info.shuttle_id != BMI160_SHUTTLE_ID) + { + + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + init_sensor_interface(); + + /* After sensor init introduce 200 msec sleep */ + coines_delay_msec(200); + init_bmi160(); + + while (times_to_read < 100) + { + /* To read both Accel and Gyro data */ + bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &bmi160_accel, &bmi160_gyro, &bmi160dev); + + printf("ax:%d\tay:%d\taz:%d\n", bmi160_accel.x, bmi160_accel.y, bmi160_accel.z); + printf("gx:%d\tgy:%d\tgz:%d\n", bmi160_gyro.x, bmi160_gyro.y, bmi160_gyro.z); + fflush(stdout); + + coines_delay_msec(10); + times_to_read = times_to_read + 1; + } + + coines_close_comm_intf(COINES_COMM_INTF_USB); + + return EXIT_SUCCESS; +} diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/Makefile b/non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/Makefile new file mode 100644 index 00000000000..40583362684 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/Makefile @@ -0,0 +1,13 @@ +COINES_INSTALL_PATH ?= ../../../.. + +EXAMPLE_FILE ?= tap.c + +API_LOCATION ?= ../.. + +C_SRCS += \ +$(API_LOCATION)/bmi160.c + +INCLUDEPATHS += \ +$(API_LOCATION) + +include $(COINES_INSTALL_PATH)/coines.mk \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/tap.c b/non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/tap.c new file mode 100644 index 00000000000..b8ea2d006b4 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/bmi160-api/examples/tap/tap.c @@ -0,0 +1,366 @@ +/** + * Copyright (C) 2021 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************/ +/* system header files */ +/*********************************************************************/ +#include +#include +#include + +/*********************************************************************/ +/* own header files */ +/*********************************************************************/ +#include "coines.h" +#include "bmi160.h" + +/*********************************************************************/ +/* local macro definitions */ +/*! i2c interface communication, 1 - Enable; 0- Disable */ +#define BMI160_INTERFACE_I2C 0 + +/*! spi interface communication, 1 - Enable; 0- Disable */ +#define BMI160_INTERFACE_SPI 1 + +#if (!((BMI160_INTERFACE_I2C == 1) && (BMI160_INTERFACE_SPI == 0)) && \ + (!((BMI160_INTERFACE_I2C == 0) && (BMI160_INTERFACE_SPI == 1)))) +#error "Invalid value given for the macros BMI160_INTERFACE_I2C / BMI160_INTERFACE_SPI" +#endif + +/*! bmi160 shuttle id */ +#define BMI160_SHUTTLE_ID 0x38 + +/*! bmi160 Device address */ +#define BMI160_DEV_ADDR BMI160_I2C_ADDR + +/*********************************************************************/ +/* global variables */ +/*********************************************************************/ + +/*! @brief This structure containing relevant bmi160 info */ +struct bmi160_dev bmi160dev; + +/*! @brief variable to hold the bmi160 accel data */ +struct bmi160_sensor_data bmi160_accel; + +/*! @brief variable to hold the bmi160 gyro data */ +struct bmi160_sensor_data bmi160_gyro; + +/*********************************************************************/ +/* static function declarations */ +/*********************************************************************/ + +/*! + * @brief internal API is used to initialize the sensor interface + */ +static void init_sensor_interface(void); + +/*! + * @brief This internal API is used to initialize the bmi160 sensor with default + */ +static void init_bmi160(void); + +/*! + * @brief This internal API is used to initialize the sensor driver interface + */ +static void init_bmi160_sensor_driver_interface(void); + +/*! + * @brief This internal API is used to set tap configurations + */ +static int8_t set_tap_config(uint8_t feature_enable); + +/*********************************************************************/ +/* functions */ +/*********************************************************************/ + +/*! + * @brief This internal API is used to initialize the sensor interface depending + * on selection either SPI or I2C. + * + * @param[in] void + * + * @return void + * + */ +static void init_sensor_interface(void) +{ + /* Switch VDD for sensor off */ + coines_set_shuttleboard_vdd_vddio_config(0, 0); + + /* wait until the sensor goes off */ + coines_delay_msec(10); +#if BMI160_INTERFACE_I2C == 1 + + /* SDO pin is made low for selecting I2C address 0x68 */ + coines_set_pin_config(COINES_SHUTTLE_PIN_15, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + /* set the sensor interface as I2C */ + coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_FAST_MODE); + coines_delay_msec(10); + + /* CSB pin is made high for selecting I2C protocol*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); +#endif +#if BMI160_INTERFACE_SPI == 1 + + /* CSB pin is made low for selecting SPI protocol*/ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW); + + coines_delay_msec(10); + coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_5_MHZ, COINES_SPI_MODE3); +#endif + coines_delay_msec(10); + + /* Switch VDD for sensor on */ + coines_set_shuttleboard_vdd_vddio_config(3300, 3300); + +#if BMI160_INTERFACE_SPI == 1 + coines_delay_msec(10); + + /* CSB pin is made high for selecting SPI protocol + * Note: CSB has to see rising after power up, to switch to SPI protocol */ + coines_set_pin_config(COINES_SHUTTLE_PIN_7, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH); +#endif +} + +/*! + * @brief This internal API is used to initializes the bmi160 sensor + * settings like power mode and OSRS settings. + * + * @param[in] void + * + * @return void + * + */ +static void init_bmi160(void) +{ + int8_t rslt; + + rslt = bmi160_init(&bmi160dev); + + if (rslt == BMI160_OK) + { + printf("BMI160 initialization success !\n"); + printf("Chip ID 0x%X\n", bmi160dev.chip_id); + } + else + { + printf("BMI160 initialization failure !\n"); + exit(COINES_E_FAILURE); + } + + /* Select the Output data rate, range of accelerometer sensor */ + bmi160dev.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ; + bmi160dev.accel_cfg.range = BMI160_ACCEL_RANGE_8G; + bmi160dev.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; + + /* Select the power mode of accelerometer sensor */ + bmi160dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; + + /* Set the sensor configuration */ + rslt = bmi160_set_sens_conf(&bmi160dev); +} + +/*! + * @brief This internal API is used to set the sensor driver interface to + * read/write the data. + * + * @param[in] void + * + * @return void + * + */ +static void init_bmi160_sensor_driver_interface(void) +{ +#if BMI160_INTERFACE_I2C == 1 + + /* I2C setup */ + + /* link read/write/delay function of host system to appropriate + * bmi160 function call prototypes */ + bmi160dev.write = coines_write_i2c; + bmi160dev.read = coines_read_i2c; + bmi160dev.delay_ms = coines_delay_msec; + + /* set correct i2c address */ + bmi160dev.id = BMI160_DEV_ADDR; + bmi160dev.intf = BMI160_I2C_INTF; +#endif +#if BMI160_INTERFACE_SPI == 1 + + /* SPI setup */ + + /* link read/write/delay function of host system to appropriate + * bmi160 function call prototypes */ + bmi160dev.write = coines_write_spi; + bmi160dev.read = coines_read_spi; + bmi160dev.delay_ms = coines_delay_msec; + bmi160dev.id = COINES_SHUTTLE_PIN_7; + bmi160dev.intf = BMI160_SPI_INTF; +#endif +} + +/*! + * @brief Main Function where the execution getting started to test the code. + * + * @param[in] argc + * @param[in] argv + * + * @return status + * + */ +int main(int argc, char *argv[]) +{ + struct coines_board_info board_info; + int16_t rslt; + + init_bmi160_sensor_driver_interface(); + + rslt = coines_open_comm_intf(COINES_COMM_INTF_USB); + + if (rslt < 0) + { + printf( + "\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n" + " 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n"); + exit(rslt); + } + + rslt = coines_get_board_info(&board_info); + + if (rslt == COINES_SUCCESS) + { + if (board_info.shuttle_id != BMI160_SHUTTLE_ID) + { + + printf("! Warning invalid sensor shuttle \n ," "This application will not support this sensor \n"); + exit(COINES_E_FAILURE); + } + } + + init_sensor_interface(); + + /* after sensor init introduce 200 msec sleep */ + coines_delay_msec(200); + init_bmi160(); + + rslt = set_tap_config(BMI160_ENABLE); + if (rslt == BMI160_OK) + { + union bmi160_int_status int_status; + uint8_t loop = 0; + uint32_t last_time = 0; + uint32_t current_time = 0; + + printf("Do Single or Double Tap the board\n"); + fflush(stdout); + + memset(int_status.data, 0x00, sizeof(int_status.data)); + + while (loop < 10) + { + /* Read interrupt status */ + rslt = bmi160_get_int_status(BMI160_INT_STATUS_ALL, &int_status, &bmi160dev); + current_time = coines_get_millis(); + + /* Enters only if the obtained interrupt is single-tap */ + if (rslt == BMI160_OK) + { + /* Enters only if the obtained interrupt is single-tap */ + if (int_status.bit.s_tap) + { + printf("Single tap, iter:%d, time:%d ms, delta:%d ms, int_status:0x%x\n", + loop++, + current_time, + current_time - last_time, + int_status.data[0]); + } + /* Enters only if the obtained interrupt is double-tap */ + else if (int_status.bit.d_tap) + { + printf("Double tap, iter:%d, time:%d ms, delta:%d ms, int_status:0x%x\n", + loop++, + current_time, + current_time - last_time, + int_status.data[0]); + } + + fflush(stdout); + } + else + { + break; + } + + memset(int_status.data, 0x00, sizeof(int_status.data)); + last_time = current_time; + } + + /* Disable tap feature */ + printf("\nDisable tap test...\n"); + rslt = set_tap_config(BMI160_DISABLE); + printf("bmi160_set_int_config(tap enable) status:%d\n", rslt); + + fflush(stdout); + } + + coines_close_comm_intf(COINES_COMM_INTF_USB); + + return EXIT_SUCCESS; +} + +static int8_t set_tap_config(uint8_t feature_enable) +{ + int8_t rslt = BMI160_OK; + struct bmi160_int_settg int_config; + + if (feature_enable > 0) + { + /* Select the Interrupt channel/pin */ + int_config.int_channel = BMI160_INT_CHANNEL_1; /* Interrupt channel/pin 1 */ + + /* Select the interrupt channel/pin settings */ + int_config.int_pin_settg.output_en = BMI160_ENABLE; /* Enabling interrupt pins to act as output pin */ + int_config.int_pin_settg.output_mode = BMI160_DISABLE; /* Choosing push-pull mode for interrupt pin */ + int_config.int_pin_settg.output_type = BMI160_ENABLE; /* Choosing active low output */ + int_config.int_pin_settg.edge_ctrl = BMI160_DISABLE; /* Choosing edge triggered output */ + int_config.int_pin_settg.input_en = BMI160_DISABLE; /* Disabling interrupt pin to act as input */ + int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE; /* non-latched output */ + + /* Select the Interrupt type */ + int_config.int_type = BMI160_ACC_SINGLE_TAP_INT; /* Choosing tap interrupt */ + + /* Select the Any-motion interrupt parameters */ + int_config.int_type_cfg.acc_tap_int.tap_en = BMI160_ENABLE; /* 1- Enable tap, 0- disable tap */ + int_config.int_type_cfg.acc_tap_int.tap_thr = 2; /* Set tap threshold */ + int_config.int_type_cfg.acc_tap_int.tap_dur = 2; /* Set tap duration */ + int_config.int_type_cfg.acc_tap_int.tap_shock = 0; /* Set tap shock value */ + int_config.int_type_cfg.acc_tap_int.tap_quiet = 0; /* Set tap quiet duration */ + int_config.int_type_cfg.acc_tap_int.tap_data_src = 1; /* data source 0 : filter or 1 : pre-filter */ + + /* Set the Any-motion interrupt */ + rslt = bmi160_set_int_config(&int_config, &bmi160dev); /* sensor is an instance of the structure bmi160_dev */ + printf("bmi160_set_int_config(tap enable) status:%d\n", rslt); + } + else + { + /* Select the Interrupt channel/pin */ + int_config.int_channel = BMI160_INT_CHANNEL_1; + int_config.int_pin_settg.output_en = BMI160_DISABLE; /* Disabling interrupt pins to act as output pin */ + int_config.int_pin_settg.edge_ctrl = BMI160_DISABLE; /* Choosing edge triggered output */ + + /* Select the Interrupt type */ + int_config.int_type = BMI160_ACC_SINGLE_TAP_INT; /* Choosing Tap interrupt */ + int_config.int_type_cfg.acc_tap_int.tap_en = BMI160_DISABLE; /* 1- Enable tap, 0- disable tap */ + + /* Set the Data ready interrupt */ + rslt = bmi160_set_int_config(&int_config, &bmi160dev); /* sensor is an instance of the structure bmi160_dev */ + printf("bmi160_set_int_config(tap disable) status:%d\n", rslt); + } + + return rslt; +} diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/.gitsubtree b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/.gitsubtree new file mode 100644 index 00000000000..9e0d9a43f52 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/.gitsubtree @@ -0,0 +1 @@ +https://github.com/STMicroelectronics/lsm6ds3tr-c-pid master / diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/CONTRIBUTING.md b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/CONTRIBUTING.md new file mode 100644 index 00000000000..bb7d8a3b89c --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/CONTRIBUTING.md @@ -0,0 +1,33 @@ +## Contributing guide +This document serves as a checklist before contributing to this repository. It includes links to additional information if topics are unclear to you. + +This guide mainly focuses on the proper use of Git. + +### 1. Before opening an issue +To report a bug/request please enter the issue in the right repository. + +Please check the following boxes before posting an issue: +- [ ] `Make sure you are using the latest commit (major releases are Tagged, but corrections are available as new commits).` +- [ ] `Make sure your issue is a question/feedback/suggestion RELATED TO the software provided in this repository.` Otherwise, it should be discussed on the [ST Community forum](https://community.st.com/s/). +- [ ] `Make sure your issue is not already reported/fixed on GitHub or discussed in a previous issue.` Please refer to the tab issue for the list of issues and pull-requests. Do not forget to browse to the **closed** issues. + +### 2. Posting the issue +When you have checked the previous boxes, you will find two templates (Bug Report or Other Issue) available in the **Issues** tab of the repository. + +### 3. Pull Requests +STMicroelectronics is happy to receive contributions from the community, based on an initial Contributor License Agreement (CLA) procedure. + +* If you are an individual writing original source code and you are sure **you own the intellectual property**, then you need to sign an Individual CLA (https://cla.st.com). +* If you work for a company that wants also to allow you to contribute with your work, your company needs to provide a Corporate CLA (https://cla.st.com) mentioning your GitHub account name. +* If you are not sure that a CLA (Individual or Corporate) has been signed for your GitHub account, you can check here (https://cla.st.com). + +Please note that: +* The Corporate CLA will always take precedence over the Individual CLA. +* One CLA submission is sufficient for any project proposed by STMicroelectronics. + +#### How to proceed + +* We recommend to engage first a communication through an issue, in order to present your proposal and just to confirm that it corresponds to a STMicroelectronics domain or scope. +* Then fork the project to your GitHub account to further develop your contribution. Please use the latest commit version. +* Please submit one Pull Request for one new feature or proposal. This will facilitate the analysis and the final merge if accepted. + diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/LICENSE b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/LICENSE new file mode 100644 index 00000000000..bc7d5adf95c --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2019, STMicroelectronics +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/README.md b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/README.md new file mode 100644 index 00000000000..7eeb9f90a4e --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/README.md @@ -0,0 +1,59 @@ +# 1 - Introduction + +Sensor driver for LSM6DS3TR-C sensor written in C programming language. This repository contains the sensor driver files (.h and .c) to be included, or linked directly as a git submodule, in your project. The driver is MISRA compliant and the documentation can be generated using the [Doxygen](http://www.doxygen.org/) tool. + +In order to `clone` the complete content of the repository folder, use the command: + +``` +git clone https://github.com/STMicroelectronics/LSM6DS3TR-C-PID/ +``` + +Some examples of driver usage can be found [here](https://github.com/STMicroelectronics/STMems_Standard_C_drivers). + +------ + + + +# 2 - Integration details + +The driver is platform-independent, you only need to define two functions for read and write transactions from the sensor hardware bus (ie. SPI or I²C). **A few devices integrate an extra bit in the communication protocol in order to enable multi read/write access, this bit must be managed in the read and write functions defined by the user.** Please refer to the read and write implementation in the [reference examples](https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lsm6ds3tr-c_STdC/examples). + + + +### 2.a Source code integration + +- Include in your project the driver files of the sensor (.h and .c) +- Define in your code the read and write functions that use the I²C or SPI platform driver like the following: + +``` +/** Please note that is MANDATORY: return 0 -> no Error.**/ +int32_t platform_write(void *handle, uint8_t Reg, const uint8_t *Bufp, uint16_t len) +int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len) +``` + +- Declare and initialize the structure of the device interface: + +``` +xxxxxxx_ctx_t dev_ctx; /** xxxxxxx is the used part number **/ +dev_ctx.write_reg = platform_write; +dev_ctx.read_reg = platform_read; +``` + +- If needed by the platform read and write functions, initialize the handle parameter: + +``` +dev_ctx.handle = &platform_handle; +``` + +Some integration examples can be found [here](https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lsm6ds3tr-c_STdC/examples). + +### 2.b Required properties + +> - A standard C language compiler for the target MCU +> - A C library for the target MCU and the desired interface (ie. SPI, I²C) + +------ + +**More Information: [http://www.st.com](http://st.com/MEMS)** + +**Copyright (C) 2021 STMicroelectronics** \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.html b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.html new file mode 100644 index 00000000000..72c4911e392 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.html @@ -0,0 +1,82 @@ + + + + + + + Release Notes for LSM6DS3TR-C Component + + + + + + +
+
+
+

Release Notes for LSM6DS3TR-C Component Driver

+

Copyright © 2021 STMicroelectronics
+

+ +
+

License

+

This software component is licensed by ST under BSD 3-Clause license, the “License”. You may not use this component except in compliance with the License. You may obtain a copy of the License at:

+

BSD 3-Clause license

+

Purpose

+

This directory contains the LSM6DS3TR-C component drivers.

+
+
+

Update history

+
+ +
+

Main changes

+

First release

+
    +
  • First official release [ref. DS v3.0]
  • +
+

+
+ +
+

Main changes

+
    +
  • Add __weak directive to read/write registers routines
  • +
  • Extend stmdev_ctx_t structure with mdelay callback
  • +
  • repo name changed adding ‘-pid’ extension
  • +
+

+
+ +
+

Main changes

+
    +
  • Fixed code style (Artistic Style Version 3.4.13)
  • +
  • Add “const” to ctx arg for all APIs
  • +
+

+
+
+
+
+
+
+
+

For complete documentation on LSM6DS3TR-C, visit: LSM6DS3TR-C

+
+

Info

+
+
+
+ + diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.md b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.md new file mode 100644 index 00000000000..7f6e0595946 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/Release_Notes.md @@ -0,0 +1,89 @@ +--- +pagetitle: Release Notes for LSM6DS3TR-C Component +lang: en +header-includes: +--- + +::: {.row} +::: {.col-sm-12 .col-lg-4} + +
+# Release Notes for LSM6DS3TR-C Component Driver +Copyright © 2021 STMicroelectronics\ + +[![ST logo](_htmresc/st_logo_2020.png)](https://www.st.com){.logo} +
+ +# License + +This software component is licensed by ST under BSD 3-Clause license, the "License". +You may not use this component except in compliance with the License. You may obtain a copy of the License at: + +[BSD 3-Clause license](https://opensource.org/licenses/BSD-3-Clause) + +# Purpose + +This directory contains the LSM6DS3TR-C component drivers. +::: + +::: {.col-sm-12 .col-lg-8} +# Update history + +::: {.collapse} + + +
+ +## Main changes + +### First release + +- First official release [ref. DS v3.0] + +## + +
+ + + +
+ +## Main changes + +- Add __weak directive to read/write registers routines +- Extend stmdev_ctx_t structure with mdelay callback +- repo name changed adding '-pid' extension + +## + +
+ + + +
+ +## Main changes + +- Fixed code style (Artistic Style Version 3.4.13) +- Add "const" to ctx arg for all APIs + +## + +
+::: + +::: +::: + +
+::: {.columns} +::: {.column width="95%"} +For complete documentation on LSM6DS3TR-C, +visit: +[LSM6DS3TR-C](https://www.st.com/content/st_com/en/products/mems-and-sensors/inemo-inertial-modules/lsm6ds3tr-c.html) +::: +::: {.column width="5%"} +Info +::: +::: +
diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/favicon.png b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/mini-st_2020.css b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/mini-st_2020.css new file mode 100644 index 00000000000..986f4d42050 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/st_logo_2020.png b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/_htmresc/st_logo_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.c b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.c new file mode 100644 index 00000000000..6bc987f60cd --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.c @@ -0,0 +1,8219 @@ +/** + ****************************************************************************** + * @file lsm6ds3tr_c_reg.c + * @author Sensors Software Solution Team + * @brief LSM6DS3TR_C driver file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include "lsm6ds3tr-c_reg.h" + +/** + * @defgroup LSM6DS3TR_C + * @brief This file provides a set of functions needed to drive the + * lsm6ds3tr_c enanced inertial module. + * @{ + * + */ + +/** + * @defgroup LSM6DS3TR_C_interfaces_functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +/** + * @brief Read generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to read + * @param data pointer to buffer that store the data read(ptr) + * @param len number of consecutive register to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t __weak lsm6ds3tr_c_read_reg(const stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len) +{ + int32_t ret; + + if (ctx == NULL) + { + return -1; + } + + ret = ctx->read_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @brief Write generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to write + * @param data pointer to data to write in register reg(ptr) + * @param len number of consecutive register to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t __weak lsm6ds3tr_c_write_reg(const stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len) +{ + int32_t ret; + + if (ctx == NULL) + { + return -1; + } + + ret = ctx->write_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Sensitivity + * @brief These functions convert raw-data into engineering units. + * @{ + * + */ + +float_t lsm6ds3tr_c_from_fs2g_to_mg(int16_t lsb) +{ + return ((float_t)lsb * 0.061f); +} + +float_t lsm6ds3tr_c_from_fs4g_to_mg(int16_t lsb) +{ + return ((float_t)lsb * 0.122f); +} + +float_t lsm6ds3tr_c_from_fs8g_to_mg(int16_t lsb) +{ + return ((float_t)lsb * 0.244f); +} + +float_t lsm6ds3tr_c_from_fs16g_to_mg(int16_t lsb) +{ + return ((float_t)lsb * 0.488f); +} + +float_t lsm6ds3tr_c_from_fs125dps_to_mdps(int16_t lsb) +{ + return ((float_t)lsb * 4.375f); +} + +float_t lsm6ds3tr_c_from_fs250dps_to_mdps(int16_t lsb) +{ + return ((float_t)lsb * 8.750f); +} + +float_t lsm6ds3tr_c_from_fs500dps_to_mdps(int16_t lsb) +{ + return ((float_t)lsb * 17.50f); +} + +float_t lsm6ds3tr_c_from_fs1000dps_to_mdps(int16_t lsb) +{ + return ((float_t)lsb * 35.0f); +} + +float_t lsm6ds3tr_c_from_fs2000dps_to_mdps(int16_t lsb) +{ + return ((float_t)lsb * 70.0f); +} + +float_t lsm6ds3tr_c_from_lsb_to_celsius(int16_t lsb) +{ + return (((float_t)lsb / 256.0f) + 25.0f); +} + +/** + * @} + * + */ + + +/** + * @defgroup LSM6DS3TR_C_data_generation + * @brief This section groups all the functions concerning data + * generation + * @{ + * + */ + +/** + * @brief Accelerometer full-scale selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fs_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_full_scale_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_xl_t val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + if (ret == 0) + { + ctrl1_xl.fs_xl = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + } + + return ret; +} + +/** + * @brief Accelerometer full-scale selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of fs_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_full_scale_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_xl_t *val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + switch (ctrl1_xl.fs_xl) + { + case LSM6DS3TR_C_2g: + *val = LSM6DS3TR_C_2g; + break; + + case LSM6DS3TR_C_16g: + *val = LSM6DS3TR_C_16g; + break; + + case LSM6DS3TR_C_4g: + *val = LSM6DS3TR_C_4g; + break; + + case LSM6DS3TR_C_8g: + *val = LSM6DS3TR_C_8g; + break; + + default: + *val = LSM6DS3TR_C_XL_FS_ND; + break; + } + + return ret; +} + +/** + * @brief Accelerometer data rate selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of odr_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_data_rate_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_xl_t val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + if (ret == 0) + { + ctrl1_xl.odr_xl = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + } + + return ret; +} + +/** + * @brief Accelerometer data rate selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of odr_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_data_rate_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_xl_t *val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + switch (ctrl1_xl.odr_xl) + { + case LSM6DS3TR_C_XL_ODR_OFF: + *val = LSM6DS3TR_C_XL_ODR_OFF; + break; + + case LSM6DS3TR_C_XL_ODR_12Hz5: + *val = LSM6DS3TR_C_XL_ODR_12Hz5; + break; + + case LSM6DS3TR_C_XL_ODR_26Hz: + *val = LSM6DS3TR_C_XL_ODR_26Hz; + break; + + case LSM6DS3TR_C_XL_ODR_52Hz: + *val = LSM6DS3TR_C_XL_ODR_52Hz; + break; + + case LSM6DS3TR_C_XL_ODR_104Hz: + *val = LSM6DS3TR_C_XL_ODR_104Hz; + break; + + case LSM6DS3TR_C_XL_ODR_208Hz: + *val = LSM6DS3TR_C_XL_ODR_208Hz; + break; + + case LSM6DS3TR_C_XL_ODR_416Hz: + *val = LSM6DS3TR_C_XL_ODR_416Hz; + break; + + case LSM6DS3TR_C_XL_ODR_833Hz: + *val = LSM6DS3TR_C_XL_ODR_833Hz; + break; + + case LSM6DS3TR_C_XL_ODR_1k66Hz: + *val = LSM6DS3TR_C_XL_ODR_1k66Hz; + break; + + case LSM6DS3TR_C_XL_ODR_3k33Hz: + *val = LSM6DS3TR_C_XL_ODR_3k33Hz; + break; + + case LSM6DS3TR_C_XL_ODR_6k66Hz: + *val = LSM6DS3TR_C_XL_ODR_6k66Hz; + break; + + case LSM6DS3TR_C_XL_ODR_1Hz6: + *val = LSM6DS3TR_C_XL_ODR_1Hz6; + break; + + default: + *val = LSM6DS3TR_C_XL_ODR_ND; + break; + } + + return ret; +} + +/** + * @brief Gyroscope chain full-scale selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fs_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_full_scale_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_g_t val) +{ + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, + (uint8_t *)&ctrl2_g, 1); + + if (ret == 0) + { + ctrl2_g.fs_g = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL2_G, + (uint8_t *)&ctrl2_g, 1); + } + + return ret; +} + +/** + * @brief Gyroscope chain full-scale selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of fs_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_full_scale_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_g_t *val) +{ + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, + (uint8_t *)&ctrl2_g, 1); + + switch (ctrl2_g.fs_g) + { + case LSM6DS3TR_C_250dps: + *val = LSM6DS3TR_C_250dps; + break; + + case LSM6DS3TR_C_125dps: + *val = LSM6DS3TR_C_125dps; + break; + + case LSM6DS3TR_C_500dps: + *val = LSM6DS3TR_C_500dps; + break; + + case LSM6DS3TR_C_1000dps: + *val = LSM6DS3TR_C_1000dps; + break; + + case LSM6DS3TR_C_2000dps: + *val = LSM6DS3TR_C_2000dps; + break; + + default: + *val = LSM6DS3TR_C_GY_FS_ND; + break; + } + + return ret; +} + +/** + * @brief Gyroscope data rate selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of odr_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_data_rate_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_g_t val) +{ + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, + (uint8_t *)&ctrl2_g, 1); + + if (ret == 0) + { + ctrl2_g.odr_g = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL2_G, + (uint8_t *)&ctrl2_g, 1); + } + + return ret; +} + +/** + * @brief Gyroscope data rate selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of odr_g in reg CTRL2_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_data_rate_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_g_t *val) +{ + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, + (uint8_t *)&ctrl2_g, 1); + + switch (ctrl2_g.odr_g) + { + case LSM6DS3TR_C_GY_ODR_OFF: + *val = LSM6DS3TR_C_GY_ODR_OFF; + break; + + case LSM6DS3TR_C_GY_ODR_12Hz5: + *val = LSM6DS3TR_C_GY_ODR_12Hz5; + break; + + case LSM6DS3TR_C_GY_ODR_26Hz: + *val = LSM6DS3TR_C_GY_ODR_26Hz; + break; + + case LSM6DS3TR_C_GY_ODR_52Hz: + *val = LSM6DS3TR_C_GY_ODR_52Hz; + break; + + case LSM6DS3TR_C_GY_ODR_104Hz: + *val = LSM6DS3TR_C_GY_ODR_104Hz; + break; + + case LSM6DS3TR_C_GY_ODR_208Hz: + *val = LSM6DS3TR_C_GY_ODR_208Hz; + break; + + case LSM6DS3TR_C_GY_ODR_416Hz: + *val = LSM6DS3TR_C_GY_ODR_416Hz; + break; + + case LSM6DS3TR_C_GY_ODR_833Hz: + *val = LSM6DS3TR_C_GY_ODR_833Hz; + break; + + case LSM6DS3TR_C_GY_ODR_1k66Hz: + *val = LSM6DS3TR_C_GY_ODR_1k66Hz; + break; + + case LSM6DS3TR_C_GY_ODR_3k33Hz: + *val = LSM6DS3TR_C_GY_ODR_3k33Hz; + break; + + case LSM6DS3TR_C_GY_ODR_6k66Hz: + *val = LSM6DS3TR_C_GY_ODR_6k66Hz; + break; + + default: + *val = LSM6DS3TR_C_GY_ODR_ND; + break; + } + + return ret; +} + +/** + * @brief Block data update.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of bdu in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_block_data_update_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.bdu = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Block data update.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of bdu in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_block_data_update_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + *val = ctrl3_c.bdu; + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers + * X_OFS_USR(73h), Y_OFS_USR(74h), Z_OFS_USR(75h).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of usr_off_w in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_offset_weight_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_usr_off_w_t val) +{ + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + if (ret == 0) + { + ctrl6_c.usr_off_w = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers + * X_OFS_USR(73h), Y_OFS_USR(74h), Z_OFS_USR(75h).[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of usr_off_w in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_offset_weight_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_usr_off_w_t *val) +{ + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + switch (ctrl6_c.usr_off_w) + { + case LSM6DS3TR_C_LSb_1mg: + *val = LSM6DS3TR_C_LSb_1mg; + break; + + case LSM6DS3TR_C_LSb_16mg: + *val = LSM6DS3TR_C_LSb_16mg; + break; + + default: + *val = LSM6DS3TR_C_WEIGHT_ND; + break; + } + + return ret; +} + +/** + * @brief High-performance operating mode for accelerometer[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of xl_hm_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_power_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_xl_hm_mode_t val) +{ + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + if (ret == 0) + { + ctrl6_c.xl_hm_mode = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief High-performance operating mode for accelerometer.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of xl_hm_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_power_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_xl_hm_mode_t *val) +{ + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + switch (ctrl6_c.xl_hm_mode) + { + case LSM6DS3TR_C_XL_HIGH_PERFORMANCE: + *val = LSM6DS3TR_C_XL_HIGH_PERFORMANCE; + break; + + case LSM6DS3TR_C_XL_NORMAL: + *val = LSM6DS3TR_C_XL_NORMAL; + break; + + default: + *val = LSM6DS3TR_C_XL_PW_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Source register rounding function on WAKE_UP_SRC (1Bh), + * TAP_SRC (1Ch), D6D_SRC (1Dh), STATUS_REG (1Eh) and + * FUNC_SRC1 (53h) registers in the primary interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of rounding_status in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_on_status_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_status_t val) +{ + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + if (ret == 0) + { + ctrl7_g.rounding_status = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + } + + return ret; +} + +/** + * @brief Source register rounding function on WAKE_UP_SRC (1Bh), + * TAP_SRC (1Ch), D6D_SRC (1Dh), STATUS_REG (1Eh) and + * FUNC_SRC1 (53h) registers in the primary interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of rounding_status in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_on_status_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_status_t *val) +{ + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + switch (ctrl7_g.rounding_status) + { + case LSM6DS3TR_C_STAT_RND_DISABLE: + *val = LSM6DS3TR_C_STAT_RND_DISABLE; + break; + + case LSM6DS3TR_C_STAT_RND_ENABLE: + *val = LSM6DS3TR_C_STAT_RND_ENABLE; + break; + + default: + *val = LSM6DS3TR_C_STAT_RND_ND; + break; + } + + return ret; +} + +/** + * @brief High-performance operating mode disable for gyroscope.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of g_hm_mode in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_power_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_g_hm_mode_t val) +{ + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + if (ret == 0) + { + ctrl7_g.g_hm_mode = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + } + + return ret; +} + +/** + * @brief High-performance operating mode disable for gyroscope.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of g_hm_mode in reg CTRL7_G + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_power_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_g_hm_mode_t *val) +{ + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + switch (ctrl7_g.g_hm_mode) + { + case LSM6DS3TR_C_GY_HIGH_PERFORMANCE: + *val = LSM6DS3TR_C_GY_HIGH_PERFORMANCE; + break; + + case LSM6DS3TR_C_GY_NORMAL: + *val = LSM6DS3TR_C_GY_NORMAL; + break; + + default: + *val = LSM6DS3TR_C_GY_PW_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Read all the interrupt/status flag of the device.[get] + * + * @param ctx Read / write interface definitions + * @param val WAKE_UP_SRC, TAP_SRC, D6D_SRC, STATUS_REG, + * FUNC_SRC1, FUNC_SRC2, WRIST_TILT_IA, A_WRIST_TILT_Mask + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_all_sources_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_all_sources_t *val) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_SRC, + (uint8_t *) & (val->wake_up_src), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_SRC, + (uint8_t *) & (val->tap_src), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_D6D_SRC, + (uint8_t *) & (val->d6d_src), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, + (uint8_t *) & (val->status_reg), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_SRC1, + (uint8_t *) & (val->func_src1), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_SRC2, + (uint8_t *) & (val->func_src2), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WRIST_TILT_IA, + (uint8_t *) & (val->wrist_tilt_ia), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, + (uint8_t *) & (val->a_wrist_tilt_mask), 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + + return ret; +} +/** + * @brief The STATUS_REG register is read by the primary interface[get] + * + * @param ctx Read / write interface definitions + * @param val Registers STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_status_reg_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_status_reg_t *val) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, + (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief Accelerometer new data available.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of xlda in reg STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_flag_data_ready_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_status_reg_t status_reg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, + (uint8_t *)&status_reg, 1); + *val = status_reg.xlda; + + return ret; +} + +/** + * @brief Gyroscope new data available.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of gda in reg STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_flag_data_ready_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_status_reg_t status_reg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, + (uint8_t *)&status_reg, 1); + *val = status_reg.gda; + + return ret; +} + +/** + * @brief Temperature new data available.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tda in reg STATUS_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_temp_flag_data_ready_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_status_reg_t status_reg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, + (uint8_t *)&status_reg, 1); + *val = status_reg.tda; + + return ret; +} + +/** + * @brief Accelerometer axis user offset correction expressed in two’s + * complement, weight depends on USR_OFF_W in CTRL6_C. + * The value must be in the range [-127 127].[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_usr_offset_set(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_X_OFS_USR, buff, 3); + + return ret; +} + +/** + * @brief Accelerometer axis user offset correction xpressed in two’s + * complement, weight depends on USR_OFF_W in CTRL6_C. + * The value must be in the range [-127 127].[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_usr_offset_get(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_X_OFS_USR, buff, 3); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Timestamp + * @brief This section groups all the functions that manage the + * timestamp generation. + * @{ + * + */ + +/** + * @brief Enable timestamp count. The count is saved in TIMESTAMP0_REG (40h), + * TIMESTAMP1_REG (41h) and TIMESTAMP2_REG (42h).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.timer_en = val; + + if (val != 0x00U) + { + ctrl10_c.func_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + } + + return ret; +} + +/** + * @brief Enable timestamp count. The count is saved in TIMESTAMP0_REG (40h), + * TIMESTAMP1_REG (41h) and TIMESTAMP2_REG (42h).[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + *val = ctrl10_c.timer_en; + + return ret; +} + +/** + * @brief Timestamp register resolution setting. + * Configuration of this bit affects + * TIMESTAMP0_REG(40h), TIMESTAMP1_REG(41h), + * TIMESTAMP2_REG(42h), STEP_TIMESTAMP_L(49h), + * STEP_TIMESTAMP_H(4Ah) and + * STEP_COUNT_DELTA(15h) registers.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_hr in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_res_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_timer_hr_t val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + wake_up_dur.timer_hr = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Timestamp register resolution setting. + * Configuration of this bit affects + * TIMESTAMP0_REG(40h), TIMESTAMP1_REG(41h), + * TIMESTAMP2_REG(42h), STEP_TIMESTAMP_L(49h), + * STEP_TIMESTAMP_H(4Ah) and + * STEP_COUNT_DELTA(15h) registers.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of timer_hr in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_timestamp_res_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_timer_hr_t *val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + switch (wake_up_dur.timer_hr) + { + case LSM6DS3TR_C_LSB_6ms4: + *val = LSM6DS3TR_C_LSB_6ms4; + break; + + case LSM6DS3TR_C_LSB_25us: + *val = LSM6DS3TR_C_LSB_25us; + break; + + default: + *val = LSM6DS3TR_C_TS_RES_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Dataoutput + * @brief This section groups all the data output functions. + * @{ + * + */ + +/** + * @brief Circular burst-mode (rounding) read from output registers + * through the primary interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of rounding in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_t val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + if (ret == 0) + { + ctrl5_c.rounding = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief Circular burst-mode (rounding) read from output registers + * through the primary interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of rounding in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_rounding_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_t *val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + switch (ctrl5_c.rounding) + { + case LSM6DS3TR_C_ROUND_DISABLE: + *val = LSM6DS3TR_C_ROUND_DISABLE; + break; + + case LSM6DS3TR_C_ROUND_XL: + *val = LSM6DS3TR_C_ROUND_XL; + break; + + case LSM6DS3TR_C_ROUND_GY: + *val = LSM6DS3TR_C_ROUND_GY; + break; + + case LSM6DS3TR_C_ROUND_GY_XL: + *val = LSM6DS3TR_C_ROUND_GY_XL; + break; + + case LSM6DS3TR_C_ROUND_SH1_TO_SH6: + *val = LSM6DS3TR_C_ROUND_SH1_TO_SH6; + break; + + case LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6: + *val = LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6; + break; + + case LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12: + *val = LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12; + break; + + case LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6: + *val = LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6; + break; + + default: + *val = LSM6DS3TR_C_ROUND_OUT_ND; + break; + } + + return ret; +} + +/** + * @brief Temperature data output register (r). L and H registers together + * express a 16-bit word in two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_temperature_raw_get(const stmdev_ctx_t *ctx, + int16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUT_TEMP_L, buff, 2); + *val = (int16_t)buff[1]; + *val = (*val * 256) + (int16_t)buff[0]; + + return ret; +} + +/** + * @brief Angular rate sensor. The value is expressed as a 16-bit word in + * two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_angular_rate_raw_get(const stmdev_ctx_t *ctx, + int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUTX_L_G, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief Linear acceleration output register. The value is expressed + * as a 16-bit word in two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_acceleration_raw_get(const stmdev_ctx_t *ctx, + int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUTX_L_XL, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief External magnetometer raw data.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_calibrated_raw_get(const stmdev_ctx_t *ctx, + int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUT_MAG_RAW_X_L, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief Read data in FIFO.[get] + * + * @param ctx Read / write interface definitions + * @param buffer Data buffer to store FIFO data. + * @param len Number of data to read from FIFO. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_raw_data_get(const stmdev_ctx_t *ctx, + uint8_t *buffer, + uint8_t len) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_DATA_OUT_L, buffer, + len); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_common + * @brief This section groups common useful functions. + * @{ + * + */ + +/** + * @brief Enable access to the embedded functions/sensor hub + * configuration registers[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of func_cfg_en in reg FUNC_CFG_ACCESS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mem_bank_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_func_cfg_en_t val) +{ + lsm6ds3tr_c_func_cfg_access_t func_cfg_access; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, + (uint8_t *)&func_cfg_access, 1); + + if (ret == 0) + { + func_cfg_access.func_cfg_en = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, + (uint8_t *)&func_cfg_access, 1); + } + + return ret; +} + +/** + * @brief Enable access to the embedded functions/sensor hub configuration + * registers[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of func_cfg_en in reg FUNC_CFG_ACCESS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mem_bank_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_func_cfg_en_t *val) +{ + lsm6ds3tr_c_func_cfg_access_t func_cfg_access; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, + (uint8_t *)&func_cfg_access, 1); + + switch (func_cfg_access.func_cfg_en) + { + case LSM6DS3TR_C_USER_BANK: + *val = LSM6DS3TR_C_USER_BANK; + break; + + case LSM6DS3TR_C_BANK_B: + *val = LSM6DS3TR_C_BANK_B; + break; + + default: + *val = LSM6DS3TR_C_BANK_ND; + break; + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_pulsed in reg DRDY_PULSE_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_ready_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_drdy_pulsed_g_t val) +{ + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, + (uint8_t *)&drdy_pulse_cfg_g, 1); + + if (ret == 0) + { + drdy_pulse_cfg_g.drdy_pulsed = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, + (uint8_t *)&drdy_pulse_cfg_g, 1); + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of drdy_pulsed in reg DRDY_PULSE_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_ready_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_drdy_pulsed_g_t *val) +{ + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, + (uint8_t *)&drdy_pulse_cfg_g, 1); + + switch (drdy_pulse_cfg_g.drdy_pulsed) + { + case LSM6DS3TR_C_DRDY_LATCHED: + *val = LSM6DS3TR_C_DRDY_LATCHED; + break; + + case LSM6DS3TR_C_DRDY_PULSED: + *val = LSM6DS3TR_C_DRDY_PULSED; + break; + + default: + *val = LSM6DS3TR_C_DRDY_ND; + break; + } + + return ret; +} + +/** + * @brief DeviceWhoamI.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_device_id_get(const stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WHO_AM_I, buff, 1); + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sw_reset in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_reset_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.sw_reset = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sw_reset in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_reset_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + *val = ctrl3_c.sw_reset; + + return ret; +} + +/** + * @brief Big/Little Endian Data selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ble in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_format_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ble_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.ble = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Big/Little Endian Data selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of ble in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_data_format_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ble_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + switch (ctrl3_c.ble) + { + case LSM6DS3TR_C_LSB_AT_LOW_ADD: + *val = LSM6DS3TR_C_LSB_AT_LOW_ADD; + break; + + case LSM6DS3TR_C_MSB_AT_LOW_ADD: + *val = LSM6DS3TR_C_MSB_AT_LOW_ADD; + break; + + default: + *val = LSM6DS3TR_C_DATA_FMT_ND; + break; + } + + return ret; +} + +/** + * @brief Register address automatically incremented during a multiple byte + * access with a serial interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of if_inc in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_auto_increment_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.if_inc = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Register address automatically incremented during a multiple byte + * access with a serial interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of if_inc in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_auto_increment_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + *val = ctrl3_c.if_inc; + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of boot in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_boot_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.boot = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of boot in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_boot_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + *val = ctrl3_c.boot; + + return ret; +} + +/** + * @brief Linear acceleration sensor self-test enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of st_xl in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_self_test_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_xl_t val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + if (ret == 0) + { + ctrl5_c.st_xl = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief Linear acceleration sensor self-test enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of st_xl in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_self_test_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_xl_t *val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + switch (ctrl5_c.st_xl) + { + case LSM6DS3TR_C_XL_ST_DISABLE: + *val = LSM6DS3TR_C_XL_ST_DISABLE; + break; + + case LSM6DS3TR_C_XL_ST_POSITIVE: + *val = LSM6DS3TR_C_XL_ST_POSITIVE; + break; + + case LSM6DS3TR_C_XL_ST_NEGATIVE: + *val = LSM6DS3TR_C_XL_ST_NEGATIVE; + break; + + default: + *val = LSM6DS3TR_C_XL_ST_ND; + break; + } + + return ret; +} + +/** + * @brief Angular rate sensor self-test enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of st_g in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_self_test_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_g_t val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + if (ret == 0) + { + ctrl5_c.st_g = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief Angular rate sensor self-test enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of st_g in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_self_test_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_g_t *val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + switch (ctrl5_c.st_g) + { + case LSM6DS3TR_C_GY_ST_DISABLE: + *val = LSM6DS3TR_C_GY_ST_DISABLE; + break; + + case LSM6DS3TR_C_GY_ST_POSITIVE: + *val = LSM6DS3TR_C_GY_ST_POSITIVE; + break; + + case LSM6DS3TR_C_GY_ST_NEGATIVE: + *val = LSM6DS3TR_C_GY_ST_NEGATIVE; + break; + + default: + *val = LSM6DS3TR_C_GY_ST_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_filters + * @brief This section group all the functions concerning the filters + * configuration that impact both accelerometer and gyro. + * @{ + * + */ + +/** + * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends + * (XL and Gyro independently masked).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_mask in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_filter_settling_mask_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ctrl4_c.drdy_mask = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends + * (XL and Gyro independently masked).[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_mask in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_filter_settling_mask_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + *val = ctrl4_c.drdy_mask; + + return ret; +} + +/** + * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity + * functions.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slope_fds in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_path_internal_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slope_fds_t val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if (ret == 0) + { + tap_cfg.slope_fds = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity + * functions.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slope_fds in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_path_internal_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slope_fds_t *val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + switch (tap_cfg.slope_fds) + { + case LSM6DS3TR_C_USE_SLOPE: + *val = LSM6DS3TR_C_USE_SLOPE; + break; + + case LSM6DS3TR_C_USE_HPF: + *val = LSM6DS3TR_C_USE_HPF; + break; + + default: + *val = LSM6DS3TR_C_HP_PATH_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_accelerometer_filters + * @brief This section group all the functions concerning the filters + * configuration that impact accelerometer in every mode. + * @{ + * + */ + +/** + * @brief Accelerometer analog chain bandwidth selection (only for + * accelerometer ODR ≥ 1.67 kHz).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of bw0_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_filter_analog_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_bw0_xl_t val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + if (ret == 0) + { + ctrl1_xl.bw0_xl = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + } + + return ret; +} + +/** + * @brief Accelerometer analog chain bandwidth selection (only for + * accelerometer ODR ≥ 1.67 kHz).[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of bw0_xl in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_filter_analog_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_bw0_xl_t *val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + switch (ctrl1_xl.bw0_xl) + { + case LSM6DS3TR_C_XL_ANA_BW_1k5Hz: + *val = LSM6DS3TR_C_XL_ANA_BW_1k5Hz; + break; + + case LSM6DS3TR_C_XL_ANA_BW_400Hz: + *val = LSM6DS3TR_C_XL_ANA_BW_400Hz; + break; + + default: + *val = LSM6DS3TR_C_XL_ANA_BW_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_accelerometer_filters + * @brief This section group all the functions concerning the filters + * configuration that impact accelerometer. + * @{ + * + */ + +/** + * @brief Accelerometer digital LPF (LPF1) bandwidth selection LPF2 is + * not used.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of lpf1_bw_sel in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_bw_sel_t val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + if (ret == 0) + { + ctrl1_xl.lpf1_bw_sel = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + ctrl8_xl.lpf2_xl_en = 0; + ctrl8_xl.hp_slope_xl_en = 0; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + } + } + } + + return ret; +} + +/** + * @brief Accelerometer digital LPF (LPF1) bandwidth selection LPF2 + * is not used.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of lpf1_bw_sel in reg CTRL1_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_bw_sel_t *val) +{ + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + if ((ctrl8_xl.lpf2_xl_en != 0x00U) || + (ctrl8_xl.hp_slope_xl_en != 0x00U)) + { + *val = LSM6DS3TR_C_XL_LP1_NA; + } + + else + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + + switch (ctrl1_xl.lpf1_bw_sel) + { + case LSM6DS3TR_C_XL_LP1_ODR_DIV_2: + *val = LSM6DS3TR_C_XL_LP1_ODR_DIV_2; + break; + + case LSM6DS3TR_C_XL_LP1_ODR_DIV_4: + *val = LSM6DS3TR_C_XL_LP1_ODR_DIV_4; + break; + + default: + *val = LSM6DS3TR_C_XL_LP1_NA; + break; + } + } + } + + return ret; +} + +/** + * @brief LPF2 on outputs[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of input_composite in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_input_composite_t val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + ctrl8_xl.input_composite = ((uint8_t) val & 0x10U) >> 4; + ctrl8_xl.hpcf_xl = (uint8_t) val & 0x03U; + ctrl8_xl.lpf2_xl_en = 1; + ctrl8_xl.hp_slope_xl_en = 0; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief LPF2 on outputs[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of input_composite in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_input_composite_t *val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + if ((ctrl8_xl.lpf2_xl_en == 0x00U) || + (ctrl8_xl.hp_slope_xl_en != 0x00U)) + { + *val = LSM6DS3TR_C_XL_LP_NA; + } + + else + { + switch ((ctrl8_xl.input_composite << 4) + ctrl8_xl.hpcf_xl) + { + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50; + break; + + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100; + break; + + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9; + break; + + case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400: + *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9; + break; + + case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400: + *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400; + break; + + default: + *val = LSM6DS3TR_C_XL_LP_NA; + break; + } + } + } + + return ret; +} + +/** + * @brief Enable HP filter reference mode.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of hp_ref_mode in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_reference_mode_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + ctrl8_xl.hp_ref_mode = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief Enable HP filter reference mode.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of hp_ref_mode in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_reference_mode_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + *val = ctrl8_xl.hp_ref_mode; + + return ret; +} + +/** + * @brief High pass/Slope on outputs.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of hpcf_xl in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_bandwidth_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_hpcf_xl_t val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + ctrl8_xl.input_composite = 0; + ctrl8_xl.hpcf_xl = (uint8_t)val & 0x03U; + ctrl8_xl.hp_slope_xl_en = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief High pass/Slope on outputs.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of hpcf_xl in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_xl_hp_bandwidth_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_hpcf_xl_t *val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ctrl8_xl.hp_slope_xl_en == 0x00U) + { + *val = LSM6DS3TR_C_XL_HP_NA; + } + + switch (ctrl8_xl.hpcf_xl) + { + case LSM6DS3TR_C_XL_HP_ODR_DIV_4: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_4; + break; + + case LSM6DS3TR_C_XL_HP_ODR_DIV_100: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_100; + break; + + case LSM6DS3TR_C_XL_HP_ODR_DIV_9: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_9; + break; + + case LSM6DS3TR_C_XL_HP_ODR_DIV_400: + *val = LSM6DS3TR_C_XL_HP_ODR_DIV_400; + break; + + default: + *val = LSM6DS3TR_C_XL_HP_NA; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_gyroscope_filters + * @brief This section group all the functions concerning the filters + * configuration that impact gyroscope. + * @{ + * + */ + +/** + * @brief Gyroscope low pass path bandwidth.[set] + * + * @param ctx Read / write interface definitions + * @param val gyroscope filtering chain configuration. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_band_pass_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_sel_g_t val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + if (ret == 0) + { + ctrl7_g.hpm_g = ((uint8_t)val & 0x30U) >> 4; + ctrl7_g.hp_en_g = ((uint8_t)val & 0x80U) >> 7; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + if (ret == 0) + { + ctrl6_c.ftype = (uint8_t)val & 0x03U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ctrl4_c.lpf1_sel_g = ((uint8_t)val & 0x08U) >> 3; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + } + } + } + } + + return ret; +} + +/** + * @brief Gyroscope low pass path bandwidth.[get] + * + * @param ctx Read / write interface definitions + * @param val gyroscope filtering chain + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_band_pass_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_sel_g_t *val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, + (uint8_t *)&ctrl7_g, 1); + + switch ((ctrl7_g.hp_en_g << 7) + (ctrl7_g.hpm_g << 4) + + (ctrl4_c.lpf1_sel_g << 3) + ctrl6_c.ftype) + { + case LSM6DS3TR_C_HP_16mHz_LP2: + *val = LSM6DS3TR_C_HP_16mHz_LP2; + break; + + case LSM6DS3TR_C_HP_65mHz_LP2: + *val = LSM6DS3TR_C_HP_65mHz_LP2; + break; + + case LSM6DS3TR_C_HP_260mHz_LP2: + *val = LSM6DS3TR_C_HP_260mHz_LP2; + break; + + case LSM6DS3TR_C_HP_1Hz04_LP2: + *val = LSM6DS3TR_C_HP_1Hz04_LP2; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT: + *val = LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL: + *val = LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP_STRONG: + *val = LSM6DS3TR_C_HP_DISABLE_LP_STRONG; + break; + + case LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE: + *val = LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE; + break; + + case LSM6DS3TR_C_HP_16mHz_LP1_LIGHT: + *val = LSM6DS3TR_C_HP_16mHz_LP1_LIGHT; + break; + + case LSM6DS3TR_C_HP_65mHz_LP1_NORMAL: + *val = LSM6DS3TR_C_HP_65mHz_LP1_NORMAL; + break; + + case LSM6DS3TR_C_HP_260mHz_LP1_STRONG: + *val = LSM6DS3TR_C_HP_260mHz_LP1_STRONG; + break; + + case LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE: + *val = LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE; + break; + + default: + *val = LSM6DS3TR_C_HP_GY_BAND_NA; + break; + } + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_serial_interface + * @brief This section groups all the functions concerning serial + * interface management + * @{ + * + */ + +/** + * @brief SPI Serial Interface Mode selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sim in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_spi_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sim_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.sim = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief SPI Serial Interface Mode selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of sim in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_spi_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sim_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + switch (ctrl3_c.sim) + { + case LSM6DS3TR_C_SPI_4_WIRE: + *val = LSM6DS3TR_C_SPI_4_WIRE; + break; + + case LSM6DS3TR_C_SPI_3_WIRE: + *val = LSM6DS3TR_C_SPI_3_WIRE; + break; + + default: + *val = LSM6DS3TR_C_SPI_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of i2c_disable in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_i2c_interface_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_i2c_disable_t val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ctrl4_c.i2c_disable = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of i2c_disable in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_i2c_interface_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_i2c_disable_t *val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + switch (ctrl4_c.i2c_disable) + { + case LSM6DS3TR_C_I2C_ENABLE: + *val = LSM6DS3TR_C_I2C_ENABLE; + break; + + case LSM6DS3TR_C_I2C_DISABLE: + *val = LSM6DS3TR_C_I2C_DISABLE; + break; + + default: + *val = LSM6DS3TR_C_I2C_MODE_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_interrupt_pins + * @brief This section groups all the functions that manage + * interrupt pins + * @{ + * + */ + +/** + * @brief Select the signal that need to route on int1 pad[set] + * + * @param ctx Read / write interface definitions + * @param val configure INT1_CTRL, MD1_CFG, CTRL4_C(den_drdy_int1), + * MASTER_CONFIG(drdy_on_int1) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int1_route_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int1_route_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_int1_ctrl_t int1_ctrl; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT1_CTRL, + (uint8_t *)&int1_ctrl, 1); + + if (ret == 0) + { + int1_ctrl.int1_drdy_xl = val.int1_drdy_xl; + int1_ctrl.int1_drdy_g = val.int1_drdy_g; + int1_ctrl.int1_boot = val.int1_boot; + int1_ctrl.int1_fth = val.int1_fth; + int1_ctrl.int1_fifo_ovr = val.int1_fifo_ovr; + int1_ctrl.int1_full_flag = val.int1_full_flag; + int1_ctrl.int1_sign_mot = val.int1_sign_mot; + int1_ctrl.int1_step_detector = val.int1_step_detector; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT1_CTRL, + (uint8_t *)&int1_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, + (uint8_t *)&md1_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, + (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + md1_cfg.int1_timer = val.int1_timer; + md1_cfg.int1_tilt = val.int1_tilt; + md1_cfg.int1_6d = val.int1_6d; + md1_cfg.int1_double_tap = val.int1_double_tap; + md1_cfg.int1_ff = val.int1_ff; + md1_cfg.int1_wu = val.int1_wu; + md1_cfg.int1_single_tap = val.int1_single_tap; + md1_cfg.int1_inact_state = val.int1_inact_state; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MD1_CFG, + (uint8_t *)&md1_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + if (ret == 0) + { + ctrl4_c.den_drdy_int1 = val.den_drdy_int1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + if (ret == 0) + { + master_config.drdy_on_int1 = val.den_drdy_int1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if ((val.int1_6d != 0x00U) || + (val.int1_ff != 0x00U) || + (val.int1_wu != 0x00U) || + (val.int1_single_tap != 0x00U) || + (val.int1_double_tap != 0x00U) || + (val.int1_inact_state != 0x00U) || + (md2_cfg.int2_6d != 0x00U) || + (md2_cfg.int2_ff != 0x00U) || + (md2_cfg.int2_wu != 0x00U) || + (md2_cfg.int2_single_tap != 0x00U) || + (md2_cfg.int2_double_tap != 0x00U) || + (md2_cfg.int2_inact_state != 0x00U)) + { + tap_cfg.interrupts_enable = PROPERTY_ENABLE; + } + + else + { + tap_cfg.interrupts_enable = PROPERTY_DISABLE; + } + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int1 pad[get] + * + * @param ctx Read / write interface definitions + * @param val read INT1_CTRL, MD1_CFG, CTRL4_C(den_drdy_int1), + * MASTER_CONFIG(drdy_on_int1) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int1_route_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int1_route_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_int1_ctrl_t int1_ctrl; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT1_CTRL, + (uint8_t *)&int1_ctrl, 1); + + if (ret == 0) + { + val->int1_drdy_xl = int1_ctrl.int1_drdy_xl; + val->int1_drdy_g = int1_ctrl.int1_drdy_g; + val->int1_boot = int1_ctrl.int1_boot; + val->int1_fth = int1_ctrl.int1_fth; + val->int1_fifo_ovr = int1_ctrl.int1_fifo_ovr; + val->int1_full_flag = int1_ctrl.int1_full_flag; + val->int1_sign_mot = int1_ctrl.int1_sign_mot; + val->int1_step_detector = int1_ctrl.int1_step_detector ; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, + (uint8_t *)&md1_cfg, 1); + + if (ret == 0) + { + val->int1_timer = md1_cfg.int1_timer; + val->int1_tilt = md1_cfg.int1_tilt; + val->int1_6d = md1_cfg.int1_6d; + val->int1_double_tap = md1_cfg.int1_double_tap; + val->int1_ff = md1_cfg.int1_ff; + val->int1_wu = md1_cfg.int1_wu; + val->int1_single_tap = md1_cfg.int1_single_tap; + val->int1_inact_state = md1_cfg.int1_inact_state; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + val->den_drdy_int1 = ctrl4_c.den_drdy_int1; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + val->den_drdy_int1 = master_config.drdy_on_int1; + } + } + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int2 pad[set] + * + * @param ctx Read / write interface definitions + * @param val INT2_CTRL, DRDY_PULSE_CFG(int2_wrist_tilt), MD2_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int2_route_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int2_route_t val) +{ + lsm6ds3tr_c_int2_ctrl_t int2_ctrl; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT2_CTRL, + (uint8_t *)&int2_ctrl, 1); + + if (ret == 0) + { + int2_ctrl.int2_drdy_xl = val.int2_drdy_xl; + int2_ctrl.int2_drdy_g = val.int2_drdy_g; + int2_ctrl.int2_drdy_temp = val.int2_drdy_temp; + int2_ctrl.int2_fth = val.int2_fth; + int2_ctrl.int2_fifo_ovr = val.int2_fifo_ovr; + int2_ctrl.int2_full_flag = val.int2_full_flag; + int2_ctrl.int2_step_count_ov = val.int2_step_count_ov; + int2_ctrl.int2_step_delta = val.int2_step_delta; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT2_CTRL, + (uint8_t *)&int2_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, + (uint8_t *)&md1_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, + (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + md2_cfg.int2_iron = val.int2_iron; + md2_cfg.int2_tilt = val.int2_tilt; + md2_cfg.int2_6d = val.int2_6d; + md2_cfg.int2_double_tap = val.int2_double_tap; + md2_cfg.int2_ff = val.int2_ff; + md2_cfg.int2_wu = val.int2_wu; + md2_cfg.int2_single_tap = val.int2_single_tap; + md2_cfg.int2_inact_state = val.int2_inact_state; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MD2_CFG, + (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, + (uint8_t *)&drdy_pulse_cfg_g, 1); + } + + if (ret == 0) + { + drdy_pulse_cfg_g.int2_wrist_tilt = val.int2_wrist_tilt; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, + (uint8_t *)&drdy_pulse_cfg_g, 1); + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if ((md1_cfg.int1_6d != 0x00U) || + (md1_cfg.int1_ff != 0x00U) || + (md1_cfg.int1_wu != 0x00U) || + (md1_cfg.int1_single_tap != 0x00U) || + (md1_cfg.int1_double_tap != 0x00U) || + (md1_cfg.int1_inact_state != 0x00U) || + (val.int2_6d != 0x00U) || + (val.int2_ff != 0x00U) || + (val.int2_wu != 0x00U) || + (val.int2_single_tap != 0x00U) || + (val.int2_double_tap != 0x00U) || + (val.int2_inact_state != 0x00U)) + { + tap_cfg.interrupts_enable = PROPERTY_ENABLE; + } + + else + { + tap_cfg.interrupts_enable = PROPERTY_DISABLE; + } + } + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int2 pad[get] + * + * @param ctx Read / write interface definitions + * @param val INT2_CTRL, DRDY_PULSE_CFG(int2_wrist_tilt), MD2_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_int2_route_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int2_route_t *val) +{ + lsm6ds3tr_c_int2_ctrl_t int2_ctrl; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT2_CTRL, + (uint8_t *)&int2_ctrl, 1); + + if (ret == 0) + { + val->int2_drdy_xl = int2_ctrl.int2_drdy_xl; + val->int2_drdy_g = int2_ctrl.int2_drdy_g; + val->int2_drdy_temp = int2_ctrl.int2_drdy_temp; + val->int2_fth = int2_ctrl.int2_fth; + val->int2_fifo_ovr = int2_ctrl.int2_fifo_ovr; + val->int2_full_flag = int2_ctrl.int2_full_flag; + val->int2_step_count_ov = int2_ctrl.int2_step_count_ov; + val->int2_step_delta = int2_ctrl.int2_step_delta; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, + (uint8_t *)&md2_cfg, 1); + + if (ret == 0) + { + val->int2_iron = md2_cfg.int2_iron; + val->int2_tilt = md2_cfg.int2_tilt; + val->int2_6d = md2_cfg.int2_6d; + val->int2_double_tap = md2_cfg.int2_double_tap; + val->int2_ff = md2_cfg.int2_ff; + val->int2_wu = md2_cfg.int2_wu; + val->int2_single_tap = md2_cfg.int2_single_tap; + val->int2_inact_state = md2_cfg.int2_inact_state; + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, + (uint8_t *)&drdy_pulse_cfg_g, 1); + val->int2_wrist_tilt = drdy_pulse_cfg_g.int2_wrist_tilt; + } + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pp_od in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pp_od_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.pp_od = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of pp_od in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pp_od_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + switch (ctrl3_c.pp_od) + { + case LSM6DS3TR_C_PUSH_PULL: + *val = LSM6DS3TR_C_PUSH_PULL; + break; + + case LSM6DS3TR_C_OPEN_DRAIN: + *val = LSM6DS3TR_C_OPEN_DRAIN; + break; + + default: + *val = LSM6DS3TR_C_PIN_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of h_lactive in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_polarity_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_h_lactive_t val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.h_lactive = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of h_lactive in reg CTRL3_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pin_polarity_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_h_lactive_t *val) +{ + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + switch (ctrl3_c.h_lactive) + { + case LSM6DS3TR_C_ACTIVE_HIGH: + *val = LSM6DS3TR_C_ACTIVE_HIGH; + break; + + case LSM6DS3TR_C_ACTIVE_LOW: + *val = LSM6DS3TR_C_ACTIVE_LOW; + break; + + default: + *val = LSM6DS3TR_C_POLARITY_ND; + break; + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of int2_on_int1 in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_all_on_int1_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ctrl4_c.int2_on_int1 = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of int2_on_int1 in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_all_on_int1_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + *val = ctrl4_c.int2_on_int1; + + return ret; +} + +/** + * @brief Latched/pulsed interrupt.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of lir in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_int_notification_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lir_t val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if (ret == 0) + { + tap_cfg.lir = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Latched/pulsed interrupt.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of lir in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_int_notification_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lir_t *val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + switch (tap_cfg.lir) + { + case LSM6DS3TR_C_INT_PULSED: + *val = LSM6DS3TR_C_INT_PULSED; + break; + + case LSM6DS3TR_C_INT_LATCHED: + *val = LSM6DS3TR_C_INT_LATCHED; + break; + + default: + *val = LSM6DS3TR_C_INT_MODE; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Wake_Up_event + * @brief This section groups all the functions that manage the + * Wake Up event generation. + * @{ + * + */ + +/** + * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wk_ths in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_threshold_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, + (uint8_t *)&wake_up_ths, 1); + + if (ret == 0) + { + wake_up_ths.wk_ths = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, + (uint8_t *)&wake_up_ths, 1); + } + + return ret; +} + +/** + * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wk_ths in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, + (uint8_t *)&wake_up_ths, 1); + *val = wake_up_ths.wk_ths; + + return ret; +} + +/** + * @brief Wake up duration event.1LSb = 1 / ODR[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wake_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_dur_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + wake_up_dur.wake_dur = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Wake up duration event.1LSb = 1 / ODR[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of wake_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wkup_dur_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + *val = wake_up_dur.wake_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Activity/Inactivity_detection + * @brief This section groups all the functions concerning + * activity/inactivity detection. + * @{ + * + */ + +/** + * @brief Enables gyroscope Sleep mode.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_sleep_mode_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ctrl4_c.sleep = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + return ret; +} + +/** + * @brief Enables gyroscope Sleep mode.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep in reg CTRL4_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_gy_sleep_mode_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + *val = ctrl4_c.sleep; + + return ret; +} + +/** + * @brief Enable inactivity function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of inact_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_inact_en_t val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if (ret == 0) + { + tap_cfg.inact_en = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable inactivity function.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of inact_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_inact_en_t *val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + switch (tap_cfg.inact_en) + { + case LSM6DS3TR_C_PROPERTY_DISABLE: + *val = LSM6DS3TR_C_PROPERTY_DISABLE; + break; + + case LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED: + *val = LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED; + break; + + case LSM6DS3TR_C_XL_12Hz5_GY_SLEEP: + *val = LSM6DS3TR_C_XL_12Hz5_GY_SLEEP; + break; + + case LSM6DS3TR_C_XL_12Hz5_GY_PD: + *val = LSM6DS3TR_C_XL_12Hz5_GY_PD; + break; + + default: + *val = LSM6DS3TR_C_ACT_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode.1 LSb = 512 / ODR[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_sleep_dur_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + wake_up_dur.sleep_dur = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode. 1 LSb = 512 / ODR[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sleep_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_act_sleep_dur_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + *val = wake_up_dur.sleep_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_tap_generator + * @brief This section groups all the functions that manage the + * tap and double tap event generation. + * @{ + * + */ + +/** + * @brief Read the tap / double tap source register.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure of registers from TAP_SRC + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_src_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_tap_src_t *val) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_SRC, (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_z_en in reg TAP_CFG + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_z_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if (ret == 0) + { + tap_cfg.tap_z_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_z_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_z_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + *val = tap_cfg.tap_z_en; + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_y_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_y_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if (ret == 0) + { + tap_cfg.tap_y_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_y_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_y_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + *val = tap_cfg.tap_y_en; + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_x_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_x_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + + if (ret == 0) + { + tap_cfg.tap_x_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + } + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_x_en in reg TAP_CFG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_detection_on_x_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_tap_cfg_t tap_cfg; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, + (uint8_t *)&tap_cfg, 1); + *val = tap_cfg.tap_x_en; + + return ret; +} + +/** + * @brief Threshold for tap recognition.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_threshold_x_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + + if (ret == 0) + { + tap_ths_6d.tap_ths = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + } + + return ret; +} + +/** + * @brief Threshold for tap recognition.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tap_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_threshold_x_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + *val = tap_ths_6d.tap_ths; + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an overthreshold signal + * detection to be recognized as a tap event. + * The default value of these bits is 00b which corresponds to + * 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different + * value, 1LSB corresponds to 8*ODR_XL time.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of shock in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_shock_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + + if (ret == 0) + { + int_dur2.shock = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + } + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an overthreshold signal + * detection to be recognized as a tap event. + * The default value of these bits is 00b which corresponds to + * 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different value, 1LSB + * corresponds to 8*ODR_XL time.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of shock in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_shock_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + *val = int_dur2.shock; + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected tap in which there + * must not be any overthreshold event. + * The default value of these bits is 00b which corresponds to + * 2*ODR_XL time. + * If the QUIET[1:0] bits are set to a different value, 1LSB + * corresponds to 4*ODR_XL time.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of quiet in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_quiet_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + + if (ret == 0) + { + int_dur2.quiet = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + } + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected tap in which there + * must not be any overthreshold event. + * The default value of these bits is 00b which corresponds to + * 2*ODR_XL time. + * If the QUIET[1:0] bits are set to a different value, 1LSB + * corresponds to 4*ODR_XL time.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of quiet in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_quiet_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + *val = int_dur2.quiet; + + return ret; +} + +/** + * @brief When double tap recognition is enabled, this register expresses the + * maximum time between two consecutive detected taps to determine a + * double tap event. + * The default value of these bits is 0000b which corresponds to + * 16*ODR_XL time. + * If the DUR[3:0] bits are set to a different value,1LSB corresponds + * to 32*ODR_XL time.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dur in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_dur_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + + if (ret == 0) + { + int_dur2.dur = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + } + + return ret; +} + +/** + * @brief When double tap recognition is enabled, this register expresses the + * maximum time between two consecutive detected taps to determine a + * double tap event. + * The default value of these bits is 0000b which corresponds to + * 16*ODR_XL time. + * If the DUR[3:0] bits are set to a different value,1LSB corresponds + * to 32*ODR_XL time.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dur in reg INT_DUR2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_dur_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_int_dur2_t int_dur2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, + (uint8_t *)&int_dur2, 1); + *val = int_dur2.dur; + + return ret; +} + +/** + * @brief Single/double-tap event enable/disable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of + * single_double_tap in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_single_double_tap_t val) +{ + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, + (uint8_t *)&wake_up_ths, 1); + + if (ret == 0) + { + wake_up_ths.single_double_tap = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, + (uint8_t *)&wake_up_ths, 1); + } + + return ret; +} + +/** + * @brief Single/double-tap event enable/disable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of single_double_tap + * in reg WAKE_UP_THS + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tap_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_single_double_tap_t *val) +{ + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, + (uint8_t *)&wake_up_ths, 1); + + switch (wake_up_ths.single_double_tap) + { + case LSM6DS3TR_C_ONLY_SINGLE: + *val = LSM6DS3TR_C_ONLY_SINGLE; + break; + + case LSM6DS3TR_C_BOTH_SINGLE_DOUBLE: + *val = LSM6DS3TR_C_BOTH_SINGLE_DOUBLE; + break; + + default: + *val = LSM6DS3TR_C_TAP_MODE_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_ Six_position_detection(6D/4D) + * @brief This section groups all the functions concerning six + * position detection (6D). + * @{ + * + */ + +/** + * @brief LPF2 feed 6D function selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of low_pass_on_6d in + * reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_feed_data_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_low_pass_on_6d_t val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + if (ret == 0) + { + ctrl8_xl.low_pass_on_6d = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + } + + return ret; +} + +/** + * @brief LPF2 feed 6D function selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of low_pass_on_6d in reg CTRL8_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_feed_data_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_low_pass_on_6d_t *val) +{ + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, + (uint8_t *)&ctrl8_xl, 1); + + switch (ctrl8_xl.low_pass_on_6d) + { + case LSM6DS3TR_C_ODR_DIV_2_FEED: + *val = LSM6DS3TR_C_ODR_DIV_2_FEED; + break; + + case LSM6DS3TR_C_LPF2_FEED: + *val = LSM6DS3TR_C_LPF2_FEED; + break; + + default: + *val = LSM6DS3TR_C_6D_FEED_ND; + break; + } + + return ret; +} + +/** + * @brief Threshold for 4D/6D function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sixd_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_threshold_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sixd_ths_t val) +{ + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + + if (ret == 0) + { + tap_ths_6d.sixd_ths = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + } + + return ret; +} + +/** + * @brief Threshold for 4D/6D function.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of sixd_ths in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_6d_threshold_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sixd_ths_t *val) +{ + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + + switch (tap_ths_6d.sixd_ths) + { + case LSM6DS3TR_C_DEG_80: + *val = LSM6DS3TR_C_DEG_80; + break; + + case LSM6DS3TR_C_DEG_70: + *val = LSM6DS3TR_C_DEG_70; + break; + + case LSM6DS3TR_C_DEG_60: + *val = LSM6DS3TR_C_DEG_60; + break; + + case LSM6DS3TR_C_DEG_50: + *val = LSM6DS3TR_C_DEG_50; + break; + + default: + *val = LSM6DS3TR_C_6D_TH_ND; + break; + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of d4d_en in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_4d_mode_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + + if (ret == 0) + { + tap_ths_6d.d4d_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of d4d_en in reg TAP_THS_6D + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_4d_mode_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, + (uint8_t *)&tap_ths_6d, 1); + *val = tap_ths_6d.d4d_en; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_free_fall + * @brief This section group all the functions concerning the free + * fall detection. + * @{ + * + */ + +/** + * @brief Free-fall duration event. 1LSb = 1 / ODR[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ff_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_dur_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, + (uint8_t *)&free_fall, 1); + + if (ret == 0) + { + free_fall.ff_dur = (val & 0x1FU); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FREE_FALL, + (uint8_t *)&free_fall, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + wake_up_dur.ff_dur = (val & 0x20U) >> 5; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + } + } + } + + return ret; +} + +/** + * @brief Free-fall duration event. 1LSb = 1 / ODR[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ff_dur in reg WAKE_UP_DUR + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_dur_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, + (uint8_t *)&free_fall, 1); + } + + *val = (wake_up_dur.ff_dur << 5) + free_fall.ff_dur; + + return ret; +} + +/** + * @brief Free fall threshold setting.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ff_ths in reg FREE_FALL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_threshold_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ff_ths_t val) +{ + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, + (uint8_t *)&free_fall, 1); + + if (ret == 0) + { + free_fall.ff_ths = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FREE_FALL, + (uint8_t *)&free_fall, 1); + } + + return ret; +} + +/** + * @brief Free fall threshold setting.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of ff_ths in reg FREE_FALL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_ff_threshold_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ff_ths_t *val) +{ + lsm6ds3tr_c_free_fall_t free_fall; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, + (uint8_t *)&free_fall, 1); + + switch (free_fall.ff_ths) + { + case LSM6DS3TR_C_FF_TSH_156mg: + *val = LSM6DS3TR_C_FF_TSH_156mg; + break; + + case LSM6DS3TR_C_FF_TSH_219mg: + *val = LSM6DS3TR_C_FF_TSH_219mg; + break; + + case LSM6DS3TR_C_FF_TSH_250mg: + *val = LSM6DS3TR_C_FF_TSH_250mg; + break; + + case LSM6DS3TR_C_FF_TSH_312mg: + *val = LSM6DS3TR_C_FF_TSH_312mg; + break; + + case LSM6DS3TR_C_FF_TSH_344mg: + *val = LSM6DS3TR_C_FF_TSH_344mg; + break; + + case LSM6DS3TR_C_FF_TSH_406mg: + *val = LSM6DS3TR_C_FF_TSH_406mg; + break; + + case LSM6DS3TR_C_FF_TSH_469mg: + *val = LSM6DS3TR_C_FF_TSH_469mg; + break; + + case LSM6DS3TR_C_FF_TSH_500mg: + *val = LSM6DS3TR_C_FF_TSH_500mg; + break; + + default: + *val = LSM6DS3TR_C_FF_TSH_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_fifo + * @brief This section group all the functions concerning the + * fifo usage + * @{ + * + */ + +/** + * @brief FIFO watermark level selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fth in reg FIFO_CTRL1 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_watermark_set(const stmdev_ctx_t *ctx, + uint16_t val) +{ + lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + fifo_ctrl1.fth = (uint8_t)(0x00FFU & val); + fifo_ctrl2.fth = (uint8_t)((0x0700U & val) >> 8); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL1, + (uint8_t *)&fifo_ctrl1, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + } + } + + return ret; +} + +/** + * @brief FIFO watermark level selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fth in reg FIFO_CTRL1 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_watermark_get(const stmdev_ctx_t *ctx, + uint16_t *val) +{ + lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL1, + (uint8_t *)&fifo_ctrl1, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + } + + *val = ((uint16_t)fifo_ctrl2.fth << 8) + (uint16_t)fifo_ctrl1.fth; + + return ret; +} + +/** + * @brief FIFO data level.[get] + * + * @param ctx Read / write interface definitions + * @param val get the values of diff_fifo in reg FIFO_STATUS1 and + * FIFO_STATUS2(diff_fifo), it is recommended to set the + * BDU bit. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_data_level_get(const stmdev_ctx_t *ctx, + uint16_t *val) +{ + lsm6ds3tr_c_fifo_status1_t fifo_status1; + lsm6ds3tr_c_fifo_status2_t fifo_status2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS1, + (uint8_t *)&fifo_status1, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS2, + (uint8_t *)&fifo_status2, 1); + *val = ((uint16_t) fifo_status2.diff_fifo << 8) + + (uint16_t) fifo_status1.diff_fifo; + } + + return ret; +} + +/** + * @brief FIFO watermark.[get] + * + * @param ctx Read / write interface definitions + * @param val get the values of watermark in reg FIFO_STATUS2 and + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_wtm_flag_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_fifo_status2_t fifo_status2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS2, + (uint8_t *)&fifo_status2, 1); + *val = fifo_status2.waterm; + + return ret; +} + +/** + * @brief FIFO pattern.[get] + * + * @param ctx Read / write interface definitions + * @param val get the values of fifo_pattern in reg FIFO_STATUS3 and + * FIFO_STATUS4, it is recommended to set the BDU bit + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_pattern_get(const stmdev_ctx_t *ctx, uint16_t *val) +{ + lsm6ds3tr_c_fifo_status3_t fifo_status3; + lsm6ds3tr_c_fifo_status4_t fifo_status4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS3, + (uint8_t *)&fifo_status3, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS4, + (uint8_t *)&fifo_status4, 1); + *val = ((uint16_t)fifo_status4.fifo_pattern << 8) + + fifo_status3.fifo_pattern; + } + + return ret; +} + +/** + * @brief Batching of temperature data[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fifo_temp_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_temp_batch_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + fifo_ctrl2.fifo_temp_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + } + + return ret; +} + +/** + * @brief Batching of temperature data[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fifo_temp_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_temp_batch_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + *val = fifo_ctrl2.fifo_temp_en; + + return ret; +} + +/** + * @brief Trigger signal for FIFO write operation.[set] + * + * @param ctx Read / write interface definitions + * @param val act on FIFO_CTRL2(timer_pedo_fifo_drdy) + * and MASTER_CONFIG(data_valid_sel_fifo) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_write_trigger_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_trigger_fifo_t val) +{ + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + fifo_ctrl2.timer_pedo_fifo_drdy = (uint8_t)val & 0x01U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.data_valid_sel_fifo = (((uint8_t)val & 0x02U) >> 1); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + } + } + + return ret; +} + +/** + * @brief Trigger signal for FIFO write operation.[get] + * + * @param ctx Read / write interface definitions + * @param val act on FIFO_CTRL2(timer_pedo_fifo_drdy) + * and MASTER_CONFIG(data_valid_sel_fifo) + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_write_trigger_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_trigger_fifo_t *val) +{ + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + switch ((fifo_ctrl2.timer_pedo_fifo_drdy << 1) + + fifo_ctrl2. timer_pedo_fifo_drdy) + { + case LSM6DS3TR_C_TRG_XL_GY_DRDY: + *val = LSM6DS3TR_C_TRG_XL_GY_DRDY; + break; + + case LSM6DS3TR_C_TRG_STEP_DETECT: + *val = LSM6DS3TR_C_TRG_STEP_DETECT; + break; + + case LSM6DS3TR_C_TRG_SH_DRDY: + *val = LSM6DS3TR_C_TRG_SH_DRDY; + break; + + default: + *val = LSM6DS3TR_C_TRG_SH_ND; + break; + } + } + + return ret; +} + +/** + * @brief Enable pedometer step counter and timestamp as 4th + * FIFO data set.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_pedo_fifo_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_set( + stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + fifo_ctrl2.timer_pedo_fifo_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + } + + return ret; +} + +/** + * @brief Enable pedometer step counter and timestamp as 4th + * FIFO data set.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of timer_pedo_fifo_en in reg FIFO_CTRL2 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_get( + stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + *val = fifo_ctrl2.timer_pedo_fifo_en; + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) for + * accelerometer data.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_fifo_xl in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_xl_t val) +{ + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, + (uint8_t *)&fifo_ctrl3, 1); + + if (ret == 0) + { + fifo_ctrl3.dec_fifo_xl = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, + (uint8_t *)&fifo_ctrl3, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) for + * accelerometer data.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_fifo_xl in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_xl_t *val) +{ + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, + (uint8_t *)&fifo_ctrl3, 1); + + switch (fifo_ctrl3.dec_fifo_xl) + { + case LSM6DS3TR_C_FIFO_XL_DISABLE: + *val = LSM6DS3TR_C_FIFO_XL_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_XL_NO_DEC: + *val = LSM6DS3TR_C_FIFO_XL_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_2: + *val = LSM6DS3TR_C_FIFO_XL_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_3: + *val = LSM6DS3TR_C_FIFO_XL_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_4: + *val = LSM6DS3TR_C_FIFO_XL_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_8: + *val = LSM6DS3TR_C_FIFO_XL_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_16: + *val = LSM6DS3TR_C_FIFO_XL_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_XL_DEC_32: + *val = LSM6DS3TR_C_FIFO_XL_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_XL_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for gyroscope data.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_fifo_gyro in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_gy_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_gyro_t val) +{ + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, + (uint8_t *)&fifo_ctrl3, 1); + + if (ret == 0) + { + fifo_ctrl3.dec_fifo_gyro = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, + (uint8_t *)&fifo_ctrl3, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for gyroscope data.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_fifo_gyro in reg FIFO_CTRL3 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_gy_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_gyro_t *val) +{ + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, + (uint8_t *)&fifo_ctrl3, 1); + + switch (fifo_ctrl3.dec_fifo_gyro) + { + case LSM6DS3TR_C_FIFO_GY_DISABLE: + *val = LSM6DS3TR_C_FIFO_GY_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_GY_NO_DEC: + *val = LSM6DS3TR_C_FIFO_GY_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_2: + *val = LSM6DS3TR_C_FIFO_GY_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_3: + *val = LSM6DS3TR_C_FIFO_GY_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_4: + *val = LSM6DS3TR_C_FIFO_GY_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_8: + *val = LSM6DS3TR_C_FIFO_GY_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_16: + *val = LSM6DS3TR_C_FIFO_GY_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_GY_DEC_32: + *val = LSM6DS3TR_C_FIFO_GY_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_GY_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for third data set.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_ds3_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds3_fifo_t val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + + if (ret == 0) + { + fifo_ctrl4.dec_ds3_fifo = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for third data set.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_ds3_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds3_fifo_t *val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + + switch (fifo_ctrl4.dec_ds3_fifo) + { + case LSM6DS3TR_C_FIFO_DS3_DISABLE: + *val = LSM6DS3TR_C_FIFO_DS3_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_DS3_NO_DEC: + *val = LSM6DS3TR_C_FIFO_DS3_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_2: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_3: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_4: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_8: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_16: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_DS3_DEC_32: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_DS3_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for fourth data set.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of dec_ds4_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds4_fifo_t val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + + if (ret == 0) + { + fifo_ctrl4.dec_ds4_fifo = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) for + * fourth data set.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of dec_ds4_fifo in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds4_fifo_t *val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + + switch (fifo_ctrl4.dec_ds4_fifo) + { + case LSM6DS3TR_C_FIFO_DS4_DISABLE: + *val = LSM6DS3TR_C_FIFO_DS4_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_DS4_NO_DEC: + *val = LSM6DS3TR_C_FIFO_DS4_NO_DEC; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_2: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_2; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_3: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_3; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_4: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_4; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_8: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_8; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_16: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_16; + break; + + case LSM6DS3TR_C_FIFO_DS4_DEC_32: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_32; + break; + + default: + *val = LSM6DS3TR_C_FIFO_DS4_DEC_ND; + break; + } + + return ret; +} + +/** + * @brief 8-bit data storage in FIFO.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of only_high_data in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + + if (ret == 0) + { + fifo_ctrl4.only_high_data = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief 8-bit data storage in FIFO.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of only_high_data in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + *val = fifo_ctrl4.only_high_data; + + return ret; +} + +/** + * @brief Sensing chain FIFO stop values memorization at threshold + * level.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of stop_on_fth in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + + if (ret == 0) + { + fifo_ctrl4.stop_on_fth = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + } + + return ret; +} + +/** + * @brief Sensing chain FIFO stop values memorization at threshold + * level.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of stop_on_fth in reg FIFO_CTRL4 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, + (uint8_t *)&fifo_ctrl4, 1); + *val = fifo_ctrl4.stop_on_fth; + + return ret; +} + +/** + * @brief FIFO mode selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of fifo_mode in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fifo_mode_t val) +{ + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, + (uint8_t *)&fifo_ctrl5, 1); + + if (ret == 0) + { + fifo_ctrl5.fifo_mode = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, + (uint8_t *)&fifo_ctrl5, 1); + } + + return ret; +} + +/** + * @brief FIFO mode selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of fifo_mode in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fifo_mode_t *val) +{ + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, + (uint8_t *)&fifo_ctrl5, 1); + + switch (fifo_ctrl5.fifo_mode) + { + case LSM6DS3TR_C_BYPASS_MODE: + *val = LSM6DS3TR_C_BYPASS_MODE; + break; + + case LSM6DS3TR_C_FIFO_MODE: + *val = LSM6DS3TR_C_FIFO_MODE; + break; + + case LSM6DS3TR_C_STREAM_TO_FIFO_MODE: + *val = LSM6DS3TR_C_STREAM_TO_FIFO_MODE; + break; + + case LSM6DS3TR_C_BYPASS_TO_STREAM_MODE: + *val = LSM6DS3TR_C_BYPASS_TO_STREAM_MODE; + break; + + case LSM6DS3TR_C_STREAM_MODE: + *val = LSM6DS3TR_C_STREAM_MODE; + break; + + default: + *val = LSM6DS3TR_C_FIFO_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief FIFO ODR selection, setting FIFO_MODE also.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of odr_fifo in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_data_rate_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_fifo_t val) +{ + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, + (uint8_t *)&fifo_ctrl5, 1); + + if (ret == 0) + { + fifo_ctrl5.odr_fifo = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, + (uint8_t *)&fifo_ctrl5, 1); + } + + return ret; +} + +/** + * @brief FIFO ODR selection, setting FIFO_MODE also.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of odr_fifo in reg FIFO_CTRL5 + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_fifo_data_rate_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_fifo_t *val) +{ + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, + (uint8_t *)&fifo_ctrl5, 1); + + switch (fifo_ctrl5.odr_fifo) + { + case LSM6DS3TR_C_FIFO_DISABLE: + *val = LSM6DS3TR_C_FIFO_DISABLE; + break; + + case LSM6DS3TR_C_FIFO_12Hz5: + *val = LSM6DS3TR_C_FIFO_12Hz5; + break; + + case LSM6DS3TR_C_FIFO_26Hz: + *val = LSM6DS3TR_C_FIFO_26Hz; + break; + + case LSM6DS3TR_C_FIFO_52Hz: + *val = LSM6DS3TR_C_FIFO_52Hz; + break; + + case LSM6DS3TR_C_FIFO_104Hz: + *val = LSM6DS3TR_C_FIFO_104Hz; + break; + + case LSM6DS3TR_C_FIFO_208Hz: + *val = LSM6DS3TR_C_FIFO_208Hz; + break; + + case LSM6DS3TR_C_FIFO_416Hz: + *val = LSM6DS3TR_C_FIFO_416Hz; + break; + + case LSM6DS3TR_C_FIFO_833Hz: + *val = LSM6DS3TR_C_FIFO_833Hz; + break; + + case LSM6DS3TR_C_FIFO_1k66Hz: + *val = LSM6DS3TR_C_FIFO_1k66Hz; + break; + + case LSM6DS3TR_C_FIFO_3k33Hz: + *val = LSM6DS3TR_C_FIFO_3k33Hz; + break; + + case LSM6DS3TR_C_FIFO_6k66Hz: + *val = LSM6DS3TR_C_FIFO_6k66Hz; + break; + + default: + *val = LSM6DS3TR_C_FIFO_RATE_ND; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_DEN_functionality + * @brief This section groups all the functions concerning DEN + * functionality. + * @{ + * + */ + +/** + * @brief DEN active level configuration.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_lh in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_polarity_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_lh_t val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + if (ret == 0) + { + ctrl5_c.den_lh = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + } + + return ret; +} + +/** + * @brief DEN active level configuration.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of den_lh in reg CTRL5_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_polarity_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_lh_t *val) +{ + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, + (uint8_t *)&ctrl5_c, 1); + + switch (ctrl5_c.den_lh) + { + case LSM6DS3TR_C_DEN_ACT_LOW: + *val = LSM6DS3TR_C_DEN_ACT_LOW; + break; + + case LSM6DS3TR_C_DEN_ACT_HIGH: + *val = LSM6DS3TR_C_DEN_ACT_HIGH; + break; + + default: + *val = LSM6DS3TR_C_DEN_POL_ND; + break; + } + + return ret; +} + +/** + * @brief DEN functionality marking mode[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_mode_t val) +{ + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + if (ret == 0) + { + ctrl6_c.den_mode = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief DEN functionality marking mode[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_mode in reg CTRL6_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_mode_t *val) +{ + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, + (uint8_t *)&ctrl6_c, 1); + + switch (ctrl6_c.den_mode) + { + case LSM6DS3TR_C_DEN_DISABLE: + *val = LSM6DS3TR_C_DEN_DISABLE; + break; + + case LSM6DS3TR_C_LEVEL_LETCHED: + *val = LSM6DS3TR_C_LEVEL_LETCHED; + break; + + case LSM6DS3TR_C_LEVEL_TRIGGER: + *val = LSM6DS3TR_C_LEVEL_TRIGGER; + break; + + case LSM6DS3TR_C_EDGE_TRIGGER: + *val = LSM6DS3TR_C_EDGE_TRIGGER; + break; + + default: + *val = LSM6DS3TR_C_DEN_MODE_ND; + break; + } + + return ret; +} + +/** + * @brief Extend DEN functionality to accelerometer sensor.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_xl_g in reg CTRL9_XL + * and den_xl_en in CTRL4_C. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_enable_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_xl_en_t val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ctrl9_xl.den_xl_g = (uint8_t)val & 0x01U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ctrl4_c.den_xl_en = (uint8_t)val & 0x02U; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + } + } + + return ret; +} + +/** + * @brief Extend DEN functionality to accelerometer sensor. [get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of den_xl_g in reg CTRL9_XL + * and den_xl_en in CTRL4_C. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_enable_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_xl_en_t *val) +{ + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + switch ((ctrl4_c.den_xl_en << 1) + ctrl9_xl.den_xl_g) + { + case LSM6DS3TR_C_STAMP_IN_GY_DATA: + *val = LSM6DS3TR_C_STAMP_IN_GY_DATA; + break; + + case LSM6DS3TR_C_STAMP_IN_XL_DATA: + *val = LSM6DS3TR_C_STAMP_IN_XL_DATA; + break; + + case LSM6DS3TR_C_STAMP_IN_GY_XL_DATA: + *val = LSM6DS3TR_C_STAMP_IN_GY_XL_DATA; + break; + + default: + *val = LSM6DS3TR_C_DEN_STAMP_ND; + break; + } + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Z-axis.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_z in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_z_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ctrl9_xl.den_z = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Z-axis.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_z in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_z_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + *val = ctrl9_xl.den_z; + + return ret; +} + +/** + * @brief DEN value stored in LSB of Y-axis.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_y in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_y_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ctrl9_xl.den_y = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Y-axis.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_y in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_y_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + *val = ctrl9_xl.den_y; + + return ret; +} + +/** + * @brief DEN value stored in LSB of X-axis.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_x in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_x_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ctrl9_xl.den_x = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of X-axis.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of den_x in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_den_mark_axis_x_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + *val = ctrl9_xl.den_x; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Pedometer + * @brief This section groups all the functions that manage pedometer. + * @{ + * + */ + +/** + * @brief Reset pedometer step counter.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_rst_step in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_step_reset_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.pedo_rst_step = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Reset pedometer step counter.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_rst_step in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_step_reset_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + *val = ctrl10_c.pedo_rst_step; + + return ret; +} + +/** + * @brief Enable pedometer algorithm.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_sens_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.pedo_en = val; + + if (val != 0x00U) + { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief pedo_sens: Enable pedometer algorithm.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_sens_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + *val = ctrl10_c.pedo_en; + + return ret; +} + +/** + * @brief Minimum threshold to detect a peak. Default is 10h.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ths_min in reg + * CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_threshold_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, + (uint8_t *)&config_pedo_ths_min, 1); + + if (ret == 0) + { + config_pedo_ths_min.ths_min = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, + (uint8_t *)&config_pedo_ths_min, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Minimum threshold to detect a peak. Default is 10h.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of ths_min in reg CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, + (uint8_t *)&config_pedo_ths_min, 1); + + if (ret == 0) + { + *val = config_pedo_ths_min.ths_min; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief pedo_full_scale: Pedometer data range.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pedo_fs in + * reg CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_full_scale_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pedo_fs_t val) +{ + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, + (uint8_t *)&config_pedo_ths_min, 1); + + if (ret == 0) + { + config_pedo_ths_min.pedo_fs = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, + (uint8_t *)&config_pedo_ths_min, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Pedometer data range.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of pedo_fs in + * reg CONFIG_PEDO_THS_MIN + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_full_scale_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pedo_fs_t *val) +{ + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, + (uint8_t *)&config_pedo_ths_min, 1); + + if (ret == 0) + { + switch (config_pedo_ths_min.pedo_fs) + { + case LSM6DS3TR_C_PEDO_AT_2g: + *val = LSM6DS3TR_C_PEDO_AT_2g; + break; + + case LSM6DS3TR_C_PEDO_AT_4g: + *val = LSM6DS3TR_C_PEDO_AT_4g; + break; + + default: + *val = LSM6DS3TR_C_PEDO_FS_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Pedometer debounce configuration register (r/w).[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_step in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_debounce_steps_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, + (uint8_t *)&pedo_deb_reg, 1); + + if (ret == 0) + { + pedo_deb_reg.deb_step = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, + (uint8_t *)&pedo_deb_reg, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Pedometer debounce configuration register (r/w).[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_step in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_debounce_steps_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, + (uint8_t *)&pedo_deb_reg, 1); + + if (ret == 0) + { + *val = pedo_deb_reg.deb_step; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Debounce time. If the time between two consecutive steps is + * greater than DEB_TIME*80ms, the debouncer is reactivated. + * Default value: 01101[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_time in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_timeout_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, + (uint8_t *)&pedo_deb_reg, 1); + + if (ret == 0) + { + pedo_deb_reg.deb_time = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, + (uint8_t *)&pedo_deb_reg, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Debounce time. If the time between two consecutive steps is + * greater than DEB_TIME*80ms, the debouncer is reactivated. + * Default value: 01101[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of deb_time in reg PEDO_DEB_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_timeout_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, + (uint8_t *)&pedo_deb_reg, 1); + + if (ret == 0) + { + *val = pedo_deb_reg.deb_time; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Time period register for step detection on delta time (r/w).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_steps_period_set(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_STEP_COUNT_DELTA, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Time period register for step detection on delta time (r/w).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_pedo_steps_period_get(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STEP_COUNT_DELTA, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_significant_motion + * @brief This section groups all the functions that manage the + * significant motion detection. + * @{ + * + */ + +/** + * @brief Enable significant motion detection function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sign_motion_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_sens_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.sign_motion_en = val; + + if (val != 0x00U) + { + ctrl10_c.func_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + } + + return ret; +} + +/** + * @brief Enable significant motion detection function.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of sign_motion_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_sens_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + *val = ctrl10_c.sign_motion_en; + + return ret; +} + +/** + * @brief Significant motion threshold.[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that store significant motion threshold. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_threshold_set(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SM_THS, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Significant motion threshold.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that store significant motion threshold. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_motion_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SM_THS, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_tilt_detection + * @brief This section groups all the functions that manage the tilt + * event detection. + * @{ + * + */ + +/** + * @brief Enable tilt calculation.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_sens_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.tilt_en = val; + + if (val != 0x00U) + { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Enable tilt calculation.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_sens_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + *val = ctrl10_c.tilt_en; + + return ret; +} + +/** + * @brief Enable tilt calculation.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wrist_tilt_sens_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.wrist_tilt_en = val; + + if (val != 0x00U) + { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Enable tilt calculation.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tilt_en in reg CTRL10_C + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_wrist_tilt_sens_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + *val = ctrl10_c.wrist_tilt_en; + + return ret; +} + +/** + * @brief Absolute Wrist Tilt latency register (r/w). + * Absolute wrist tilt latency parameters. + * 1 LSB = 40 ms. Default value: 0Fh (600 ms).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_latency_set(const stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_LAT, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt latency register (r/w). + * Absolute wrist tilt latency parameters. + * 1 LSB = 40 ms. Default value: 0Fh (600 ms).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_latency_get(const stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_LAT, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt threshold register(r/w). + * Absolute wrist tilt threshold parameters. + * 1 LSB = 15.625 mg.Default value: 20h (500 mg).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_threshold_set(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_THS, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt threshold register(r/w). + * Absolute wrist tilt threshold parameters. + * 1 LSB = 15.625 mg.Default value: 20h (500 mg).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_THS, buff, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt mask register (r/w).[set] + * + * @param ctx Read / write interface definitions + * @param val Registers A_WRIST_TILT_MASK + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_src_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_a_wrist_tilt_mask_t *val) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, + (uint8_t *) val, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Absolute Wrist Tilt mask register (r/w).[get] + * + * @param ctx Read / write interface definitions + * @param val Registers A_WRIST_TILT_MASK + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_tilt_src_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_a_wrist_tilt_mask_t *val) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, + (uint8_t *) val, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_ magnetometer_sensor + * @brief This section groups all the functions that manage additional + * magnetometer sensor. + * @{ + * + */ + +/** + * @brief Enable soft-iron correction algorithm for magnetometer.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of soft_en in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ctrl9_xl.soft_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + return ret; +} + +/** + * @brief Enable soft-iron correction algorithm for magnetometer.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of soft_en in reg CTRL9_XL + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + *val = ctrl9_xl.soft_en; + + return ret; +} + +/** + * @brief Enable hard-iron correction algorithm for magnetometer.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of iron_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_hard_iron_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.iron_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + if (val != 0x00U) + { + ctrl10_c.func_en = val; + } + + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + } + } + + return ret; +} + +/** + * @brief Enable hard-iron correction algorithm for magnetometer.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of iron_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_hard_iron_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + *val = master_config.iron_en; + + return ret; +} + +/** + * @brief Soft iron 3x3 matrix. Value are expressed in sign-module format. + * (Es. SVVVVVVVb where S is the sign 0/+1/- and V is the value).[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_mat_set(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MAG_SI_XX, buff, 9); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Soft iron 3x3 matrix. Value are expressed in sign-module format. + * (Es. SVVVVVVVb where S is the sign 0/+1/- and V is the value).[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_soft_iron_mat_get(const stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MAG_SI_XX, buff, 9); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Offset for hard-iron compensation register (r/w). The value is + * expressed as a 16-bit word in two’s complement.[set] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that contains data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_offset_set(const stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + buff[1] = (uint8_t)((uint16_t)val[0] / 256U); + buff[0] = (uint8_t)((uint16_t)val[0] - (buff[1] * 256U)); + buff[3] = (uint8_t)((uint16_t)val[1] / 256U); + buff[2] = (uint8_t)((uint16_t)val[1] - (buff[3] * 256U)); + buff[5] = (uint8_t)((uint16_t)val[2] / 256U); + buff[4] = (uint8_t)((uint16_t)val[2] - (buff[5] * 256U)); + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MAG_OFFX_L, buff, 6); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Offset for hard-iron compensation register(r/w). + * The value is expressed as a 16-bit word in two’s complement.[get] + * + * @param ctx Read / write interface definitions + * @param buff Buffer that stores data read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_mag_offset_get(const stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MAG_OFFX_L, buff, 6); + + if (ret == 0) + { + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DS3TR_C_Sensor_hub + * @brief This section groups all the functions that manage the sensor + * hub functionality. + * @{ + * + */ + +/** + * @brief Enable function.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values func_en + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_func_en_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + + if (ret == 0) + { + ctrl10_c.func_en = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, + (uint8_t *)&ctrl10_c, 1); + } + + return ret; +} + +/** + * @brief Sensor synchronization time frame with the step of 500 ms and + * full range of 5s. Unsigned 8-bit.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tph in reg SENSOR_SYNC_TIME_FRAME + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_frame_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, + (uint8_t *)&sensor_sync_time_frame, 1); + + if (ret == 0) + { + sensor_sync_time_frame.tph = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, + (uint8_t *)&sensor_sync_time_frame, 1); + } + + return ret; +} + +/** + * @brief Sensor synchronization time frame with the step of 500 ms and + * full range of 5s. Unsigned 8-bit.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of tph in reg SENSOR_SYNC_TIME_FRAME + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_frame_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, + (uint8_t *)&sensor_sync_time_frame, 1); + *val = sensor_sync_time_frame.tph; + + return ret; +} + +/** + * @brief Resolution ratio of error code for sensor synchronization.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of rr in reg SENSOR_SYNC_RES_RATIO + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rr_t val) +{ + lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, + (uint8_t *)&sensor_sync_res_ratio, 1); + + if (ret == 0) + { + sensor_sync_res_ratio.rr = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, + (uint8_t *)&sensor_sync_res_ratio, 1); + } + + return ret; +} + +/** + * @brief Resolution ratio of error code for sensor synchronization.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of rr in reg SENSOR_SYNC_RES_RATIO + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rr_t *val) +{ + lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, + (uint8_t *)&sensor_sync_res_ratio, 1); + + switch (sensor_sync_res_ratio.rr) + { + case LSM6DS3TR_C_RES_RATIO_2_11: + *val = LSM6DS3TR_C_RES_RATIO_2_11; + break; + + case LSM6DS3TR_C_RES_RATIO_2_12: + *val = LSM6DS3TR_C_RES_RATIO_2_12; + break; + + case LSM6DS3TR_C_RES_RATIO_2_13: + *val = LSM6DS3TR_C_RES_RATIO_2_13; + break; + + case LSM6DS3TR_C_RES_RATIO_2_14: + *val = LSM6DS3TR_C_RES_RATIO_2_14; + break; + + default: + *val = LSM6DS3TR_C_RES_RATIO_ND; + break; + } + + return ret; +} + +/** + * @brief Sensor hub I2C master enable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_on in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_master_set(const stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.master_on = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + return ret; +} + +/** + * @brief Sensor hub I2C master enable.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_on in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_master_get(const stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + *val = master_config.master_on; + + return ret; +} + +/** + * @brief I2C interface pass-through.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pass_through_mode in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pass_through_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.pass_through_mode = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + return ret; +} + +/** + * @brief I2C interface pass-through.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pass_through_mode in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pass_through_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + *val = master_config.pass_through_mode; + + return ret; +} + +/** + * @brief Master I2C pull-up enable/disable.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of pull_up_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pin_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pull_up_en_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.pull_up_en = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + return ret; +} + +/** + * @brief Master I2C pull-up enable/disable.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of pull_up_en in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_pin_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pull_up_en_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + switch (master_config.pull_up_en) + { + case LSM6DS3TR_C_EXT_PULL_UP: + *val = LSM6DS3TR_C_EXT_PULL_UP; + break; + + case LSM6DS3TR_C_INTERNAL_PULL_UP: + *val = LSM6DS3TR_C_INTERNAL_PULL_UP; + break; + + default: + *val = LSM6DS3TR_C_SH_PIN_MODE; + break; + } + + return ret; +} + +/** + * @brief Sensor hub trigger signal selection.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of start_config in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_syncro_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_start_config_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.start_config = (uint8_t)val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + return ret; +} + +/** + * @brief Sensor hub trigger signal selection.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of start_config in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_syncro_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_start_config_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + switch (master_config.start_config) + { + case LSM6DS3TR_C_XL_GY_DRDY: + *val = LSM6DS3TR_C_XL_GY_DRDY; + break; + + case LSM6DS3TR_C_EXT_ON_INT2_PIN: + *val = LSM6DS3TR_C_EXT_ON_INT2_PIN; + break; + + default: + *val = LSM6DS3TR_C_SH_SYNCRO_ND; + break; + } + + return ret; +} + +/** + * @brief Manage the Master DRDY signal on INT1 pad.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_on_int1 in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_drdy_on_int1_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + + if (ret == 0) + { + master_config.drdy_on_int1 = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + } + + return ret; +} + +/** + * @brief Manage the Master DRDY signal on INT1 pad.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of drdy_on_int1 in reg MASTER_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_drdy_on_int1_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_master_config_t master_config; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, + (uint8_t *)&master_config, 1); + *val = master_config.drdy_on_int1; + + return ret; +} + +/** + * @brief Sensor hub output registers.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure of registers from SENSORHUB1_REG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_read_data_raw_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_emb_sh_read_t *val) +{ + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSORHUB1_REG, + (uint8_t *) & (val->sh_byte_1), 12); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSORHUB13_REG, + (uint8_t *) & (val->sh_byte_13), 6); + } + + return ret; +} + +/** + * @brief Master command code used for stamping for sensor sync.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_cmd_code in + * reg MASTER_CMD_CODE + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_master_cmd_code_t master_cmd_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, + (uint8_t *)&master_cmd_code, 1); + + if (ret == 0) + { + master_cmd_code.master_cmd_code = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, + (uint8_t *)&master_cmd_code, 1); + } + + return ret; +} + +/** + * @brief Master command code used for stamping for sensor sync.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of master_cmd_code in + * reg MASTER_CMD_CODE + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_master_cmd_code_t master_cmd_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, + (uint8_t *)&master_cmd_code, 1); + *val = master_cmd_code.master_cmd_code; + + return ret; +} + +/** + * @brief Error code used for sensor synchronization.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of error_code in + * reg SENS_SYNC_SPI_ERROR_CODE. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_spi_sync_error_set(const stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, + (uint8_t *)&sens_sync_spi_error_code, 1); + + if (ret == 0) + { + sens_sync_spi_error_code.error_code = val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, + (uint8_t *)&sens_sync_spi_error_code, 1); + } + + return ret; +} + +/** + * @brief Error code used for sensor synchronization.[get] + * + * @param ctx Read / write interface definitions + * @param val Change the values of error_code in + * reg SENS_SYNC_SPI_ERROR_CODE. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_spi_sync_error_get(const stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; + int32_t ret; + + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, + (uint8_t *)&sens_sync_spi_error_code, 1); + *val = sens_sync_spi_error_code.error_code; + + return ret; +} + +/** + * @brief Number of external sensors to be read by the sensor hub.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of aux_sens_on in reg SLAVE0_CONFIG. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_aux_sens_on_t val) +{ + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + slave0_config.aux_sens_on = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Number of external sensors to be read by the sensor hub.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of aux_sens_on in reg SLAVE0_CONFIG. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_aux_sens_on_t *val) +{ + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + switch (slave0_config.aux_sens_on) + { + case LSM6DS3TR_C_SLV_0: + *val = LSM6DS3TR_C_SLV_0; + break; + + case LSM6DS3TR_C_SLV_0_1: + *val = LSM6DS3TR_C_SLV_0_1; + break; + + case LSM6DS3TR_C_SLV_0_1_2: + *val = LSM6DS3TR_C_SLV_0_1_2; + break; + + case LSM6DS3TR_C_SLV_0_1_2_3: + *val = LSM6DS3TR_C_SLV_0_1_2_3; + break; + + default: + *val = LSM6DS3TR_C_SLV_EN_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a write.[set] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_data; 8 bit data to write + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_cfg_write(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_write_t *val) +{ + lsm6ds3tr_c_slv0_add_t slv0_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + slv0_add.slave0_add = val->slv0_add; + slv0_add.rw_0 = 0; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_ADD, + (uint8_t *)&slv0_add, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_SUBADD, + &(val->slv0_subadd), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, + LSM6DS3TR_C_DATAWRITE_SRC_MODE_SUB_SLV0, + &(val->slv0_data), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv0_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val) +{ + lsm6ds3tr_c_slave0_config_t slave0_config; + lsm6ds3tr_c_slv0_add_t slv0_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + slv0_add.slave0_add = val->slv_add; + slv0_add.rw_0 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_ADD, + (uint8_t *)&slv0_add, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_SUBADD, + &(val->slv_subadd), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + slave0_config.slave0_numop = val->slv_len; + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 1 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv1_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val) +{ + lsm6ds3tr_c_slave1_config_t slave1_config; + lsm6ds3tr_c_slv1_add_t slv1_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + slv1_add.slave1_add = val->slv_add; + slv1_add.r_1 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV1_ADD, + (uint8_t *)&slv1_add, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV1_SUBADD, + &(val->slv_subadd), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + slave1_config.slave1_numop = val->slv_len; + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 2 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv2_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val) +{ + lsm6ds3tr_c_slv2_add_t slv2_add; + lsm6ds3tr_c_slave2_config_t slave2_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + slv2_add.slave2_add = val->slv_add; + slv2_add.r_2 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV2_ADD, + (uint8_t *)&slv2_add, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV2_SUBADD, + &(val->slv_subadd), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, + (uint8_t *)&slave2_config, 1); + + if (ret == 0) + { + slave2_config.slave2_numop = val->slv_len; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, + (uint8_t *)&slave2_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Configure slave 3 for perform a read.[get] + * + * @param ctx Read / write interface definitions + * @param val Structure that contain: + * - uint8_t slv_add; 8 bit i2c device address + * - uint8_t slv_subadd; 8 bit register device address + * - uint8_t slv_len; num of bit to read + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slv3_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val) +{ + lsm6ds3tr_c_slave3_config_t slave3_config; + lsm6ds3tr_c_slv3_add_t slv3_add; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + slv3_add.slave3_add = val->slv_add; + slv3_add.r_3 = 1; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV3_ADD, + (uint8_t *)&slv3_add, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV3_SUBADD, + (uint8_t *) & (val->slv_subadd), 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, + (uint8_t *)&slave3_config, 1); + + if (ret == 0) + { + slave3_config.slave3_numop = val->slv_len; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, + (uint8_t *)&slave3_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 0 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave0_rate in reg SLAVE0_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_0_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave0_rate_t val) +{ + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + slave0_config.slave0_rate = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 0 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slave0_rate in reg SLAVE0_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_0_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave0_rate_t *val) +{ + lsm6ds3tr_c_slave0_config_t slave0_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, + (uint8_t *)&slave0_config, 1); + + if (ret == 0) + { + switch (slave0_config.slave0_rate) + { + case LSM6DS3TR_C_SL0_NO_DEC: + *val = LSM6DS3TR_C_SL0_NO_DEC; + break; + + case LSM6DS3TR_C_SL0_DEC_2: + *val = LSM6DS3TR_C_SL0_DEC_2; + break; + + case LSM6DS3TR_C_SL0_DEC_4: + *val = LSM6DS3TR_C_SL0_DEC_4; + break; + + case LSM6DS3TR_C_SL0_DEC_8: + *val = LSM6DS3TR_C_SL0_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL0_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Slave 0 write operation is performed only at the first sensor + * hub cycle. + * This is effective if the Aux_sens_on[1:0] field in + * SLAVE0_CONFIG(04h) is set to a value other than 00.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of write_once in reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_write_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_write_once_t val) +{ + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + slave1_config.write_once = (uint8_t) val; + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Slave 0 write operation is performed only at the first sensor + * hub cycle. + * This is effective if the Aux_sens_on[1:0] field in + * SLAVE0_CONFIG(04h) is set to a value other than 00.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of write_once in reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_write_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_write_once_t *val) +{ + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + + if (ret == 0) + { + switch (slave1_config.write_once) + { + case LSM6DS3TR_C_EACH_SH_CYCLE: + *val = LSM6DS3TR_C_EACH_SH_CYCLE; + break; + + case LSM6DS3TR_C_ONLY_FIRST_CYCLE: + *val = LSM6DS3TR_C_ONLY_FIRST_CYCLE; + break; + + default: + *val = LSM6DS3TR_C_SH_WR_MODE_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 1 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave1_rate in reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_1_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave1_rate_t val) +{ + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + + if (ret == 0) + { + slave1_config.slave1_rate = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 1 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions reg SLAVE1_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_1_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave1_rate_t *val) +{ + lsm6ds3tr_c_slave1_config_t slave1_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, + (uint8_t *)&slave1_config, 1); + + if (ret == 0) + { + switch (slave1_config.slave1_rate) + { + case LSM6DS3TR_C_SL1_NO_DEC: + *val = LSM6DS3TR_C_SL1_NO_DEC; + break; + + case LSM6DS3TR_C_SL1_DEC_2: + *val = LSM6DS3TR_C_SL1_DEC_2; + break; + + case LSM6DS3TR_C_SL1_DEC_4: + *val = LSM6DS3TR_C_SL1_DEC_4; + break; + + case LSM6DS3TR_C_SL1_DEC_8: + *val = LSM6DS3TR_C_SL1_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL1_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 2 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave2_rate in reg SLAVE2_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_2_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave2_rate_t val) +{ + lsm6ds3tr_c_slave2_config_t slave2_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, + (uint8_t *)&slave2_config, 1); + + if (ret == 0) + { + slave2_config.slave2_rate = (uint8_t) val; + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, + (uint8_t *)&slave2_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 2 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slave2_rate in reg SLAVE2_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_2_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave2_rate_t *val) +{ + lsm6ds3tr_c_slave2_config_t slave2_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, + (uint8_t *)&slave2_config, 1); + + if (ret == 0) + { + switch (slave2_config.slave2_rate) + { + case LSM6DS3TR_C_SL2_NO_DEC: + *val = LSM6DS3TR_C_SL2_NO_DEC; + break; + + case LSM6DS3TR_C_SL2_DEC_2: + *val = LSM6DS3TR_C_SL2_DEC_2; + break; + + case LSM6DS3TR_C_SL2_DEC_4: + *val = LSM6DS3TR_C_SL2_DEC_4; + break; + + case LSM6DS3TR_C_SL2_DEC_8: + *val = LSM6DS3TR_C_SL2_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL2_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 3 starting from the + * sensor hub trigger.[set] + * + * @param ctx Read / write interface definitions + * @param val Change the values of slave3_rate in reg SLAVE3_CONFIG + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_3_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave3_rate_t val) +{ + lsm6ds3tr_c_slave3_config_t slave3_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, + (uint8_t *)&slave3_config, 1); + slave3_config.slave3_rate = (uint8_t)val; + + if (ret == 0) + { + ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, + (uint8_t *)&slave3_config, 1); + + if (ret == 0) + { + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + } + + return ret; +} + +/** + * @brief Decimation of read operation on Slave 3 starting from the + * sensor hub trigger.[get] + * + * @param ctx Read / write interface definitions + * @param val Get the values of slave3_rate in reg SLAVE3_CONFIG. + * @retval Interface status (MANDATORY: return 0 -> no Error). + * + */ +int32_t lsm6ds3tr_c_sh_slave_3_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave3_rate_t *val) +{ + lsm6ds3tr_c_slave3_config_t slave3_config; + int32_t ret; + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); + + if (ret == 0) + { + ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, + (uint8_t *)&slave3_config, 1); + + if (ret == 0) + { + switch (slave3_config.slave3_rate) + { + case LSM6DS3TR_C_SL3_NO_DEC: + *val = LSM6DS3TR_C_SL3_NO_DEC; + break; + + case LSM6DS3TR_C_SL3_DEC_2: + *val = LSM6DS3TR_C_SL3_DEC_2; + break; + + case LSM6DS3TR_C_SL3_DEC_4: + *val = LSM6DS3TR_C_SL3_DEC_4; + break; + + case LSM6DS3TR_C_SL3_DEC_8: + *val = LSM6DS3TR_C_SL3_DEC_8; + break; + + default: + *val = LSM6DS3TR_C_SL3_DEC_ND; + break; + } + + ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @} + * + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.h b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.h new file mode 100644 index 00000000000..3411c79091a --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.h @@ -0,0 +1,2804 @@ +/** + ****************************************************************************** + * @file lsm6ds3tr_c_reg.h + * @author Sensors Software Solution Team + * @brief This file contains all the functions prototypes for the + * lsm6ds3tr_c_reg.c driver. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef LSM6DS3TR_C_DRIVER_H +#define LSM6DS3TR_C_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include + +/** @addtogroup LSM6DS3TR_C + * @{ + * + */ + +/** @defgroup Endianness definitions + * @{ + * + */ + +#ifndef DRV_BYTE_ORDER +#ifndef __BYTE_ORDER__ + +#define DRV_LITTLE_ENDIAN 1234 +#define DRV_BIG_ENDIAN 4321 + +/** if _BYTE_ORDER is not defined, choose the endianness of your architecture + * by uncommenting the define which fits your platform endianness + */ +//#define DRV_BYTE_ORDER DRV_BIG_ENDIAN +#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN + +#else /* defined __BYTE_ORDER__ */ + +#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#define DRV_BYTE_ORDER __BYTE_ORDER__ + +#endif /* __BYTE_ORDER__*/ +#endif /* DRV_BYTE_ORDER */ + +/** + * @} + * + */ + +/** @defgroup STMicroelectronics sensors common types + * @{ + * + */ + +#ifndef MEMS_SHARED_TYPES +#define MEMS_SHARED_TYPES + +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} bitwise_t; + +#define PROPERTY_DISABLE (0U) +#define PROPERTY_ENABLE (1U) + +/** @addtogroup Interfaces_Functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +typedef int32_t (*stmdev_write_ptr)(void *, uint8_t, const uint8_t *, uint16_t); +typedef int32_t (*stmdev_read_ptr)(void *, uint8_t, uint8_t *, uint16_t); +typedef void (*stmdev_mdelay_ptr)(uint32_t millisec); + +typedef struct +{ + /** Component mandatory fields **/ + stmdev_write_ptr write_reg; + stmdev_read_ptr read_reg; + /** Component optional fields **/ + stmdev_mdelay_ptr mdelay; + /** Customizable optional pointer **/ + void *handle; +} stmdev_ctx_t; + +/** + * @} + * + */ + +#endif /* MEMS_SHARED_TYPES */ + +#ifndef MEMS_UCF_SHARED_TYPES +#define MEMS_UCF_SHARED_TYPES + +/** @defgroup Generic address-data structure definition + * @brief This structure is useful to load a predefined configuration + * of a sensor. + * You can create a sensor configuration by your own or using + * Unico / Unicleo tools available on STMicroelectronics + * web site. + * + * @{ + * + */ + +typedef struct +{ + uint8_t address; + uint8_t data; +} ucf_line_t; + +/** + * @} + * + */ + +#endif /* MEMS_UCF_SHARED_TYPES */ + +/** + * @} + * + */ + +/** @defgroup LSM6DS3TR_C_Infos + * @{ + * + */ + +/** I2C Device Address 8 bit format if SA0=0 -> D5 if SA0=1 -> D7 **/ +#define LSM6DS3TR_C_I2C_ADD_L 0xD5U +#define LSM6DS3TR_C_I2C_ADD_H 0xD7U + +/** Device Identification (Who am I) **/ +#define LSM6DS3TR_C_ID 0x6AU + +/** + * @} + * + */ + +#define LSM6DS3TR_C_FUNC_CFG_ACCESS 0x01U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 5; + uint8_t func_cfg_en : 3; /* func_cfg_en + func_cfg_en_b */ +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t func_cfg_en : 3; /* func_cfg_en + func_cfg_en_b */ + uint8_t not_used_01 : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_func_cfg_access_t; + +#define LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME 0x04U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tph : 4; + uint8_t not_used_01 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 4; + uint8_t tph : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensor_sync_time_frame_t; + +#define LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO 0x05U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t rr : 2; + uint8_t not_used_01 : 6; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 6; + uint8_t rr : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensor_sync_res_ratio_t; + +#define LSM6DS3TR_C_FIFO_CTRL1 0x06U +typedef struct +{ + uint8_t fth : 8; /* + FIFO_CTRL2(fth) */ +} lsm6ds3tr_c_fifo_ctrl1_t; + +#define LSM6DS3TR_C_FIFO_CTRL2 0x07U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fth : 3; /* + FIFO_CTRL1(fth) */ + uint8_t fifo_temp_en : 1; + uint8_t not_used_01 : 2; + uint8_t timer_pedo_fifo_drdy : 1; + uint8_t timer_pedo_fifo_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t timer_pedo_fifo_en : 1; + uint8_t timer_pedo_fifo_drdy : 1; + uint8_t not_used_01 : 2; + uint8_t fifo_temp_en : 1; + uint8_t fth : 3; /* + FIFO_CTRL1(fth) */ +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl2_t; + +#define LSM6DS3TR_C_FIFO_CTRL3 0x08U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t dec_fifo_xl : 3; + uint8_t dec_fifo_gyro : 3; + uint8_t not_used_01 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 2; + uint8_t dec_fifo_gyro : 3; + uint8_t dec_fifo_xl : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl3_t; + +#define LSM6DS3TR_C_FIFO_CTRL4 0x09U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t dec_ds3_fifo : 3; + uint8_t dec_ds4_fifo : 3; + uint8_t only_high_data : 1; + uint8_t stop_on_fth : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t stop_on_fth : 1; + uint8_t only_high_data : 1; + uint8_t dec_ds4_fifo : 3; + uint8_t dec_ds3_fifo : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl4_t; + +#define LSM6DS3TR_C_FIFO_CTRL5 0x0AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fifo_mode : 3; + uint8_t odr_fifo : 4; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t odr_fifo : 4; + uint8_t fifo_mode : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_ctrl5_t; + +#define LSM6DS3TR_C_DRDY_PULSE_CFG_G 0x0BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_wrist_tilt : 1; + uint8_t not_used_01 : 6; + uint8_t drdy_pulsed : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t drdy_pulsed : 1; + uint8_t not_used_01 : 6; + uint8_t int2_wrist_tilt : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_drdy_pulse_cfg_g_t; + +#define LSM6DS3TR_C_INT1_CTRL 0x0DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_drdy_xl : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_boot : 1; + uint8_t int1_fth : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_full_flag : 1; + uint8_t int1_sign_mot : 1; + uint8_t int1_step_detector : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_step_detector : 1; + uint8_t int1_sign_mot : 1; + uint8_t int1_full_flag : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_fth : 1; + uint8_t int1_boot : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_drdy_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_int1_ctrl_t; + +#define LSM6DS3TR_C_INT2_CTRL 0x0EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_drdy_xl : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_fth : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_full_flag : 1; + uint8_t int2_step_count_ov : 1; + uint8_t int2_step_delta : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_step_delta : 1; + uint8_t int2_step_count_ov : 1; + uint8_t int2_full_flag : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_fth : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_int2_ctrl_t; + +#define LSM6DS3TR_C_WHO_AM_I 0x0FU +#define LSM6DS3TR_C_CTRL1_XL 0x10U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bw0_xl : 1; + uint8_t lpf1_bw_sel : 1; + uint8_t fs_xl : 2; + uint8_t odr_xl : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_xl : 4; + uint8_t fs_xl : 2; + uint8_t lpf1_bw_sel : 1; + uint8_t bw0_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl1_xl_t; + +#define LSM6DS3TR_C_CTRL2_G 0x11U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t fs_g : 3; /* fs_g + fs_125 */ + uint8_t odr_g : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_g : 4; + uint8_t fs_g : 3; /* fs_g + fs_125 */ + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl2_g_t; + +#define LSM6DS3TR_C_CTRL3_C 0x12U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sw_reset : 1; + uint8_t ble : 1; + uint8_t if_inc : 1; + uint8_t sim : 1; + uint8_t pp_od : 1; + uint8_t h_lactive : 1; + uint8_t bdu : 1; + uint8_t boot : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t boot : 1; + uint8_t bdu : 1; + uint8_t h_lactive : 1; + uint8_t pp_od : 1; + uint8_t sim : 1; + uint8_t if_inc : 1; + uint8_t ble : 1; + uint8_t sw_reset : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl3_c_t; + +#define LSM6DS3TR_C_CTRL4_C 0x13U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t lpf1_sel_g : 1; + uint8_t i2c_disable : 1; + uint8_t drdy_mask : 1; + uint8_t den_drdy_int1 : 1; + uint8_t int2_on_int1 : 1; + uint8_t sleep : 1; + uint8_t den_xl_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_xl_en : 1; + uint8_t sleep : 1; + uint8_t int2_on_int1 : 1; + uint8_t den_drdy_int1 : 1; + uint8_t drdy_mask : 1; + uint8_t i2c_disable : 1; + uint8_t lpf1_sel_g : 1; + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl4_c_t; + +#define LSM6DS3TR_C_CTRL5_C 0x14U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t st_xl : 2; + uint8_t st_g : 2; + uint8_t den_lh : 1; + uint8_t rounding : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t rounding : 3; + uint8_t den_lh : 1; + uint8_t st_g : 2; + uint8_t st_xl : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl5_c_t; + +#define LSM6DS3TR_C_CTRL6_C 0x15U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ftype : 2; + uint8_t not_used_01 : 1; + uint8_t usr_off_w : 1; + uint8_t xl_hm_mode : 1; + uint8_t den_mode : 3; /* trig_en + lvl_en + lvl2_en */ +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_mode : 3; /* trig_en + lvl_en + lvl2_en */ + uint8_t xl_hm_mode : 1; + uint8_t usr_off_w : 1; + uint8_t not_used_01 : 1; + uint8_t ftype : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl6_c_t; + +#define LSM6DS3TR_C_CTRL7_G 0x16U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t rounding_status : 1; + uint8_t not_used_02 : 1; + uint8_t hpm_g : 2; + uint8_t hp_en_g : 1; + uint8_t g_hm_mode : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t g_hm_mode : 1; + uint8_t hp_en_g : 1; + uint8_t hpm_g : 2; + uint8_t not_used_02 : 1; + uint8_t rounding_status : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl7_g_t; + +#define LSM6DS3TR_C_CTRL8_XL 0x17U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t low_pass_on_6d : 1; + uint8_t not_used_01 : 1; + uint8_t hp_slope_xl_en : 1; + uint8_t input_composite : 1; + uint8_t hp_ref_mode : 1; + uint8_t hpcf_xl : 2; + uint8_t lpf2_xl_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t lpf2_xl_en : 1; + uint8_t hpcf_xl : 2; + uint8_t hp_ref_mode : 1; + uint8_t input_composite : 1; + uint8_t hp_slope_xl_en : 1; + uint8_t not_used_01 : 1; + uint8_t low_pass_on_6d : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl8_xl_t; + +#define LSM6DS3TR_C_CTRL9_XL 0x18U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t soft_en : 1; + uint8_t not_used_02 : 1; + uint8_t den_xl_g : 1; + uint8_t den_z : 1; + uint8_t den_y : 1; + uint8_t den_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_x : 1; + uint8_t den_y : 1; + uint8_t den_z : 1; + uint8_t den_xl_g : 1; + uint8_t not_used_02 : 1; + uint8_t soft_en : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl9_xl_t; + +#define LSM6DS3TR_C_CTRL10_C 0x19U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sign_motion_en : 1; + uint8_t pedo_rst_step : 1; + uint8_t func_en : 1; + uint8_t tilt_en : 1; + uint8_t pedo_en : 1; + uint8_t timer_en : 1; + uint8_t not_used_01 : 1; + uint8_t wrist_tilt_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wrist_tilt_en : 1; + uint8_t not_used_01 : 1; + uint8_t timer_en : 1; + uint8_t pedo_en : 1; + uint8_t tilt_en : 1; + uint8_t func_en : 1; + uint8_t pedo_rst_step : 1; + uint8_t sign_motion_en : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_ctrl10_c_t; + +#define LSM6DS3TR_C_MASTER_CONFIG 0x1AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t master_on : 1; + uint8_t iron_en : 1; + uint8_t pass_through_mode : 1; + uint8_t pull_up_en : 1; + uint8_t start_config : 1; + uint8_t not_used_01 : 1; + uint8_t data_valid_sel_fifo : 1; + uint8_t drdy_on_int1 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t drdy_on_int1 : 1; + uint8_t data_valid_sel_fifo : 1; + uint8_t not_used_01 : 1; + uint8_t start_config : 1; + uint8_t pull_up_en : 1; + uint8_t pass_through_mode : 1; + uint8_t iron_en : 1; + uint8_t master_on : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_master_config_t; + +#define LSM6DS3TR_C_WAKE_UP_SRC 0x1BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_wu : 1; + uint8_t y_wu : 1; + uint8_t x_wu : 1; + uint8_t wu_ia : 1; + uint8_t sleep_state_ia : 1; + uint8_t ff_ia : 1; + uint8_t not_used_01 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 2; + uint8_t ff_ia : 1; + uint8_t sleep_state_ia : 1; + uint8_t wu_ia : 1; + uint8_t x_wu : 1; + uint8_t y_wu : 1; + uint8_t z_wu : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wake_up_src_t; + +#define LSM6DS3TR_C_TAP_SRC 0x1CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_tap : 1; + uint8_t y_tap : 1; + uint8_t x_tap : 1; + uint8_t tap_sign : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t tap_ia : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t tap_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t tap_sign : 1; + uint8_t x_tap : 1; + uint8_t y_tap : 1; + uint8_t z_tap : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_tap_src_t; + +#define LSM6DS3TR_C_D6D_SRC 0x1DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xl : 1; + uint8_t xh : 1; + uint8_t yl : 1; + uint8_t yh : 1; + uint8_t zl : 1; + uint8_t zh : 1; + uint8_t d6d_ia : 1; + uint8_t den_drdy : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_drdy : 1; + uint8_t d6d_ia : 1; + uint8_t zh : 1; + uint8_t zl : 1; + uint8_t yh : 1; + uint8_t yl : 1; + uint8_t xh : 1; + uint8_t xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_d6d_src_t; + +#define LSM6DS3TR_C_STATUS_REG 0x1EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xlda : 1; + uint8_t gda : 1; + uint8_t tda : 1; + uint8_t not_used_01 : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 5; + uint8_t tda : 1; + uint8_t gda : 1; + uint8_t xlda : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_status_reg_t; + +#define LSM6DS3TR_C_OUT_TEMP_L 0x20U +#define LSM6DS3TR_C_OUT_TEMP_H 0x21U +#define LSM6DS3TR_C_OUTX_L_G 0x22U +#define LSM6DS3TR_C_OUTX_H_G 0x23U +#define LSM6DS3TR_C_OUTY_L_G 0x24U +#define LSM6DS3TR_C_OUTY_H_G 0x25U +#define LSM6DS3TR_C_OUTZ_L_G 0x26U +#define LSM6DS3TR_C_OUTZ_H_G 0x27U +#define LSM6DS3TR_C_OUTX_L_XL 0x28U +#define LSM6DS3TR_C_OUTX_H_XL 0x29U +#define LSM6DS3TR_C_OUTY_L_XL 0x2AU +#define LSM6DS3TR_C_OUTY_H_XL 0x2BU +#define LSM6DS3TR_C_OUTZ_L_XL 0x2CU +#define LSM6DS3TR_C_OUTZ_H_XL 0x2DU +#define LSM6DS3TR_C_SENSORHUB1_REG 0x2EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub1_reg_t; + +#define LSM6DS3TR_C_SENSORHUB2_REG 0x2FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub2_reg_t; + +#define LSM6DS3TR_C_SENSORHUB3_REG 0x30U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub3_reg_t; + +#define LSM6DS3TR_C_SENSORHUB4_REG 0x31U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub4_reg_t; + +#define LSM6DS3TR_C_SENSORHUB5_REG 0x32U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub5_reg_t; + +#define LSM6DS3TR_C_SENSORHUB6_REG 0x33U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub6_reg_t; + +#define LSM6DS3TR_C_SENSORHUB7_REG 0x34U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub7_reg_t; + +#define LSM6DS3TR_C_SENSORHUB8_REG 0x35U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub8_reg_t; + +#define LSM6DS3TR_C_SENSORHUB9_REG 0x36U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub9_reg_t; + +#define LSM6DS3TR_C_SENSORHUB10_REG 0x37U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub10_reg_t; + +#define LSM6DS3TR_C_SENSORHUB11_REG 0x38U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub11_reg_t; + +#define LSM6DS3TR_C_SENSORHUB12_REG 0x39U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub12_reg_t; + +#define LSM6DS3TR_C_FIFO_STATUS1 0x3AU +typedef struct +{ + uint8_t diff_fifo : 8; /* + FIFO_STATUS2(diff_fifo) */ +} lsm6ds3tr_c_fifo_status1_t; + +#define LSM6DS3TR_C_FIFO_STATUS2 0x3BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t diff_fifo : 3; /* + FIFO_STATUS1(diff_fifo) */ + uint8_t not_used_01 : 1; + uint8_t fifo_empty : 1; + uint8_t fifo_full_smart : 1; + uint8_t over_run : 1; + uint8_t waterm : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t waterm : 1; + uint8_t over_run : 1; + uint8_t fifo_full_smart : 1; + uint8_t fifo_empty : 1; + uint8_t not_used_01 : 1; + uint8_t diff_fifo : 3; /* + FIFO_STATUS1(diff_fifo) */ +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_status2_t; + +#define LSM6DS3TR_C_FIFO_STATUS3 0x3CU +typedef struct +{ + uint8_t fifo_pattern : 8; /* + FIFO_STATUS4(fifo_pattern) */ +} lsm6ds3tr_c_fifo_status3_t; + +#define LSM6DS3TR_C_FIFO_STATUS4 0x3DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fifo_pattern : 2; /* + FIFO_STATUS3(fifo_pattern) */ + uint8_t not_used_01 : 6; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 6; + uint8_t fifo_pattern : 2; /* + FIFO_STATUS3(fifo_pattern) */ +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_fifo_status4_t; + +#define LSM6DS3TR_C_FIFO_DATA_OUT_L 0x3EU +#define LSM6DS3TR_C_FIFO_DATA_OUT_H 0x3FU +#define LSM6DS3TR_C_TIMESTAMP0_REG 0x40U +#define LSM6DS3TR_C_TIMESTAMP1_REG 0x41U +#define LSM6DS3TR_C_TIMESTAMP2_REG 0x42U +#define LSM6DS3TR_C_STEP_TIMESTAMP_L 0x49U +#define LSM6DS3TR_C_STEP_TIMESTAMP_H 0x4AU +#define LSM6DS3TR_C_STEP_COUNTER_L 0x4BU +#define LSM6DS3TR_C_STEP_COUNTER_H 0x4CU + +#define LSM6DS3TR_C_SENSORHUB13_REG 0x4DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub13_reg_t; + +#define LSM6DS3TR_C_SENSORHUB14_REG 0x4EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub14_reg_t; + +#define LSM6DS3TR_C_SENSORHUB15_REG 0x4FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub15_reg_t; + +#define LSM6DS3TR_C_SENSORHUB16_REG 0x50U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub16_reg_t; + +#define LSM6DS3TR_C_SENSORHUB17_REG 0x51U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub17_reg_t; + +#define LSM6DS3TR_C_SENSORHUB18_REG 0x52U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_sensorhub18_reg_t; + +#define LSM6DS3TR_C_FUNC_SRC1 0x53U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sensorhub_end_op : 1; + uint8_t si_end_op : 1; + uint8_t hi_fail : 1; + uint8_t step_overflow : 1; + uint8_t step_detected : 1; + uint8_t tilt_ia : 1; + uint8_t sign_motion_ia : 1; + uint8_t step_count_delta_ia : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t step_count_delta_ia : 1; + uint8_t sign_motion_ia : 1; + uint8_t tilt_ia : 1; + uint8_t step_detected : 1; + uint8_t step_overflow : 1; + uint8_t hi_fail : 1; + uint8_t si_end_op : 1; + uint8_t sensorhub_end_op : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_func_src1_t; + +#define LSM6DS3TR_C_FUNC_SRC2 0x54U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wrist_tilt_ia : 1; + uint8_t not_used_01 : 2; + uint8_t slave0_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave3_nack : 1; + uint8_t not_used_02 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 1; + uint8_t slave3_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave0_nack : 1; + uint8_t not_used_01 : 2; + uint8_t wrist_tilt_ia : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_func_src2_t; + +#define LSM6DS3TR_C_WRIST_TILT_IA 0x55U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t wrist_tilt_ia_zneg : 1; + uint8_t wrist_tilt_ia_zpos : 1; + uint8_t wrist_tilt_ia_yneg : 1; + uint8_t wrist_tilt_ia_ypos : 1; + uint8_t wrist_tilt_ia_xneg : 1; + uint8_t wrist_tilt_ia_xpos : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wrist_tilt_ia_xpos : 1; + uint8_t wrist_tilt_ia_xneg : 1; + uint8_t wrist_tilt_ia_ypos : 1; + uint8_t wrist_tilt_ia_yneg : 1; + uint8_t wrist_tilt_ia_zpos : 1; + uint8_t wrist_tilt_ia_zneg : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wrist_tilt_ia_t; + +#define LSM6DS3TR_C_TAP_CFG 0x58U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t lir : 1; + uint8_t tap_z_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_x_en : 1; + uint8_t slope_fds : 1; + uint8_t inact_en : 2; + uint8_t interrupts_enable : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t interrupts_enable : 1; + uint8_t inact_en : 2; + uint8_t slope_fds : 1; + uint8_t tap_x_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_z_en : 1; + uint8_t lir : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_tap_cfg_t; + +#define LSM6DS3TR_C_TAP_THS_6D 0x59U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_ths : 5; + uint8_t sixd_ths : 2; + uint8_t d4d_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t d4d_en : 1; + uint8_t sixd_ths : 2; + uint8_t tap_ths : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_tap_ths_6d_t; + +#define LSM6DS3TR_C_INT_DUR2 0x5AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t shock : 2; + uint8_t quiet : 2; + uint8_t dur : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t dur : 4; + uint8_t quiet : 2; + uint8_t shock : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_int_dur2_t; + +#define LSM6DS3TR_C_WAKE_UP_THS 0x5BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wk_ths : 6; + uint8_t not_used_01 : 1; + uint8_t single_double_tap : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t single_double_tap : 1; + uint8_t not_used_01 : 1; + uint8_t wk_ths : 6; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wake_up_ths_t; + +#define LSM6DS3TR_C_WAKE_UP_DUR 0x5CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sleep_dur : 4; + uint8_t timer_hr : 1; + uint8_t wake_dur : 2; + uint8_t ff_dur : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 1; + uint8_t wake_dur : 2; + uint8_t timer_hr : 1; + uint8_t sleep_dur : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_wake_up_dur_t; + +#define LSM6DS3TR_C_FREE_FALL 0x5DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ff_ths : 3; + uint8_t ff_dur : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 5; + uint8_t ff_ths : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_free_fall_t; + +#define LSM6DS3TR_C_MD1_CFG 0x5EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_timer : 1; + uint8_t int1_tilt : 1; + uint8_t int1_6d : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_ff : 1; + uint8_t int1_wu : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_inact_state : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_inact_state : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_wu : 1; + uint8_t int1_ff : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_6d : 1; + uint8_t int1_tilt : 1; + uint8_t int1_timer : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_md1_cfg_t; + +#define LSM6DS3TR_C_MD2_CFG 0x5FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_iron : 1; + uint8_t int2_tilt : 1; + uint8_t int2_6d : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_ff : 1; + uint8_t int2_wu : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_inact_state : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_inact_state : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_wu : 1; + uint8_t int2_ff : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_6d : 1; + uint8_t int2_tilt : 1; + uint8_t int2_iron : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_md2_cfg_t; + +#define LSM6DS3TR_C_MASTER_CMD_CODE 0x60U +typedef struct +{ + uint8_t master_cmd_code : 8; +} lsm6ds3tr_c_master_cmd_code_t; + +#define LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE 0x61U +typedef struct +{ + uint8_t error_code : 8; +} lsm6ds3tr_c_sens_sync_spi_error_code_t; + +#define LSM6DS3TR_C_OUT_MAG_RAW_X_L 0x66U +#define LSM6DS3TR_C_OUT_MAG_RAW_X_H 0x67U +#define LSM6DS3TR_C_OUT_MAG_RAW_Y_L 0x68U +#define LSM6DS3TR_C_OUT_MAG_RAW_Y_H 0x69U +#define LSM6DS3TR_C_OUT_MAG_RAW_Z_L 0x6AU +#define LSM6DS3TR_C_OUT_MAG_RAW_Z_H 0x6BU +#define LSM6DS3TR_C_X_OFS_USR 0x73U +#define LSM6DS3TR_C_Y_OFS_USR 0x74U +#define LSM6DS3TR_C_Z_OFS_USR 0x75U +#define LSM6DS3TR_C_SLV0_ADD 0x02U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t rw_0 : 1; + uint8_t slave0_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave0_add : 7; + uint8_t rw_0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv0_add_t; + +#define LSM6DS3TR_C_SLV0_SUBADD 0x03U +typedef struct +{ + uint8_t slave0_reg : 8; +} lsm6ds3tr_c_slv0_subadd_t; + +#define LSM6DS3TR_C_SLAVE0_CONFIG 0x04U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave0_numop : 3; + uint8_t src_mode : 1; + uint8_t aux_sens_on : 2; + uint8_t slave0_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave0_rate : 2; + uint8_t aux_sens_on : 2; + uint8_t src_mode : 1; + uint8_t slave0_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave0_config_t; + +#define LSM6DS3TR_C_SLV1_ADD 0x05U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_1 : 1; + uint8_t slave1_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave1_add : 7; + uint8_t r_1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv1_add_t; + +#define LSM6DS3TR_C_SLV1_SUBADD 0x06U +typedef struct +{ + uint8_t slave1_reg : 8; +} lsm6ds3tr_c_slv1_subadd_t; + +#define LSM6DS3TR_C_SLAVE1_CONFIG 0x07U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave1_numop : 3; + uint8_t not_used_01 : 2; + uint8_t write_once : 1; + uint8_t slave1_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave1_rate : 2; + uint8_t write_once : 1; + uint8_t not_used_01 : 2; + uint8_t slave1_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave1_config_t; + +#define LSM6DS3TR_C_SLV2_ADD 0x08U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_2 : 1; + uint8_t slave2_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave2_add : 7; + uint8_t r_2 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv2_add_t; + +#define LSM6DS3TR_C_SLV2_SUBADD 0x09U +typedef struct +{ + uint8_t slave2_reg : 8; +} lsm6ds3tr_c_slv2_subadd_t; + +#define LSM6DS3TR_C_SLAVE2_CONFIG 0x0AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave2_numop : 3; + uint8_t not_used_01 : 3; + uint8_t slave2_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave2_rate : 2; + uint8_t not_used_01 : 3; + uint8_t slave2_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave2_config_t; + +#define LSM6DS3TR_C_SLV3_ADD 0x0BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_3 : 1; + uint8_t slave3_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave3_add : 7; + uint8_t r_3 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slv3_add_t; + +#define LSM6DS3TR_C_SLV3_SUBADD 0x0CU +typedef struct +{ + uint8_t slave3_reg : 8; +} lsm6ds3tr_c_slv3_subadd_t; + +#define LSM6DS3TR_C_SLAVE3_CONFIG 0x0DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave3_numop : 3; + uint8_t not_used_01 : 3; + uint8_t slave3_rate : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave3_rate : 2; + uint8_t not_used_01 : 3; + uint8_t slave3_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_slave3_config_t; + +#define LSM6DS3TR_C_DATAWRITE_SRC_MODE_SUB_SLV0 0x0EU +typedef struct +{ + uint8_t slave_dataw : 8; +} lsm6ds3tr_c_datawrite_src_mode_sub_slv0_t; + +#define LSM6DS3TR_C_CONFIG_PEDO_THS_MIN 0x0FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ths_min : 5; + uint8_t not_used_01 : 2; + uint8_t pedo_fs : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t pedo_fs : 1; + uint8_t not_used_01 : 2; + uint8_t ths_min : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_config_pedo_ths_min_t; + +#define LSM6DS3TR_C_SM_THS 0x13U +#define LSM6DS3TR_C_PEDO_DEB_REG 0x14U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t deb_step : 3; + uint8_t deb_time : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t deb_time : 5; + uint8_t deb_step : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_pedo_deb_reg_t; + +#define LSM6DS3TR_C_STEP_COUNT_DELTA 0x15U +#define LSM6DS3TR_C_MAG_SI_XX 0x24U +#define LSM6DS3TR_C_MAG_SI_XY 0x25U +#define LSM6DS3TR_C_MAG_SI_XZ 0x26U +#define LSM6DS3TR_C_MAG_SI_YX 0x27U +#define LSM6DS3TR_C_MAG_SI_YY 0x28U +#define LSM6DS3TR_C_MAG_SI_YZ 0x29U +#define LSM6DS3TR_C_MAG_SI_ZX 0x2AU +#define LSM6DS3TR_C_MAG_SI_ZY 0x2BU +#define LSM6DS3TR_C_MAG_SI_ZZ 0x2CU +#define LSM6DS3TR_C_MAG_OFFX_L 0x2DU +#define LSM6DS3TR_C_MAG_OFFX_H 0x2EU +#define LSM6DS3TR_C_MAG_OFFY_L 0x2FU +#define LSM6DS3TR_C_MAG_OFFY_H 0x30U +#define LSM6DS3TR_C_MAG_OFFZ_L 0x31U +#define LSM6DS3TR_C_MAG_OFFZ_H 0x32U +#define LSM6DS3TR_C_A_WRIST_TILT_LAT 0x50U +#define LSM6DS3TR_C_A_WRIST_TILT_THS 0x54U +#define LSM6DS3TR_C_A_WRIST_TILT_MASK 0x59U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t wrist_tilt_mask_zneg : 1; + uint8_t wrist_tilt_mask_zpos : 1; + uint8_t wrist_tilt_mask_yneg : 1; + uint8_t wrist_tilt_mask_ypos : 1; + uint8_t wrist_tilt_mask_xneg : 1; + uint8_t wrist_tilt_mask_xpos : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wrist_tilt_mask_xpos : 1; + uint8_t wrist_tilt_mask_xneg : 1; + uint8_t wrist_tilt_mask_ypos : 1; + uint8_t wrist_tilt_mask_yneg : 1; + uint8_t wrist_tilt_mask_zpos : 1; + uint8_t wrist_tilt_mask_zneg : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6ds3tr_c_a_wrist_tilt_mask_t; + +/** + * @defgroup LSM6DS3TR_C_Register_Union + * @brief This union group all the registers having a bit-field + * description. + * This union is useful but it's not needed by the driver. + * + * REMOVING this union you are compliant with: + * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " + * + * @{ + * + */ +typedef union +{ + lsm6ds3tr_c_func_cfg_access_t func_cfg_access; + lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; + lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; + lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; + lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; + lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; + lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; + lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; + lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; + lsm6ds3tr_c_int1_ctrl_t int1_ctrl; + lsm6ds3tr_c_int2_ctrl_t int2_ctrl; + lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; + lsm6ds3tr_c_ctrl2_g_t ctrl2_g; + lsm6ds3tr_c_ctrl3_c_t ctrl3_c; + lsm6ds3tr_c_ctrl4_c_t ctrl4_c; + lsm6ds3tr_c_ctrl5_c_t ctrl5_c; + lsm6ds3tr_c_ctrl6_c_t ctrl6_c; + lsm6ds3tr_c_ctrl7_g_t ctrl7_g; + lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; + lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; + lsm6ds3tr_c_ctrl10_c_t ctrl10_c; + lsm6ds3tr_c_master_config_t master_config; + lsm6ds3tr_c_wake_up_src_t wake_up_src; + lsm6ds3tr_c_tap_src_t tap_src; + lsm6ds3tr_c_d6d_src_t d6d_src; + lsm6ds3tr_c_status_reg_t status_reg; + lsm6ds3tr_c_sensorhub1_reg_t sensorhub1_reg; + lsm6ds3tr_c_sensorhub2_reg_t sensorhub2_reg; + lsm6ds3tr_c_sensorhub3_reg_t sensorhub3_reg; + lsm6ds3tr_c_sensorhub4_reg_t sensorhub4_reg; + lsm6ds3tr_c_sensorhub5_reg_t sensorhub5_reg; + lsm6ds3tr_c_sensorhub6_reg_t sensorhub6_reg; + lsm6ds3tr_c_sensorhub7_reg_t sensorhub7_reg; + lsm6ds3tr_c_sensorhub8_reg_t sensorhub8_reg; + lsm6ds3tr_c_sensorhub9_reg_t sensorhub9_reg; + lsm6ds3tr_c_sensorhub10_reg_t sensorhub10_reg; + lsm6ds3tr_c_sensorhub11_reg_t sensorhub11_reg; + lsm6ds3tr_c_sensorhub12_reg_t sensorhub12_reg; + lsm6ds3tr_c_fifo_status1_t fifo_status1; + lsm6ds3tr_c_fifo_status2_t fifo_status2; + lsm6ds3tr_c_fifo_status3_t fifo_status3; + lsm6ds3tr_c_fifo_status4_t fifo_status4; + lsm6ds3tr_c_sensorhub13_reg_t sensorhub13_reg; + lsm6ds3tr_c_sensorhub14_reg_t sensorhub14_reg; + lsm6ds3tr_c_sensorhub15_reg_t sensorhub15_reg; + lsm6ds3tr_c_sensorhub16_reg_t sensorhub16_reg; + lsm6ds3tr_c_sensorhub17_reg_t sensorhub17_reg; + lsm6ds3tr_c_sensorhub18_reg_t sensorhub18_reg; + lsm6ds3tr_c_func_src1_t func_src1; + lsm6ds3tr_c_func_src2_t func_src2; + lsm6ds3tr_c_wrist_tilt_ia_t wrist_tilt_ia; + lsm6ds3tr_c_tap_cfg_t tap_cfg; + lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; + lsm6ds3tr_c_int_dur2_t int_dur2; + lsm6ds3tr_c_wake_up_ths_t wake_up_ths; + lsm6ds3tr_c_wake_up_dur_t wake_up_dur; + lsm6ds3tr_c_free_fall_t free_fall; + lsm6ds3tr_c_md1_cfg_t md1_cfg; + lsm6ds3tr_c_md2_cfg_t md2_cfg; + lsm6ds3tr_c_master_cmd_code_t master_cmd_code; + lsm6ds3tr_c_sens_sync_spi_error_code_t + sens_sync_spi_error_code; + lsm6ds3tr_c_slv0_add_t slv0_add; + lsm6ds3tr_c_slv0_subadd_t slv0_subadd; + lsm6ds3tr_c_slave0_config_t slave0_config; + lsm6ds3tr_c_slv1_add_t slv1_add; + lsm6ds3tr_c_slv1_subadd_t slv1_subadd; + lsm6ds3tr_c_slave1_config_t slave1_config; + lsm6ds3tr_c_slv2_add_t slv2_add; + lsm6ds3tr_c_slv2_subadd_t slv2_subadd; + lsm6ds3tr_c_slave2_config_t slave2_config; + lsm6ds3tr_c_slv3_add_t slv3_add; + lsm6ds3tr_c_slv3_subadd_t slv3_subadd; + lsm6ds3tr_c_slave3_config_t slave3_config; + lsm6ds3tr_c_datawrite_src_mode_sub_slv0_t + datawrite_src_mode_sub_slv0; + lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; + lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; + lsm6ds3tr_c_a_wrist_tilt_mask_t a_wrist_tilt_mask; + bitwise_t bitwise; + uint8_t byte; +} lsm6ds3tr_c_reg_t; + +/** + * @} + * + */ + +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ + +/* + * These are the basic platform dependent I/O routines to read + * and write device registers connected on a standard bus. + * The driver keeps offering a default implementation based on function + * pointers to read/write routines for backward compatibility. + * The __weak directive allows the final application to overwrite + * them with a custom implementation. + */ + +int32_t lsm6ds3tr_c_read_reg(const stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len); +int32_t lsm6ds3tr_c_write_reg(const stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len); + +float_t lsm6ds3tr_c_from_fs2g_to_mg(int16_t lsb); +float_t lsm6ds3tr_c_from_fs4g_to_mg(int16_t lsb); +float_t lsm6ds3tr_c_from_fs8g_to_mg(int16_t lsb); +float_t lsm6ds3tr_c_from_fs16g_to_mg(int16_t lsb); + +float_t lsm6ds3tr_c_from_fs125dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs250dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs500dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs1000dps_to_mdps(int16_t lsb); +float_t lsm6ds3tr_c_from_fs2000dps_to_mdps(int16_t lsb); + +float_t lsm6ds3tr_c_from_lsb_to_celsius(int16_t lsb); + +typedef enum +{ + LSM6DS3TR_C_2g = 0, + LSM6DS3TR_C_16g = 1, + LSM6DS3TR_C_4g = 2, + LSM6DS3TR_C_8g = 3, + LSM6DS3TR_C_XL_FS_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_fs_xl_t; +int32_t lsm6ds3tr_c_xl_full_scale_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_xl_t val); +int32_t lsm6ds3tr_c_xl_full_scale_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_xl_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_ODR_OFF = 0, + LSM6DS3TR_C_XL_ODR_12Hz5 = 1, + LSM6DS3TR_C_XL_ODR_26Hz = 2, + LSM6DS3TR_C_XL_ODR_52Hz = 3, + LSM6DS3TR_C_XL_ODR_104Hz = 4, + LSM6DS3TR_C_XL_ODR_208Hz = 5, + LSM6DS3TR_C_XL_ODR_416Hz = 6, + LSM6DS3TR_C_XL_ODR_833Hz = 7, + LSM6DS3TR_C_XL_ODR_1k66Hz = 8, + LSM6DS3TR_C_XL_ODR_3k33Hz = 9, + LSM6DS3TR_C_XL_ODR_6k66Hz = 10, + LSM6DS3TR_C_XL_ODR_1Hz6 = 11, + LSM6DS3TR_C_XL_ODR_ND = 12, /* ERROR CODE */ +} lsm6ds3tr_c_odr_xl_t; +int32_t lsm6ds3tr_c_xl_data_rate_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_xl_t val); +int32_t lsm6ds3tr_c_xl_data_rate_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_xl_t *val); + +typedef enum +{ + LSM6DS3TR_C_250dps = 0, + LSM6DS3TR_C_125dps = 1, + LSM6DS3TR_C_500dps = 2, + LSM6DS3TR_C_1000dps = 4, + LSM6DS3TR_C_2000dps = 6, + LSM6DS3TR_C_GY_FS_ND = 7, /* ERROR CODE */ +} lsm6ds3tr_c_fs_g_t; +int32_t lsm6ds3tr_c_gy_full_scale_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_g_t val); +int32_t lsm6ds3tr_c_gy_full_scale_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fs_g_t *val); + +typedef enum +{ + LSM6DS3TR_C_GY_ODR_OFF = 0, + LSM6DS3TR_C_GY_ODR_12Hz5 = 1, + LSM6DS3TR_C_GY_ODR_26Hz = 2, + LSM6DS3TR_C_GY_ODR_52Hz = 3, + LSM6DS3TR_C_GY_ODR_104Hz = 4, + LSM6DS3TR_C_GY_ODR_208Hz = 5, + LSM6DS3TR_C_GY_ODR_416Hz = 6, + LSM6DS3TR_C_GY_ODR_833Hz = 7, + LSM6DS3TR_C_GY_ODR_1k66Hz = 8, + LSM6DS3TR_C_GY_ODR_3k33Hz = 9, + LSM6DS3TR_C_GY_ODR_6k66Hz = 10, + LSM6DS3TR_C_GY_ODR_ND = 11, /* ERROR CODE */ +} lsm6ds3tr_c_odr_g_t; +int32_t lsm6ds3tr_c_gy_data_rate_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_g_t val); +int32_t lsm6ds3tr_c_gy_data_rate_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_g_t *val); + +int32_t lsm6ds3tr_c_block_data_update_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_block_data_update_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_LSb_1mg = 0, + LSM6DS3TR_C_LSb_16mg = 1, + LSM6DS3TR_C_WEIGHT_ND = 2, +} lsm6ds3tr_c_usr_off_w_t; +int32_t lsm6ds3tr_c_xl_offset_weight_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_usr_off_w_t val); +int32_t lsm6ds3tr_c_xl_offset_weight_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_usr_off_w_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_HIGH_PERFORMANCE = 0, + LSM6DS3TR_C_XL_NORMAL = 1, + LSM6DS3TR_C_XL_PW_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_xl_hm_mode_t; +int32_t lsm6ds3tr_c_xl_power_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_xl_hm_mode_t val); +int32_t lsm6ds3tr_c_xl_power_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_xl_hm_mode_t *val); + +typedef enum +{ + LSM6DS3TR_C_STAT_RND_DISABLE = 0, + LSM6DS3TR_C_STAT_RND_ENABLE = 1, + LSM6DS3TR_C_STAT_RND_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_rounding_status_t; +int32_t lsm6ds3tr_c_rounding_on_status_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_status_t val); +int32_t lsm6ds3tr_c_rounding_on_status_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_status_t *val); + +typedef enum +{ + LSM6DS3TR_C_GY_HIGH_PERFORMANCE = 0, + LSM6DS3TR_C_GY_NORMAL = 1, + LSM6DS3TR_C_GY_PW_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_g_hm_mode_t; +int32_t lsm6ds3tr_c_gy_power_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_g_hm_mode_t val); +int32_t lsm6ds3tr_c_gy_power_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_g_hm_mode_t *val); + +typedef struct +{ + lsm6ds3tr_c_wake_up_src_t wake_up_src; + lsm6ds3tr_c_tap_src_t tap_src; + lsm6ds3tr_c_d6d_src_t d6d_src; + lsm6ds3tr_c_status_reg_t status_reg; + lsm6ds3tr_c_func_src1_t func_src1; + lsm6ds3tr_c_func_src2_t func_src2; + lsm6ds3tr_c_wrist_tilt_ia_t wrist_tilt_ia; + lsm6ds3tr_c_a_wrist_tilt_mask_t a_wrist_tilt_mask; +} lsm6ds3tr_c_all_sources_t; +int32_t lsm6ds3tr_c_all_sources_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_all_sources_t *val); + +int32_t lsm6ds3tr_c_status_reg_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_status_reg_t *val); + +int32_t lsm6ds3tr_c_xl_flag_data_ready_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_gy_flag_data_ready_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_temp_flag_data_ready_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_xl_usr_offset_set(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_xl_usr_offset_get(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_timestamp_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_timestamp_get(const stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_LSB_6ms4 = 0, + LSM6DS3TR_C_LSB_25us = 1, + LSM6DS3TR_C_TS_RES_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_timer_hr_t; +int32_t lsm6ds3tr_c_timestamp_res_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_timer_hr_t val); +int32_t lsm6ds3tr_c_timestamp_res_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_timer_hr_t *val); + +typedef enum +{ + LSM6DS3TR_C_ROUND_DISABLE = 0, + LSM6DS3TR_C_ROUND_XL = 1, + LSM6DS3TR_C_ROUND_GY = 2, + LSM6DS3TR_C_ROUND_GY_XL = 3, + LSM6DS3TR_C_ROUND_SH1_TO_SH6 = 4, + LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6 = 5, + LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12 = 6, + LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6 = 7, + LSM6DS3TR_C_ROUND_OUT_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_rounding_t; +int32_t lsm6ds3tr_c_rounding_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_t val); +int32_t lsm6ds3tr_c_rounding_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rounding_t *val); + +int32_t lsm6ds3tr_c_temperature_raw_get(const stmdev_ctx_t *ctx, + int16_t *val); +int32_t lsm6ds3tr_c_angular_rate_raw_get(const stmdev_ctx_t *ctx, + int16_t *val); +int32_t lsm6ds3tr_c_acceleration_raw_get(const stmdev_ctx_t *ctx, + int16_t *val); + +int32_t lsm6ds3tr_c_mag_calibrated_raw_get(const stmdev_ctx_t *ctx, + int16_t *val); + +int32_t lsm6ds3tr_c_fifo_raw_data_get(const stmdev_ctx_t *ctx, + uint8_t *buffer, + uint8_t len); + +typedef enum +{ + LSM6DS3TR_C_USER_BANK = 0, + LSM6DS3TR_C_BANK_A = 4, + LSM6DS3TR_C_BANK_B = 5, + LSM6DS3TR_C_BANK_ND = 6, /* ERROR CODE */ +} lsm6ds3tr_c_func_cfg_en_t; +int32_t lsm6ds3tr_c_mem_bank_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_func_cfg_en_t val); +int32_t lsm6ds3tr_c_mem_bank_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_func_cfg_en_t *val); + +typedef enum +{ + LSM6DS3TR_C_DRDY_LATCHED = 0, + LSM6DS3TR_C_DRDY_PULSED = 1, + LSM6DS3TR_C_DRDY_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_drdy_pulsed_g_t; +int32_t lsm6ds3tr_c_data_ready_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_drdy_pulsed_g_t val); +int32_t lsm6ds3tr_c_data_ready_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_drdy_pulsed_g_t *val); + +int32_t lsm6ds3tr_c_device_id_get(const stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lsm6ds3tr_c_reset_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_reset_get(const stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_LSB_AT_LOW_ADD = 0, + LSM6DS3TR_C_MSB_AT_LOW_ADD = 1, + LSM6DS3TR_C_DATA_FMT_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_ble_t; +int32_t lsm6ds3tr_c_data_format_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ble_t val); +int32_t lsm6ds3tr_c_data_format_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ble_t *val); + +int32_t lsm6ds3tr_c_auto_increment_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_auto_increment_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_boot_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_boot_get(const stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_ST_DISABLE = 0, + LSM6DS3TR_C_XL_ST_POSITIVE = 1, + LSM6DS3TR_C_XL_ST_NEGATIVE = 2, + LSM6DS3TR_C_XL_ST_ND = 3, /* ERROR CODE */ +} lsm6ds3tr_c_st_xl_t; +int32_t lsm6ds3tr_c_xl_self_test_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_xl_t val); +int32_t lsm6ds3tr_c_xl_self_test_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_xl_t *val); + +typedef enum +{ + LSM6DS3TR_C_GY_ST_DISABLE = 0, + LSM6DS3TR_C_GY_ST_POSITIVE = 1, + LSM6DS3TR_C_GY_ST_NEGATIVE = 3, + LSM6DS3TR_C_GY_ST_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_st_g_t; +int32_t lsm6ds3tr_c_gy_self_test_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_g_t val); +int32_t lsm6ds3tr_c_gy_self_test_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_st_g_t *val); + +int32_t lsm6ds3tr_c_filter_settling_mask_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_filter_settling_mask_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_USE_SLOPE = 0, + LSM6DS3TR_C_USE_HPF = 1, + LSM6DS3TR_C_HP_PATH_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_slope_fds_t; +int32_t lsm6ds3tr_c_xl_hp_path_internal_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slope_fds_t val); +int32_t lsm6ds3tr_c_xl_hp_path_internal_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slope_fds_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_ANA_BW_1k5Hz = 0, + LSM6DS3TR_C_XL_ANA_BW_400Hz = 1, + LSM6DS3TR_C_XL_ANA_BW_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_bw0_xl_t; +int32_t lsm6ds3tr_c_xl_filter_analog_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_bw0_xl_t val); +int32_t lsm6ds3tr_c_xl_filter_analog_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_bw0_xl_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_LP1_ODR_DIV_2 = 0, + LSM6DS3TR_C_XL_LP1_ODR_DIV_4 = 1, + LSM6DS3TR_C_XL_LP1_NA = 2, /* ERROR CODE */ +} lsm6ds3tr_c_lpf1_bw_sel_t; +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_bw_sel_t val); +int32_t lsm6ds3tr_c_xl_lp1_bandwidth_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_bw_sel_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50 = 0x00, + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100 = 0x01, + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9 = 0x02, + LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400 = 0x03, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50 = 0x10, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100 = 0x11, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9 = 0x12, + LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400 = 0x13, + LSM6DS3TR_C_XL_LP_NA = 0x20, /* ERROR CODE */ +} lsm6ds3tr_c_input_composite_t; +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_input_composite_t val); +int32_t lsm6ds3tr_c_xl_lp2_bandwidth_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_input_composite_t *val); + +int32_t lsm6ds3tr_c_xl_reference_mode_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_xl_reference_mode_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_HP_ODR_DIV_4 = 0x00, /* Slope filter */ + LSM6DS3TR_C_XL_HP_ODR_DIV_100 = 0x01, + LSM6DS3TR_C_XL_HP_ODR_DIV_9 = 0x02, + LSM6DS3TR_C_XL_HP_ODR_DIV_400 = 0x03, + LSM6DS3TR_C_XL_HP_NA = 0x10, /* ERROR CODE */ +} lsm6ds3tr_c_hpcf_xl_t; +int32_t lsm6ds3tr_c_xl_hp_bandwidth_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_hpcf_xl_t val); +int32_t lsm6ds3tr_c_xl_hp_bandwidth_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_hpcf_xl_t *val); + +typedef enum +{ + LSM6DS3TR_C_LP2_ONLY = 0x00, + + LSM6DS3TR_C_HP_16mHz_LP2 = 0x80, + LSM6DS3TR_C_HP_65mHz_LP2 = 0x90, + LSM6DS3TR_C_HP_260mHz_LP2 = 0xA0, + LSM6DS3TR_C_HP_1Hz04_LP2 = 0xB0, + + LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT = 0x0A, + LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL = 0x09, + LSM6DS3TR_C_HP_DISABLE_LP_STRONG = 0x08, + LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE = 0x0B, + + LSM6DS3TR_C_HP_16mHz_LP1_LIGHT = 0x8A, + LSM6DS3TR_C_HP_65mHz_LP1_NORMAL = 0x99, + LSM6DS3TR_C_HP_260mHz_LP1_STRONG = 0xA8, + LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE = 0xBB, + + LSM6DS3TR_C_HP_GY_BAND_NA = 0xFF, /* ERROR CODE */ +} lsm6ds3tr_c_lpf1_sel_g_t; +int32_t lsm6ds3tr_c_gy_band_pass_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_sel_g_t val); +int32_t lsm6ds3tr_c_gy_band_pass_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lpf1_sel_g_t *val); + +typedef enum +{ + LSM6DS3TR_C_SPI_4_WIRE = 0, + LSM6DS3TR_C_SPI_3_WIRE = 1, + LSM6DS3TR_C_SPI_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_sim_t; +int32_t lsm6ds3tr_c_spi_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sim_t val); +int32_t lsm6ds3tr_c_spi_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sim_t *val); + +typedef enum +{ + LSM6DS3TR_C_I2C_ENABLE = 0, + LSM6DS3TR_C_I2C_DISABLE = 1, + LSM6DS3TR_C_I2C_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_i2c_disable_t; +int32_t lsm6ds3tr_c_i2c_interface_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_i2c_disable_t val); +int32_t lsm6ds3tr_c_i2c_interface_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_i2c_disable_t *val); + +typedef struct +{ + uint8_t int1_drdy_xl : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_boot : 1; + uint8_t int1_fth : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_full_flag : 1; + uint8_t int1_sign_mot : 1; + uint8_t int1_step_detector : 1; + uint8_t int1_timer : 1; + uint8_t int1_tilt : 1; + uint8_t int1_6d : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_ff : 1; + uint8_t int1_wu : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_inact_state : 1; + uint8_t den_drdy_int1 : 1; + uint8_t drdy_on_int1 : 1; +} lsm6ds3tr_c_int1_route_t; +int32_t lsm6ds3tr_c_pin_int1_route_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int1_route_t val); +int32_t lsm6ds3tr_c_pin_int1_route_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int1_route_t *val); + +typedef struct +{ + uint8_t int2_drdy_xl : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_fth : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_full_flag : 1; + uint8_t int2_step_count_ov : 1; + uint8_t int2_step_delta : 1; + uint8_t int2_iron : 1; + uint8_t int2_tilt : 1; + uint8_t int2_6d : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_ff : 1; + uint8_t int2_wu : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_inact_state : 1; + uint8_t int2_wrist_tilt : 1; +} lsm6ds3tr_c_int2_route_t; +int32_t lsm6ds3tr_c_pin_int2_route_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int2_route_t val); +int32_t lsm6ds3tr_c_pin_int2_route_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_int2_route_t *val); + +typedef enum +{ + LSM6DS3TR_C_PUSH_PULL = 0, + LSM6DS3TR_C_OPEN_DRAIN = 1, + LSM6DS3TR_C_PIN_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_pp_od_t; +int32_t lsm6ds3tr_c_pin_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pp_od_t val); +int32_t lsm6ds3tr_c_pin_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pp_od_t *val); + +typedef enum +{ + LSM6DS3TR_C_ACTIVE_HIGH = 0, + LSM6DS3TR_C_ACTIVE_LOW = 1, + LSM6DS3TR_C_POLARITY_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_h_lactive_t; +int32_t lsm6ds3tr_c_pin_polarity_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_h_lactive_t val); +int32_t lsm6ds3tr_c_pin_polarity_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_h_lactive_t *val); + +int32_t lsm6ds3tr_c_all_on_int1_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_all_on_int1_get(const stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_INT_PULSED = 0, + LSM6DS3TR_C_INT_LATCHED = 1, + LSM6DS3TR_C_INT_MODE = 2, /* ERROR CODE */ +} lsm6ds3tr_c_lir_t; +int32_t lsm6ds3tr_c_int_notification_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lir_t val); +int32_t lsm6ds3tr_c_int_notification_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_lir_t *val); + +int32_t lsm6ds3tr_c_wkup_threshold_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_wkup_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_wkup_dur_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_wkup_dur_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_gy_sleep_mode_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_gy_sleep_mode_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_PROPERTY_DISABLE = 0, + LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED = 1, + LSM6DS3TR_C_XL_12Hz5_GY_SLEEP = 2, + LSM6DS3TR_C_XL_12Hz5_GY_PD = 3, + LSM6DS3TR_C_ACT_MODE_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_inact_en_t; +int32_t lsm6ds3tr_c_act_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_inact_en_t val); +int32_t lsm6ds3tr_c_act_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_inact_en_t *val); + +int32_t lsm6ds3tr_c_act_sleep_dur_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_act_sleep_dur_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_tap_src_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_tap_src_t *val); + +int32_t lsm6ds3tr_c_tap_detection_on_z_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_tap_detection_on_z_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_tap_detection_on_y_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_tap_detection_on_y_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_tap_detection_on_x_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_tap_detection_on_x_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_tap_threshold_x_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_tap_threshold_x_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_tap_shock_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_shock_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_tap_quiet_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_quiet_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_tap_dur_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_tap_dur_get(const stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_ONLY_SINGLE = 0, + LSM6DS3TR_C_BOTH_SINGLE_DOUBLE = 1, + LSM6DS3TR_C_TAP_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_single_double_tap_t; +int32_t lsm6ds3tr_c_tap_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_single_double_tap_t val); +int32_t lsm6ds3tr_c_tap_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_single_double_tap_t *val); + +typedef enum +{ + LSM6DS3TR_C_ODR_DIV_2_FEED = 0, + LSM6DS3TR_C_LPF2_FEED = 1, + LSM6DS3TR_C_6D_FEED_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_low_pass_on_6d_t; +int32_t lsm6ds3tr_c_6d_feed_data_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_low_pass_on_6d_t val); +int32_t lsm6ds3tr_c_6d_feed_data_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_low_pass_on_6d_t *val); + +typedef enum +{ + LSM6DS3TR_C_DEG_80 = 0, + LSM6DS3TR_C_DEG_70 = 1, + LSM6DS3TR_C_DEG_60 = 2, + LSM6DS3TR_C_DEG_50 = 3, + LSM6DS3TR_C_6D_TH_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_sixd_ths_t; +int32_t lsm6ds3tr_c_6d_threshold_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sixd_ths_t val); +int32_t lsm6ds3tr_c_6d_threshold_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sixd_ths_t *val); + +int32_t lsm6ds3tr_c_4d_mode_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_4d_mode_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_ff_dur_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_ff_dur_get(const stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_FF_TSH_156mg = 0, + LSM6DS3TR_C_FF_TSH_219mg = 1, + LSM6DS3TR_C_FF_TSH_250mg = 2, + LSM6DS3TR_C_FF_TSH_312mg = 3, + LSM6DS3TR_C_FF_TSH_344mg = 4, + LSM6DS3TR_C_FF_TSH_406mg = 5, + LSM6DS3TR_C_FF_TSH_469mg = 6, + LSM6DS3TR_C_FF_TSH_500mg = 7, + LSM6DS3TR_C_FF_TSH_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_ff_ths_t; +int32_t lsm6ds3tr_c_ff_threshold_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ff_ths_t val); +int32_t lsm6ds3tr_c_ff_threshold_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_ff_ths_t *val); + +int32_t lsm6ds3tr_c_fifo_watermark_set(const stmdev_ctx_t *ctx, + uint16_t val); +int32_t lsm6ds3tr_c_fifo_watermark_get(const stmdev_ctx_t *ctx, + uint16_t *val); + +int32_t lsm6ds3tr_c_fifo_data_level_get(const stmdev_ctx_t *ctx, + uint16_t *val); + +int32_t lsm6ds3tr_c_fifo_wtm_flag_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_fifo_pattern_get(const stmdev_ctx_t *ctx, + uint16_t *val); + +int32_t lsm6ds3tr_c_fifo_temp_batch_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_fifo_temp_batch_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_TRG_XL_GY_DRDY = 0, + LSM6DS3TR_C_TRG_STEP_DETECT = 1, + LSM6DS3TR_C_TRG_SH_DRDY = 2, + LSM6DS3TR_C_TRG_SH_ND = 3, /* ERROR CODE */ +} lsm6ds3tr_c_trigger_fifo_t; +int32_t lsm6ds3tr_c_fifo_write_trigger_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_trigger_fifo_t val); +int32_t lsm6ds3tr_c_fifo_write_trigger_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_trigger_fifo_t *val); + +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_set( + stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_get( + stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_FIFO_XL_DISABLE = 0, + LSM6DS3TR_C_FIFO_XL_NO_DEC = 1, + LSM6DS3TR_C_FIFO_XL_DEC_2 = 2, + LSM6DS3TR_C_FIFO_XL_DEC_3 = 3, + LSM6DS3TR_C_FIFO_XL_DEC_4 = 4, + LSM6DS3TR_C_FIFO_XL_DEC_8 = 5, + LSM6DS3TR_C_FIFO_XL_DEC_16 = 6, + LSM6DS3TR_C_FIFO_XL_DEC_32 = 7, + LSM6DS3TR_C_FIFO_XL_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_fifo_xl_t; +int32_t lsm6ds3tr_c_fifo_xl_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_xl_t val); +int32_t lsm6ds3tr_c_fifo_xl_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_xl_t *val); + +typedef enum +{ + LSM6DS3TR_C_FIFO_GY_DISABLE = 0, + LSM6DS3TR_C_FIFO_GY_NO_DEC = 1, + LSM6DS3TR_C_FIFO_GY_DEC_2 = 2, + LSM6DS3TR_C_FIFO_GY_DEC_3 = 3, + LSM6DS3TR_C_FIFO_GY_DEC_4 = 4, + LSM6DS3TR_C_FIFO_GY_DEC_8 = 5, + LSM6DS3TR_C_FIFO_GY_DEC_16 = 6, + LSM6DS3TR_C_FIFO_GY_DEC_32 = 7, + LSM6DS3TR_C_FIFO_GY_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_fifo_gyro_t; +int32_t lsm6ds3tr_c_fifo_gy_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_gyro_t val); +int32_t lsm6ds3tr_c_fifo_gy_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_fifo_gyro_t *val); + +typedef enum +{ + LSM6DS3TR_C_FIFO_DS3_DISABLE = 0, + LSM6DS3TR_C_FIFO_DS3_NO_DEC = 1, + LSM6DS3TR_C_FIFO_DS3_DEC_2 = 2, + LSM6DS3TR_C_FIFO_DS3_DEC_3 = 3, + LSM6DS3TR_C_FIFO_DS3_DEC_4 = 4, + LSM6DS3TR_C_FIFO_DS3_DEC_8 = 5, + LSM6DS3TR_C_FIFO_DS3_DEC_16 = 6, + LSM6DS3TR_C_FIFO_DS3_DEC_32 = 7, + LSM6DS3TR_C_FIFO_DS3_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_ds3_fifo_t; +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds3_fifo_t val); +int32_t lsm6ds3tr_c_fifo_dataset_3_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds3_fifo_t *val); + +typedef enum +{ + LSM6DS3TR_C_FIFO_DS4_DISABLE = 0, + LSM6DS3TR_C_FIFO_DS4_NO_DEC = 1, + LSM6DS3TR_C_FIFO_DS4_DEC_2 = 2, + LSM6DS3TR_C_FIFO_DS4_DEC_3 = 3, + LSM6DS3TR_C_FIFO_DS4_DEC_4 = 4, + LSM6DS3TR_C_FIFO_DS4_DEC_8 = 5, + LSM6DS3TR_C_FIFO_DS4_DEC_16 = 6, + LSM6DS3TR_C_FIFO_DS4_DEC_32 = 7, + LSM6DS3TR_C_FIFO_DS4_DEC_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_dec_ds4_fifo_t; +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds4_fifo_t val); +int32_t lsm6ds3tr_c_fifo_dataset_4_batch_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_dec_ds4_fifo_t *val); + +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_fifo_stop_on_wtm_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_BYPASS_MODE = 0, + LSM6DS3TR_C_FIFO_MODE = 1, + LSM6DS3TR_C_STREAM_TO_FIFO_MODE = 3, + LSM6DS3TR_C_BYPASS_TO_STREAM_MODE = 4, + LSM6DS3TR_C_STREAM_MODE = 6, + LSM6DS3TR_C_FIFO_MODE_ND = 8, /* ERROR CODE */ +} lsm6ds3tr_c_fifo_mode_t; +int32_t lsm6ds3tr_c_fifo_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fifo_mode_t val); +int32_t lsm6ds3tr_c_fifo_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_fifo_mode_t *val); + +typedef enum +{ + LSM6DS3TR_C_FIFO_DISABLE = 0, + LSM6DS3TR_C_FIFO_12Hz5 = 1, + LSM6DS3TR_C_FIFO_26Hz = 2, + LSM6DS3TR_C_FIFO_52Hz = 3, + LSM6DS3TR_C_FIFO_104Hz = 4, + LSM6DS3TR_C_FIFO_208Hz = 5, + LSM6DS3TR_C_FIFO_416Hz = 6, + LSM6DS3TR_C_FIFO_833Hz = 7, + LSM6DS3TR_C_FIFO_1k66Hz = 8, + LSM6DS3TR_C_FIFO_3k33Hz = 9, + LSM6DS3TR_C_FIFO_6k66Hz = 10, + LSM6DS3TR_C_FIFO_RATE_ND = 11, /* ERROR CODE */ +} lsm6ds3tr_c_odr_fifo_t; +int32_t lsm6ds3tr_c_fifo_data_rate_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_fifo_t val); +int32_t lsm6ds3tr_c_fifo_data_rate_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_odr_fifo_t *val); + +typedef enum +{ + LSM6DS3TR_C_DEN_ACT_LOW = 0, + LSM6DS3TR_C_DEN_ACT_HIGH = 1, + LSM6DS3TR_C_DEN_POL_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_den_lh_t; +int32_t lsm6ds3tr_c_den_polarity_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_lh_t val); +int32_t lsm6ds3tr_c_den_polarity_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_lh_t *val); + +typedef enum +{ + LSM6DS3TR_C_DEN_DISABLE = 0, + LSM6DS3TR_C_LEVEL_FIFO = 6, + LSM6DS3TR_C_LEVEL_LETCHED = 3, + LSM6DS3TR_C_LEVEL_TRIGGER = 2, + LSM6DS3TR_C_EDGE_TRIGGER = 4, + LSM6DS3TR_C_DEN_MODE_ND = 5, /* ERROR CODE */ +} lsm6ds3tr_c_den_mode_t; +int32_t lsm6ds3tr_c_den_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_mode_t val); +int32_t lsm6ds3tr_c_den_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_mode_t *val); + +typedef enum +{ + LSM6DS3TR_C_STAMP_IN_GY_DATA = 0, + LSM6DS3TR_C_STAMP_IN_XL_DATA = 1, + LSM6DS3TR_C_STAMP_IN_GY_XL_DATA = 2, + LSM6DS3TR_C_DEN_STAMP_ND = 3, /* ERROR CODE */ +} lsm6ds3tr_c_den_xl_en_t; +int32_t lsm6ds3tr_c_den_enable_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_xl_en_t val); +int32_t lsm6ds3tr_c_den_enable_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_den_xl_en_t *val); + +int32_t lsm6ds3tr_c_den_mark_axis_z_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_den_mark_axis_z_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_den_mark_axis_y_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_den_mark_axis_y_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_den_mark_axis_x_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_den_mark_axis_x_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_pedo_step_reset_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_pedo_step_reset_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_pedo_sens_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_sens_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_pedo_threshold_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_pedo_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_PEDO_AT_2g = 0, + LSM6DS3TR_C_PEDO_AT_4g = 1, + LSM6DS3TR_C_PEDO_FS_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_pedo_fs_t; +int32_t lsm6ds3tr_c_pedo_full_scale_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pedo_fs_t val); +int32_t lsm6ds3tr_c_pedo_full_scale_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pedo_fs_t *val); + +int32_t lsm6ds3tr_c_pedo_debounce_steps_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_pedo_debounce_steps_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_pedo_timeout_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_pedo_timeout_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_pedo_steps_period_set(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_pedo_steps_period_get(const stmdev_ctx_t *ctx, + uint8_t *buff); + +int32_t lsm6ds3tr_c_motion_sens_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_motion_sens_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_motion_threshold_set(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_motion_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *buff); + +int32_t lsm6ds3tr_c_tilt_sens_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_tilt_sens_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_wrist_tilt_sens_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_wrist_tilt_sens_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_tilt_latency_set(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_tilt_latency_get(const stmdev_ctx_t *ctx, + uint8_t *buff); + +int32_t lsm6ds3tr_c_tilt_threshold_set(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_tilt_threshold_get(const stmdev_ctx_t *ctx, + uint8_t *buff); + +int32_t lsm6ds3tr_c_tilt_src_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_a_wrist_tilt_mask_t *val); +int32_t lsm6ds3tr_c_tilt_src_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_a_wrist_tilt_mask_t *val); + +int32_t lsm6ds3tr_c_mag_soft_iron_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_mag_soft_iron_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_mag_hard_iron_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_mag_hard_iron_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_mag_soft_iron_mat_set(const stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6ds3tr_c_mag_soft_iron_mat_get(const stmdev_ctx_t *ctx, + uint8_t *buff); + +int32_t lsm6ds3tr_c_mag_offset_set(const stmdev_ctx_t *ctx, int16_t *val); +int32_t lsm6ds3tr_c_mag_offset_get(const stmdev_ctx_t *ctx, int16_t *val); + +int32_t lsm6ds3tr_c_func_en_set(const stmdev_ctx_t *ctx, uint8_t val); + +int32_t lsm6ds3tr_c_sh_sync_sens_frame_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_sh_sync_sens_frame_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_RES_RATIO_2_11 = 0, + LSM6DS3TR_C_RES_RATIO_2_12 = 1, + LSM6DS3TR_C_RES_RATIO_2_13 = 2, + LSM6DS3TR_C_RES_RATIO_2_14 = 3, + LSM6DS3TR_C_RES_RATIO_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_rr_t; +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rr_t val); +int32_t lsm6ds3tr_c_sh_sync_sens_ratio_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_rr_t *val); + +int32_t lsm6ds3tr_c_sh_master_set(const stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6ds3tr_c_sh_master_get(const stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6ds3tr_c_sh_pass_through_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_sh_pass_through_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_EXT_PULL_UP = 0, + LSM6DS3TR_C_INTERNAL_PULL_UP = 1, + LSM6DS3TR_C_SH_PIN_MODE = 2, /* ERROR CODE */ +} lsm6ds3tr_c_pull_up_en_t; +int32_t lsm6ds3tr_c_sh_pin_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pull_up_en_t val); +int32_t lsm6ds3tr_c_sh_pin_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_pull_up_en_t *val); + +typedef enum +{ + LSM6DS3TR_C_XL_GY_DRDY = 0, + LSM6DS3TR_C_EXT_ON_INT2_PIN = 1, + LSM6DS3TR_C_SH_SYNCRO_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_start_config_t; +int32_t lsm6ds3tr_c_sh_syncro_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_start_config_t val); +int32_t lsm6ds3tr_c_sh_syncro_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_start_config_t *val); + +int32_t lsm6ds3tr_c_sh_drdy_on_int1_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_sh_drdy_on_int1_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef struct +{ + lsm6ds3tr_c_sensorhub1_reg_t sh_byte_1; + lsm6ds3tr_c_sensorhub2_reg_t sh_byte_2; + lsm6ds3tr_c_sensorhub3_reg_t sh_byte_3; + lsm6ds3tr_c_sensorhub4_reg_t sh_byte_4; + lsm6ds3tr_c_sensorhub5_reg_t sh_byte_5; + lsm6ds3tr_c_sensorhub6_reg_t sh_byte_6; + lsm6ds3tr_c_sensorhub7_reg_t sh_byte_7; + lsm6ds3tr_c_sensorhub8_reg_t sh_byte_8; + lsm6ds3tr_c_sensorhub9_reg_t sh_byte_9; + lsm6ds3tr_c_sensorhub10_reg_t sh_byte_10; + lsm6ds3tr_c_sensorhub11_reg_t sh_byte_11; + lsm6ds3tr_c_sensorhub12_reg_t sh_byte_12; + lsm6ds3tr_c_sensorhub13_reg_t sh_byte_13; + lsm6ds3tr_c_sensorhub14_reg_t sh_byte_14; + lsm6ds3tr_c_sensorhub15_reg_t sh_byte_15; + lsm6ds3tr_c_sensorhub16_reg_t sh_byte_16; + lsm6ds3tr_c_sensorhub17_reg_t sh_byte_17; + lsm6ds3tr_c_sensorhub18_reg_t sh_byte_18; +} lsm6ds3tr_c_emb_sh_read_t; +int32_t lsm6ds3tr_c_sh_read_data_raw_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_emb_sh_read_t *val); + +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_sh_cmd_sens_sync_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6ds3tr_c_sh_spi_sync_error_set(const stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6ds3tr_c_sh_spi_sync_error_get(const stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DS3TR_C_SLV_0 = 0, + LSM6DS3TR_C_SLV_0_1 = 1, + LSM6DS3TR_C_SLV_0_1_2 = 2, + LSM6DS3TR_C_SLV_0_1_2_3 = 3, + LSM6DS3TR_C_SLV_EN_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_aux_sens_on_t; +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_aux_sens_on_t val); +int32_t lsm6ds3tr_c_sh_num_of_dev_connected_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_aux_sens_on_t *val); + +typedef struct +{ + uint8_t slv0_add; + uint8_t slv0_subadd; + uint8_t slv0_data; +} lsm6ds3tr_c_sh_cfg_write_t; +int32_t lsm6ds3tr_c_sh_cfg_write(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_write_t *val); + +typedef struct +{ + uint8_t slv_add; + uint8_t slv_subadd; + uint8_t slv_len; +} lsm6ds3tr_c_sh_cfg_read_t; +int32_t lsm6ds3tr_c_sh_slv0_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val); +int32_t lsm6ds3tr_c_sh_slv1_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val); +int32_t lsm6ds3tr_c_sh_slv2_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val); +int32_t lsm6ds3tr_c_sh_slv3_cfg_read(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_sh_cfg_read_t *val); + +typedef enum +{ + LSM6DS3TR_C_SL0_NO_DEC = 0, + LSM6DS3TR_C_SL0_DEC_2 = 1, + LSM6DS3TR_C_SL0_DEC_4 = 2, + LSM6DS3TR_C_SL0_DEC_8 = 3, + LSM6DS3TR_C_SL0_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave0_rate_t; +int32_t lsm6ds3tr_c_sh_slave_0_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave0_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_0_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave0_rate_t *val); + +typedef enum +{ + LSM6DS3TR_C_EACH_SH_CYCLE = 0, + LSM6DS3TR_C_ONLY_FIRST_CYCLE = 1, + LSM6DS3TR_C_SH_WR_MODE_ND = 2, /* ERROR CODE */ +} lsm6ds3tr_c_write_once_t; +int32_t lsm6ds3tr_c_sh_write_mode_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_write_once_t val); +int32_t lsm6ds3tr_c_sh_write_mode_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_write_once_t *val); + +typedef enum +{ + LSM6DS3TR_C_SL1_NO_DEC = 0, + LSM6DS3TR_C_SL1_DEC_2 = 1, + LSM6DS3TR_C_SL1_DEC_4 = 2, + LSM6DS3TR_C_SL1_DEC_8 = 3, + LSM6DS3TR_C_SL1_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave1_rate_t; +int32_t lsm6ds3tr_c_sh_slave_1_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave1_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_1_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave1_rate_t *val); + +typedef enum +{ + LSM6DS3TR_C_SL2_NO_DEC = 0, + LSM6DS3TR_C_SL2_DEC_2 = 1, + LSM6DS3TR_C_SL2_DEC_4 = 2, + LSM6DS3TR_C_SL2_DEC_8 = 3, + LSM6DS3TR_C_SL2_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave2_rate_t; +int32_t lsm6ds3tr_c_sh_slave_2_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave2_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_2_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave2_rate_t *val); + +typedef enum +{ + LSM6DS3TR_C_SL3_NO_DEC = 0, + LSM6DS3TR_C_SL3_DEC_2 = 1, + LSM6DS3TR_C_SL3_DEC_4 = 2, + LSM6DS3TR_C_SL3_DEC_8 = 3, + LSM6DS3TR_C_SL3_DEC_ND = 4, /* ERROR CODE */ +} lsm6ds3tr_c_slave3_rate_t; +int32_t lsm6ds3tr_c_sh_slave_3_dec_set(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave3_rate_t val); +int32_t lsm6ds3tr_c_sh_slave_3_dec_get(const stmdev_ctx_t *ctx, + lsm6ds3tr_c_slave3_rate_t *val); + +/** + * @} + * + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LSM6DS3TR_C_DRIVER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/.gitsubtree b/non_catalog_apps/airmouse/lib/lsm6dso-api/.gitsubtree new file mode 100644 index 00000000000..ea6c0e11285 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/.gitsubtree @@ -0,0 +1 @@ +https://github.com/STMicroelectronics/stm32-lsm6dso main / diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/CODE_OF_CONDUCT.md b/non_catalog_apps/airmouse/lib/lsm6dso-api/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..8f8955aa3ad --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team via this [link](https://www.st.com/content/st_com/en/contact-us.html). +All complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, +available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html). + +For answers to common questions about this code of conduct, see the [FAQ section](https://www.contributor-covenant.org/faq). diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/CONTRIBUTING.md b/non_catalog_apps/airmouse/lib/lsm6dso-api/CONTRIBUTING.md new file mode 100644 index 00000000000..8668d97cbf3 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/CONTRIBUTING.md @@ -0,0 +1,40 @@ +# Contributing guide + +This guide serves as a checklist before contributing to this repository. It mainly focuses on the steps to follow to submit an issue or a pull-request. + +## 1. Issues + +### 1.1 Before opening an issue + +Please check the following points before posting an issue: +* Make sure you are using the latest commit (major releases are tagged, but corrections are available as new commits). +* Make sure your issue is a question/feedback/suggestions **related to** the software provided in this repository. Otherwise, please refer to section [3](CONTRIBUTING.md#3-support-requests-and-questions) below. +* Make sure your issue is not already reported/fixed on GitHub or discussed on a previous issue. Do not forget to browse into the **closed** issues. + +### 1.2 Posting the issue + +When you have checked the previous points, create a new report from the **Issues** tab of this repository. A template is available [here](../../issues/new/choose) to help you report the issue you are facing or the enhancement you would like to propose. + +## 2. Pull Requests + +### 2.1 Before opening a pull-request + +STMicrolectronics is happy to receive contributions from the community, based on an initial Contributor License Agreement (CLA) procedure. + +* If you are an individual writing original source code and you are sure **you own the intellectual property**, then you need to sign an Individual [CLA](https://cla.st.com). +* If you work for a company that wants also to allow you to contribute with your work, your company needs to provide a Corporate [CLA](https://cla.st.com) mentioning your GitHub account name. +* If you are not sure that a CLA (Individual or Corporate) has been signed for your GitHub account you can check the [CLA](https://cla.st.com) dedicated page. + +Please note that: +* The Corporate CLA will always take precedence over the Individual CLA. +* One CLA submission is sufficient, for any project proposed by STMicroelectronics. + +### 2.2 How to proceed + +* We recommend to engage first a communication thru an issue, in order to present your proposal, just to confirm that it corresponds to STMicroelectronics' domain or scope. +* Then fork the project to your GitHub account to further develop your contribution. Please use the latest commit version. +* Please, submit one pull-request per new feature or proposal. This will ease the analysis and the final merge if accepted. + +## 3. Support requests and questions + +For support requests or any other question related to the product, the tools, the environment, you can submit a post to the **ST Community** on the appropriate topic [page](https://community.st.com/s/topiccatalog). diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/LICENSE.md b/non_catalog_apps/airmouse/lib/lsm6dso-api/LICENSE.md new file mode 100644 index 00000000000..e349e2328b7 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2019 STMicroelectronics. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/README.md b/non_catalog_apps/airmouse/lib/lsm6dso-api/README.md new file mode 100644 index 00000000000..1fe67f605fe --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/README.md @@ -0,0 +1,34 @@ +# BSP LSM6DSO Component + +![latest tag](https://img.shields.io/github/v/tag/STMicroelectronics/stm32-lsm6dso.svg?color=brightgreen) + +## Overview + +**STM32Cube** is an STMicroelectronics original initiative to ease the developers life by reducing efforts, time and cost. + +**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series. + * The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product. + * The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio. + * The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series. + * A consistent set of middleware components such as RTOS, USB, FatFS, graphics, touch sensing library... + * A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series. + +Two models of publication are proposed for the STM32Cube embedded software: + * The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series). + * The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions. + +## Description + +This **lsm6dso** MCU component repository is one element **common to all** STM32Cube MCU embedded software packages, providing the **LSM6DSO** BSP MEMS component part. + +## Release note + +Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/lsm6dso/blob/main/Release_Notes.html). + +## Compatibility information + +Please refer to the repository of the BSP **board** driver you are using to know which version of this BSP component driver to use. It is **crucial** that you use a consistent set of versions. + +## Troubleshooting + +Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide. diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/Release_Notes.html b/non_catalog_apps/airmouse/lib/lsm6dso-api/Release_Notes.html new file mode 100644 index 00000000000..4da65558c45 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/Release_Notes.html @@ -0,0 +1,257 @@ + + + + + + + Release Notes for LSM6DSO Component + + + + + + +
+
+
+

Release Notes for +LSM6DSO Component Driver

+

Copyright © 2022 STMicroelectronics
+

+ +
+

Purpose

+

This directory contains the LSM6DSO component drivers.

+
+
+

Update history

+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • Synchronized PID with currently latest version on ST GitHub
  • +
  • Added Delay function
  • +
+

+
+
+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • Synchronized PID with currently latest version on ST GitHub
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Update License to new format
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Fix C++ compiler errors
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Update Release Notes to new format
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Fix issues on INT2 events
  • +
+

+
+
+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • Synchronize PID with latest version on ST GitHub
  • +
+

+
+
+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • Update PID
  • +
+

+
+
+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • Update PID
  • +
  • Add MISRA 2012 compliancy
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Align ODR values like PID
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Rename context type to universal stmdev_ctx_t
  • +
  • Move unions from PID to HLD
  • +
+

+
+
+
+ + +
+

Main changes

+

Patch release

+
    +
  • Update license
  • +
+

+
+
+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • PID update from ST GitHub
  • +
  • Add new APIs for VibrationMonitoring to HLD
  • +
  • HLD coding style update
  • +
+

+
+
+
+ + +
+

Main changes

+

Maintenance release

+
    +
  • Add new APIs
  • +
+

+
+
+
+ + +
+

Main changes

+

First release

+
    +
  • First official release
  • +
+

+
+
+
+
+
+
+
+

For complete documentation on LSM6DSO, visit: LSM6DSO

+
+

Info

+
+
+
+ + diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/SECURITY.md b/non_catalog_apps/airmouse/lib/lsm6dso-api/SECURITY.md new file mode 100644 index 00000000000..b784d151bde --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/SECURITY.md @@ -0,0 +1,31 @@ +# Report potential product security vulnerabilities + +ST places a high priority on security, and our Product Security Incident +Response Team (PSIRT) is committed to rapidly addressing potential security +vulnerabilities affecting our products. PSIRT's long history and vast experience +in security allows ST to perform clear analyses and provide appropriate guidance +on mitigations and solutions when applicable. + +If you wish to report potential security vulnerabilities regarding our products, +**please do not report them through public GitHub issues.** Instead, we +encourage you to report them to our ST PSIRT following the process described at: +**https://www.st.com/content/st_com/en/security/report-vulnerabilities.html** + +### IMPORTANT - READ CAREFULLY: + +STMicroelectronics International N.V., on behalf of itself, its affiliates and +subsidiaries, (collectively “ST”) takes all potential security vulnerability +reports or other related communications (“Report(s)”) seriously. In order to +review Your Report (the terms “You” and “Yours” include your employer, and all +affiliates, subsidiaries and related persons or entities) and take actions as +deemed appropriate, ST requires that we have the rights and Your permission to +do so. + +As such, by submitting Your Report to ST, You agree that You have the right to +do so, and You grant to ST the rights to use the Report for purposes related to +security vulnerability analysis, testing, correction, patching, reporting and +any other related purpose or function. + +By submitting Your Report, You agree that ST’s +[Privacy Policy](https://www.st.com/content/st_com/en/common/privacy-portal.html) +applies to all related communications. diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/favicon.png b/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/mini-st_2020.css b/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/mini-st_2020.css new file mode 100644 index 00000000000..986f4d42050 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/st_logo_2020.png b/non_catalog_apps/airmouse/lib/lsm6dso-api/_htmresc/st_logo_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.c b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.c new file mode 100644 index 00000000000..739d67afddf --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.c @@ -0,0 +1,3909 @@ +/** + ****************************************************************************** + * @file lsm6dso.c + * @author MEMS Software Solutions Team + * @brief LSM6DSO driver file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "lsm6dso.h" + +/** @addtogroup BSP BSP + * @{ + */ + +/** @addtogroup Component Component + * @{ + */ + +/** @defgroup LSM6DSO LSM6DSO + * @{ + */ + +/** @defgroup LSM6DSO_Exported_Variables LSM6DSO Exported Variables + * @{ + */ + +LSM6DSO_CommonDrv_t LSM6DSO_COMMON_Driver = +{ + LSM6DSO_Init, + LSM6DSO_DeInit, + LSM6DSO_ReadID, + LSM6DSO_GetCapabilities, +}; + +LSM6DSO_ACC_Drv_t LSM6DSO_ACC_Driver = +{ + LSM6DSO_ACC_Enable, + LSM6DSO_ACC_Disable, + LSM6DSO_ACC_GetSensitivity, + LSM6DSO_ACC_GetOutputDataRate, + LSM6DSO_ACC_SetOutputDataRate, + LSM6DSO_ACC_GetFullScale, + LSM6DSO_ACC_SetFullScale, + LSM6DSO_ACC_GetAxes, + LSM6DSO_ACC_GetAxesRaw, +}; + +LSM6DSO_GYRO_Drv_t LSM6DSO_GYRO_Driver = +{ + LSM6DSO_GYRO_Enable, + LSM6DSO_GYRO_Disable, + LSM6DSO_GYRO_GetSensitivity, + LSM6DSO_GYRO_GetOutputDataRate, + LSM6DSO_GYRO_SetOutputDataRate, + LSM6DSO_GYRO_GetFullScale, + LSM6DSO_GYRO_SetFullScale, + LSM6DSO_GYRO_GetAxes, + LSM6DSO_GYRO_GetAxesRaw, +}; + +/** + * @} + */ + +/** @defgroup LSM6DSO_Private_Function_Prototypes LSM6DSO Private Function Prototypes + * @{ + */ + +static int32_t LSM6DSO_ACC_SetOutputDataRate_When_Enabled(LSM6DSO_Object_t *pObj, float_t Odr); +static int32_t LSM6DSO_ACC_SetOutputDataRate_When_Disabled(LSM6DSO_Object_t *pObj, float_t Odr); +static int32_t LSM6DSO_GYRO_SetOutputDataRate_When_Enabled(LSM6DSO_Object_t *pObj, float_t Odr); +static int32_t LSM6DSO_GYRO_SetOutputDataRate_When_Disabled(LSM6DSO_Object_t *pObj, float_t Odr); +static void LSM6DSO_Delay(LSM6DSO_Object_t *pObj, uint32_t msDelay); +static int32_t ReadRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length); +static int32_t WriteRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length); + +/** + * @} + */ + +/** @defgroup LSM6DSO_Exported_Functions LSM6DSO Exported Functions + * @{ + */ + +/** + * @brief Register Component Bus IO operations + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_RegisterBusIO(LSM6DSO_Object_t *pObj, LSM6DSO_IO_t *pIO) +{ + int32_t ret = LSM6DSO_OK; + + if (pObj == NULL) + { + ret = LSM6DSO_ERROR; + } + else + { + pObj->IO.Init = pIO->Init; + pObj->IO.DeInit = pIO->DeInit; + pObj->IO.BusType = pIO->BusType; + pObj->IO.Address = pIO->Address; + pObj->IO.WriteReg = pIO->WriteReg; + pObj->IO.ReadReg = pIO->ReadReg; + pObj->IO.GetTick = pIO->GetTick; + + pObj->Ctx.read_reg = ReadRegWrap; + pObj->Ctx.write_reg = WriteRegWrap; + pObj->Ctx.mdelay = pIO->Delay; + pObj->Ctx.handle = pObj; + + if (pObj->IO.Init == NULL) + { + ret = LSM6DSO_ERROR; + } + else if (pObj->IO.Init() != LSM6DSO_OK) + { + ret = LSM6DSO_ERROR; + } + else + { + if (pObj->IO.BusType == LSM6DSO_SPI_3WIRES_BUS) /* SPI 3-Wires */ + { + /* Enable the SPI 3-Wires support only the first time */ + if (pObj->is_initialized == 0U) + { + /* Enable SPI 3-Wires on the component */ + uint8_t data = 0x0C; + + if (LSM6DSO_Write_Reg(pObj, LSM6DSO_CTRL3_C, data) != LSM6DSO_OK) + { + ret = LSM6DSO_ERROR; + } + } + } + } + } + + return ret; +} + +/** + * @brief Initialize the LSM6DSO sensor + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_Init(LSM6DSO_Object_t *pObj) +{ + /* Disable I3C */ + if (lsm6dso_i3c_disable_set(&(pObj->Ctx), LSM6DSO_I3C_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable register address automatically incremented during a multiple byte + access with a serial interface. */ + if (lsm6dso_auto_increment_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable BDU */ + if (lsm6dso_block_data_update_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* FIFO mode selection */ + if (lsm6dso_fifo_mode_set(&(pObj->Ctx), LSM6DSO_BYPASS_MODE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Select default output data rate. */ + pObj->acc_odr = LSM6DSO_XL_ODR_104Hz; + + /* Output data rate selection - power down. */ + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), LSM6DSO_XL_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection. */ + if (lsm6dso_xl_full_scale_set(&(pObj->Ctx), LSM6DSO_2g) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Select default output data rate. */ + pObj->gyro_odr = LSM6DSO_GY_ODR_104Hz; + + /* Output data rate selection - power down. */ + if (lsm6dso_gy_data_rate_set(&(pObj->Ctx), LSM6DSO_GY_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection. */ + if (lsm6dso_gy_full_scale_set(&(pObj->Ctx), LSM6DSO_2000dps) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + pObj->is_initialized = 1; + + return LSM6DSO_OK; +} + +/** + * @brief Deinitialize the LSM6DSO sensor + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_DeInit(LSM6DSO_Object_t *pObj) +{ + /* Disable the component */ + if (LSM6DSO_ACC_Disable(pObj) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (LSM6DSO_GYRO_Disable(pObj) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset output data rate. */ + pObj->acc_odr = LSM6DSO_XL_ODR_OFF; + pObj->gyro_odr = LSM6DSO_GY_ODR_OFF; + + pObj->is_initialized = 0; + + return LSM6DSO_OK; +} + +/** + * @brief Read component ID + * @param pObj the device pObj + * @param Id the WHO_AM_I value + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ReadID(LSM6DSO_Object_t *pObj, uint8_t *Id) +{ + if (lsm6dso_device_id_get(&(pObj->Ctx), Id) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get LSM6DSO sensor capabilities + * @param pObj Component object pointer + * @param Capabilities pointer to LSM6DSO sensor capabilities + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GetCapabilities(LSM6DSO_Object_t *pObj, LSM6DSO_Capabilities_t *Capabilities) +{ + /* Prevent unused argument(s) compilation warning */ + (void)(pObj); + + Capabilities->Acc = 1; + Capabilities->Gyro = 1; + Capabilities->Magneto = 0; + Capabilities->LowPower = 0; + Capabilities->GyroMaxFS = 2000; + Capabilities->AccMaxFS = 16; + Capabilities->MagMaxFS = 0; + Capabilities->GyroMaxOdr = 6660.0f; + Capabilities->AccMaxOdr = 6660.0f; + Capabilities->MagMaxOdr = 0.0f; + return LSM6DSO_OK; +} + +/** + * @brief Enable the LSM6DSO accelerometer sensor + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable(LSM6DSO_Object_t *pObj) +{ + /* Check if the component is already enabled */ + if (pObj->acc_is_enabled == 1U) + { + return LSM6DSO_OK; + } + + /* Output data rate selection. */ + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), pObj->acc_odr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + pObj->acc_is_enabled = 1; + + return LSM6DSO_OK; +} + +/** + * @brief Disable the LSM6DSO accelerometer sensor + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable(LSM6DSO_Object_t *pObj) +{ + /* Check if the component is already disabled */ + if (pObj->acc_is_enabled == 0U) + { + return LSM6DSO_OK; + } + + /* Get current output data rate. */ + if (lsm6dso_xl_data_rate_get(&(pObj->Ctx), &pObj->acc_odr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Output data rate selection - power down. */ + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), LSM6DSO_XL_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + pObj->acc_is_enabled = 0; + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO accelerometer sensor sensitivity + * @param pObj the device pObj + * @param Sensitivity pointer + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_GetSensitivity(LSM6DSO_Object_t *pObj, float_t *Sensitivity) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_fs_xl_t full_scale; + + /* Read actual full scale selection from sensor. */ + if (lsm6dso_xl_full_scale_get(&(pObj->Ctx), &full_scale) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Store the Sensitivity based on actual full scale. */ + switch (full_scale) + { + case LSM6DSO_2g: + *Sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_2G; + break; + + case LSM6DSO_4g: + *Sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_4G; + break; + + case LSM6DSO_8g: + *Sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_8G; + break; + + case LSM6DSO_16g: + *Sensitivity = LSM6DSO_ACC_SENSITIVITY_FS_16G; + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Get the LSM6DSO accelerometer sensor output data rate + * @param pObj the device pObj + * @param Odr pointer where the output data rate is written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_GetOutputDataRate(LSM6DSO_Object_t *pObj, float_t *Odr) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_odr_xl_t odr_low_level; + + /* Get current output data rate. */ + if (lsm6dso_xl_data_rate_get(&(pObj->Ctx), &odr_low_level) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + switch (odr_low_level) + { + case LSM6DSO_XL_ODR_OFF: + *Odr = 0.0f; + break; + + case LSM6DSO_XL_ODR_1Hz6: + *Odr = 1.6f; + break; + + case LSM6DSO_XL_ODR_12Hz5: + *Odr = 12.5f; + break; + + case LSM6DSO_XL_ODR_26Hz: + *Odr = 26.0f; + break; + + case LSM6DSO_XL_ODR_52Hz: + *Odr = 52.0f; + break; + + case LSM6DSO_XL_ODR_104Hz: + *Odr = 104.0f; + break; + + case LSM6DSO_XL_ODR_208Hz: + *Odr = 208.0f; + break; + + case LSM6DSO_XL_ODR_417Hz: + *Odr = 417.0f; + break; + + case LSM6DSO_XL_ODR_833Hz: + *Odr = 833.0f; + break; + + case LSM6DSO_XL_ODR_1667Hz: + *Odr = 1667.0f; + break; + + case LSM6DSO_XL_ODR_3333Hz: + *Odr = 3333.0f; + break; + + case LSM6DSO_XL_ODR_6667Hz: + *Odr = 6667.0f; + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Set the LSM6DSO accelerometer sensor output data rate + * @param pObj the device pObj + * @param Odr the output data rate value to be set + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_SetOutputDataRate(LSM6DSO_Object_t *pObj, float_t Odr) +{ + return LSM6DSO_ACC_SetOutputDataRate_With_Mode(pObj, Odr, LSM6DSO_ACC_HIGH_PERFORMANCE_MODE); +} + +/** + * @brief Set the LSM6DSO accelerometer sensor output data rate with operating mode + * @param pObj the device pObj + * @param Odr the output data rate value to be set + * @param Mode the accelerometer operating mode + * @note This function switches off the gyroscope if Ultra Low Power Mode is set + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_SetOutputDataRate_With_Mode(LSM6DSO_Object_t *pObj, float_t Odr, LSM6DSO_ACC_Operating_Mode_t Mode) +{ + int32_t ret = LSM6DSO_OK; + float_t newOdr = Odr; + + switch (Mode) + { + case LSM6DSO_ACC_HIGH_PERFORMANCE_MODE: + { + /* We must uncheck Low Power and Ultra Low Power bits if they are enabled */ + lsm6dso_ctrl5_c_t val1; + lsm6dso_ctrl6_c_t val2; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL5_C, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val1.xl_ulp_en != 0U) + { + /* Power off the accelerometer */ + if (pObj->acc_is_enabled == 1U) + { + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), LSM6DSO_XL_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + val1.xl_ulp_en = 0; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL5_C, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL6_C, (uint8_t *)&val2, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val2.xl_hm_mode != 0U) + { + val2.xl_hm_mode = 0U; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL6_C, (uint8_t *)&val2, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + /* ODR should be at least 12.5Hz */ + if (newOdr < 12.5f) + { + newOdr = 12.5f; + } + break; + } + case LSM6DSO_ACC_LOW_POWER_NORMAL_MODE: + { + /* We must uncheck Ultra Low Power bit if it is enabled */ + /* and check the Low Power bit if it is unchecked */ + lsm6dso_ctrl5_c_t val1; + lsm6dso_ctrl6_c_t val2; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL5_C, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val1.xl_ulp_en != 0U) + { + /* Power off the accelerometer */ + if (pObj->acc_is_enabled == 1U) + { + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), LSM6DSO_XL_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + val1.xl_ulp_en = 0; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL5_C, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL6_C, (uint8_t *)&val2, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val2.xl_hm_mode == 0U) + { + val2.xl_hm_mode = 1U; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL6_C, (uint8_t *)&val2, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + /* Now we need to limit the ODR to 208 Hz if it is higher */ + if (newOdr > 208.0f) + { + newOdr = 208.0f; + } + break; + } + case LSM6DSO_ACC_ULTRA_LOW_POWER_MODE: + { + /* We must uncheck Low Power bit if it is enabled */ + /* and check the Ultra Low Power bit if it is unchecked */ + /* We must switch off gyro otherwise Ultra Low Power does not work */ + lsm6dso_ctrl5_c_t val1; + lsm6dso_ctrl6_c_t val2; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL6_C, (uint8_t *)&val2, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val2.xl_hm_mode != 0U) + { + val2.xl_hm_mode = 0U; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL6_C, (uint8_t *)&val2, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + /* Disable Gyro */ + if (pObj->gyro_is_enabled == 1U) + { + if (LSM6DSO_GYRO_Disable(pObj) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL5_C, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val1.xl_ulp_en == 0U) + { + /* Power off the accelerometer */ + if (pObj->acc_is_enabled == 1U) + { + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), LSM6DSO_XL_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + val1.xl_ulp_en = 1U; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL5_C, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + /* Now we need to limit the ODR to 208 Hz if it is higher */ + if (newOdr > 208.0f) + { + newOdr = 208.0f; + } + break; + } + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (pObj->acc_is_enabled == 1U) + { + ret = LSM6DSO_ACC_SetOutputDataRate_When_Enabled(pObj, newOdr); + } + else + { + ret = LSM6DSO_ACC_SetOutputDataRate_When_Disabled(pObj, newOdr); + } + + return ret; +} + +/** + * @brief Get the LSM6DSO accelerometer sensor full scale + * @param pObj the device pObj + * @param FullScale pointer where the full scale is written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_GetFullScale(LSM6DSO_Object_t *pObj, int32_t *FullScale) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_fs_xl_t fs_low_level; + + /* Read actual full scale selection from sensor. */ + if (lsm6dso_xl_full_scale_get(&(pObj->Ctx), &fs_low_level) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + switch (fs_low_level) + { + case LSM6DSO_2g: + *FullScale = 2; + break; + + case LSM6DSO_4g: + *FullScale = 4; + break; + + case LSM6DSO_8g: + *FullScale = 8; + break; + + case LSM6DSO_16g: + *FullScale = 16; + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Set the LSM6DSO accelerometer sensor full scale + * @param pObj the device pObj + * @param FullScale the functional full scale to be set + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_SetFullScale(LSM6DSO_Object_t *pObj, int32_t FullScale) +{ + lsm6dso_fs_xl_t new_fs; + + /* Seems like MISRA C-2012 rule 14.3a violation but only from single file statical analysis point of view because + the parameter passed to the function is not known at the moment of analysis */ + new_fs = (FullScale <= 2) ? LSM6DSO_2g + : (FullScale <= 4) ? LSM6DSO_4g + : (FullScale <= 8) ? LSM6DSO_8g + : LSM6DSO_16g; + + if (lsm6dso_xl_full_scale_set(&(pObj->Ctx), new_fs) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO accelerometer sensor raw axes + * @param pObj the device pObj + * @param Value pointer where the raw values of the axes are written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_GetAxesRaw(LSM6DSO_Object_t *pObj, LSM6DSO_AxesRaw_t *Value) +{ + lsm6dso_axis3bit16_t data_raw; + + /* Read raw data values. */ + if (lsm6dso_acceleration_raw_get(&(pObj->Ctx), data_raw.i16bit) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Format the data. */ + Value->x = data_raw.i16bit[0]; + Value->y = data_raw.i16bit[1]; + Value->z = data_raw.i16bit[2]; + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO accelerometer sensor axes + * @param pObj the device pObj + * @param Acceleration pointer where the values of the axes are written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_GetAxes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *Acceleration) +{ + lsm6dso_axis3bit16_t data_raw; + float_t sensitivity = 0.0f; + + /* Read raw data values. */ + if (lsm6dso_acceleration_raw_get(&(pObj->Ctx), data_raw.i16bit) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Get LSM6DSO actual sensitivity. */ + if (LSM6DSO_ACC_GetSensitivity(pObj, &sensitivity) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Calculate the data. */ + Acceleration->x = (int32_t)((float_t)((float_t)data_raw.i16bit[0] * sensitivity)); + Acceleration->y = (int32_t)((float_t)((float_t)data_raw.i16bit[1] * sensitivity)); + Acceleration->z = (int32_t)((float_t)((float_t)data_raw.i16bit[2] * sensitivity)); + + return LSM6DSO_OK; +} + +/** + * @brief Enable the LSM6DSO gyroscope sensor + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Enable(LSM6DSO_Object_t *pObj) +{ + /* Check if the component is already enabled */ + if (pObj->gyro_is_enabled == 1U) + { + return LSM6DSO_OK; + } + + /* Output data rate selection. */ + if (lsm6dso_gy_data_rate_set(&(pObj->Ctx), pObj->gyro_odr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + pObj->gyro_is_enabled = 1; + + return LSM6DSO_OK; +} + +/** + * @brief Disable the LSM6DSO gyroscope sensor + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Disable(LSM6DSO_Object_t *pObj) +{ + /* Check if the component is already disabled */ + if (pObj->gyro_is_enabled == 0U) + { + return LSM6DSO_OK; + } + + /* Get current output data rate. */ + if (lsm6dso_gy_data_rate_get(&(pObj->Ctx), &pObj->gyro_odr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Output data rate selection - power down. */ + if (lsm6dso_gy_data_rate_set(&(pObj->Ctx), LSM6DSO_GY_ODR_OFF) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + pObj->gyro_is_enabled = 0; + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO gyroscope sensor sensitivity + * @param pObj the device pObj + * @param Sensitivity pointer + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_GetSensitivity(LSM6DSO_Object_t *pObj, float_t *Sensitivity) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_fs_g_t full_scale; + + /* Read actual full scale selection from sensor. */ + if (lsm6dso_gy_full_scale_get(&(pObj->Ctx), &full_scale) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Store the sensitivity based on actual full scale. */ + switch (full_scale) + { + case LSM6DSO_125dps: + *Sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_125DPS; + break; + + case LSM6DSO_250dps: + *Sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_250DPS; + break; + + case LSM6DSO_500dps: + *Sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_500DPS; + break; + + case LSM6DSO_1000dps: + *Sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_1000DPS; + break; + + case LSM6DSO_2000dps: + *Sensitivity = LSM6DSO_GYRO_SENSITIVITY_FS_2000DPS; + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Get the LSM6DSO gyroscope sensor output data rate + * @param pObj the device pObj + * @param Odr pointer where the output data rate is written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_GetOutputDataRate(LSM6DSO_Object_t *pObj, float_t *Odr) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_odr_g_t odr_low_level; + + /* Get current output data rate. */ + if (lsm6dso_gy_data_rate_get(&(pObj->Ctx), &odr_low_level) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + switch (odr_low_level) + { + case LSM6DSO_GY_ODR_OFF: + *Odr = 0.0f; + break; + + case LSM6DSO_GY_ODR_12Hz5: + *Odr = 12.5f; + break; + + case LSM6DSO_GY_ODR_26Hz: + *Odr = 26.0f; + break; + + case LSM6DSO_GY_ODR_52Hz: + *Odr = 52.0f; + break; + + case LSM6DSO_GY_ODR_104Hz: + *Odr = 104.0f; + break; + + case LSM6DSO_GY_ODR_208Hz: + *Odr = 208.0f; + break; + + case LSM6DSO_GY_ODR_417Hz: + *Odr = 417.0f; + break; + + case LSM6DSO_GY_ODR_833Hz: + *Odr = 833.0f; + break; + + case LSM6DSO_GY_ODR_1667Hz: + *Odr = 1667.0f; + break; + + case LSM6DSO_GY_ODR_3333Hz: + *Odr = 3333.0f; + break; + + case LSM6DSO_GY_ODR_6667Hz: + *Odr = 6667.0f; + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Set the LSM6DSO gyroscope sensor output data rate + * @param pObj the device pObj + * @param Odr the output data rate value to be set + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_SetOutputDataRate(LSM6DSO_Object_t *pObj, float_t Odr) +{ + return LSM6DSO_GYRO_SetOutputDataRate_With_Mode(pObj, Odr, LSM6DSO_GYRO_HIGH_PERFORMANCE_MODE); +} + +/** + * @brief Set the LSM6DSO gyroscope sensor output data rate with operating mode + * @param pObj the device pObj + * @param Odr the output data rate value to be set + * @param Mode the gyroscope operating mode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_SetOutputDataRate_With_Mode(LSM6DSO_Object_t *pObj, float_t Odr, + LSM6DSO_GYRO_Operating_Mode_t Mode) +{ + int32_t ret = LSM6DSO_OK; + float_t newOdr = Odr; + + switch (Mode) + { + case LSM6DSO_GYRO_HIGH_PERFORMANCE_MODE: + { + /* We must uncheck Low Power bit if it is enabled */ + lsm6dso_ctrl7_g_t val1; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL7_G, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val1.g_hm_mode != 0U) + { + val1.g_hm_mode = 0U; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL7_G, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + break; + } + case LSM6DSO_GYRO_LOW_POWER_NORMAL_MODE: + { + /* We must check the Low Power bit if it is unchecked */ + lsm6dso_ctrl7_g_t val1; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_CTRL7_G, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (val1.g_hm_mode == 0U) + { + val1.g_hm_mode = 1U; + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_CTRL7_G, (uint8_t *)&val1, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + + /* Now we need to limit the ODR to 208 Hz if it is higher */ + if (newOdr > 208.0f) + { + newOdr = 208.0f; + } + break; + } + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (pObj->gyro_is_enabled == 1U) + { + ret = LSM6DSO_GYRO_SetOutputDataRate_When_Enabled(pObj, newOdr); + } + else + { + ret = LSM6DSO_GYRO_SetOutputDataRate_When_Disabled(pObj, newOdr); + } + + return ret; +} + +/** + * @brief Get the LSM6DSO gyroscope sensor full scale + * @param pObj the device pObj + * @param FullScale pointer where the full scale is written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_GetFullScale(LSM6DSO_Object_t *pObj, int32_t *FullScale) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_fs_g_t fs_low_level; + + /* Read actual full scale selection from sensor. */ + if (lsm6dso_gy_full_scale_get(&(pObj->Ctx), &fs_low_level) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + switch (fs_low_level) + { + case LSM6DSO_125dps: + *FullScale = 125; + break; + + case LSM6DSO_250dps: + *FullScale = 250; + break; + + case LSM6DSO_500dps: + *FullScale = 500; + break; + + case LSM6DSO_1000dps: + *FullScale = 1000; + break; + + case LSM6DSO_2000dps: + *FullScale = 2000; + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Set the LSM6DSO gyroscope sensor full scale + * @param pObj the device pObj + * @param FullScale the functional full scale to be set + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_SetFullScale(LSM6DSO_Object_t *pObj, int32_t FullScale) +{ + lsm6dso_fs_g_t new_fs; + + new_fs = (FullScale <= 125) ? LSM6DSO_125dps + : (FullScale <= 250) ? LSM6DSO_250dps + : (FullScale <= 500) ? LSM6DSO_500dps + : (FullScale <= 1000) ? LSM6DSO_1000dps + : LSM6DSO_2000dps; + + if (lsm6dso_gy_full_scale_set(&(pObj->Ctx), new_fs) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO gyroscope sensor raw axes + * @param pObj the device pObj + * @param Value pointer where the raw values of the axes are written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_GetAxesRaw(LSM6DSO_Object_t *pObj, LSM6DSO_AxesRaw_t *Value) +{ + lsm6dso_axis3bit16_t data_raw; + + /* Read raw data values. */ + if (lsm6dso_angular_rate_raw_get(&(pObj->Ctx), data_raw.i16bit) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Format the data. */ + Value->x = data_raw.i16bit[0]; + Value->y = data_raw.i16bit[1]; + Value->z = data_raw.i16bit[2]; + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO gyroscope sensor axes + * @param pObj the device pObj + * @param AngularRate pointer where the values of the axes are written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_GetAxes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *AngularRate) +{ + lsm6dso_axis3bit16_t data_raw; + float_t sensitivity; + + /* Read raw data values. */ + if (lsm6dso_angular_rate_raw_get(&(pObj->Ctx), data_raw.i16bit) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Get LSM6DSO actual sensitivity. */ + if (LSM6DSO_GYRO_GetSensitivity(pObj, &sensitivity) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Calculate the data. */ + AngularRate->x = (int32_t)((float_t)((float_t)data_raw.i16bit[0] * sensitivity)); + AngularRate->y = (int32_t)((float_t)((float_t)data_raw.i16bit[1] * sensitivity)); + AngularRate->z = (int32_t)((float_t)((float_t)data_raw.i16bit[2] * sensitivity)); + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO register value + * @param pObj the device pObj + * @param Reg address to be read + * @param Data pointer where the value is written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_Read_Reg(LSM6DSO_Object_t *pObj, uint8_t Reg, uint8_t *Data) +{ + if (lsm6dso_read_reg(&(pObj->Ctx), Reg, Data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO register value + * @param pObj the device pObj + * @param Reg address to be written + * @param Data value to be written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_Write_Reg(LSM6DSO_Object_t *pObj, uint8_t Reg, uint8_t Data) +{ + if (lsm6dso_write_reg(&(pObj->Ctx), Reg, &Data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the interrupt latch + * @param pObj the device pObj + * @param Status value to be written + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_Set_Interrupt_Latch(LSM6DSO_Object_t *pObj, uint8_t Status) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_lir_t newStatus = LSM6DSO_ALL_INT_PULSED; + + switch (Status) + { + case 0: + newStatus = LSM6DSO_ALL_INT_PULSED; + break; + case 1: + newStatus = LSM6DSO_BASE_LATCHED_EMB_PULSED; + break; + case 2: + newStatus = LSM6DSO_BASE_PULSED_EMB_LATCHED; + break; + case 3: + newStatus = LSM6DSO_ALL_INT_LATCHED; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (Status > 1U) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_int_notification_set(&(pObj->Ctx), newStatus) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable free fall detection + * @param pObj the device pObj + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Free_Fall_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 417.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* FF_DUR setting */ + if (lsm6dso_ff_dur_set(&(pObj->Ctx), 0x06) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* WAKE_DUR setting */ + if (lsm6dso_wkup_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* SLEEP_DUR setting */ + if (lsm6dso_act_sleep_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* FF_THS setting */ + if (lsm6dso_ff_threshold_set(&(pObj->Ctx), LSM6DSO_FF_TSH_312mg) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable free fall event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.free_fall = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + case LSM6DSO_INT2_PIN: + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.free_fall = PROPERTY_ENABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable free fall detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Free_Fall_Detection(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Disable free fall event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.free_fall = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.free_fall = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* FF_DUR setting */ + if (lsm6dso_ff_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* FF_THS setting */ + if (lsm6dso_ff_threshold_set(&(pObj->Ctx), LSM6DSO_FF_TSH_156mg) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set free fall threshold + * @param pObj the device pObj + * @param Threshold free fall detection threshold + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Free_Fall_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_ff_ths_t newThreshold = LSM6DSO_FF_TSH_156mg; + + switch (Threshold) + { + case 0: + newThreshold = LSM6DSO_FF_TSH_156mg; + break; + case 1: + newThreshold = LSM6DSO_FF_TSH_219mg; + break; + case 2: + newThreshold = LSM6DSO_FF_TSH_250mg; + break; + case 3: + newThreshold = LSM6DSO_FF_TSH_312mg; + break; + case 4: + newThreshold = LSM6DSO_FF_TSH_344mg; + break; + case 5: + newThreshold = LSM6DSO_FF_TSH_406mg; + break; + case 6: + newThreshold = LSM6DSO_FF_TSH_469mg; + break; + case 7: + newThreshold = LSM6DSO_FF_TSH_500mg; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_ff_threshold_set(&(pObj->Ctx), newThreshold) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return ret; +} + +/** + * @brief Set free fall duration + * @param pObj the device pObj + * @param Duration free fall detection duration + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Free_Fall_Duration(LSM6DSO_Object_t *pObj, uint8_t Duration) +{ + if (lsm6dso_ff_dur_set(&(pObj->Ctx), Duration) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable pedometer + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Pedometer(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val; + lsm6dso_emb_sens_t emb_sens; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 26.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Save current embedded features */ + if (lsm6dso_embedded_sens_get(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Turn off embedded features */ + if (lsm6dso_embedded_sens_off(&(pObj->Ctx)) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Wait for 10 ms */ + LSM6DSO_Delay(pObj, 10); + + /* Enable pedometer algorithm. */ + emb_sens.step = PROPERTY_ENABLE; + + if (lsm6dso_pedo_sens_set(&(pObj->Ctx), LSM6DSO_PEDO_BASE_MODE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Turn on embedded features */ + if (lsm6dso_embedded_sens_set(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable step detector on INT1 pin */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val.step_detector = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Disable pedometer + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Pedometer(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_emb_sens_t emb_sens; + + /* Disable step detector on INT1 pin */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.step_detector = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Save current embedded features */ + if (lsm6dso_embedded_sens_get(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable pedometer algorithm. */ + emb_sens.step = PROPERTY_DISABLE; + + if (lsm6dso_embedded_sens_set(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get step count + * @param pObj the device pObj + * @param StepCount step counter + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_Step_Count(LSM6DSO_Object_t *pObj, uint16_t *StepCount) +{ + if (lsm6dso_number_of_steps_get(&(pObj->Ctx), StepCount) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable step counter reset + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Step_Counter_Reset(LSM6DSO_Object_t *pObj) +{ + if (lsm6dso_steps_reset(&(pObj->Ctx)) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable tilt detection + * @param pObj the device pObj + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Tilt_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + lsm6dso_emb_sens_t emb_sens; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 26.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Save current embedded features */ + if (lsm6dso_embedded_sens_get(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Turn off embedded features */ + if (lsm6dso_embedded_sens_off(&(pObj->Ctx)) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Wait for 10 ms */ + LSM6DSO_Delay(pObj, 10); + + /* Enable tilt algorithm. */ + emb_sens.tilt = PROPERTY_ENABLE; + + /* Turn on embedded features */ + if (lsm6dso_embedded_sens_set(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable tilt event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.tilt = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + case LSM6DSO_INT2_PIN: + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.tilt = PROPERTY_ENABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable tilt detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Tilt_Detection(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + lsm6dso_emb_sens_t emb_sens; + + /* Disable tilt event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.tilt = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.tilt = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Save current embedded features */ + if (lsm6dso_embedded_sens_get(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable tilt algorithm. */ + emb_sens.tilt = PROPERTY_DISABLE; + + if (lsm6dso_embedded_sens_set(&(pObj->Ctx), &emb_sens) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable wake up detection + * @param pObj the device pObj + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Wake_Up_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 417.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* WAKE_DUR setting */ + if (lsm6dso_wkup_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set wake up threshold. */ + if (lsm6dso_wkup_threshold_set(&(pObj->Ctx), 0x02) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable wake up event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.wake_up = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + case LSM6DSO_INT2_PIN: + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.wake_up = PROPERTY_ENABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable wake up detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Wake_Up_Detection(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Disable wake up event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.wake_up = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.wake_up = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset wake up threshold. */ + if (lsm6dso_wkup_threshold_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* WAKE_DUR setting */ + if (lsm6dso_wkup_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set wake up threshold + * @param pObj the device pObj + * @param Threshold wake up detection threshold + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Wake_Up_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold) +{ + /* Set wake up threshold. */ + if (lsm6dso_wkup_threshold_set(&(pObj->Ctx), Threshold) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set wake up duration + * @param pObj the device pObj + * @param Duration wake up detection duration + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Wake_Up_Duration(LSM6DSO_Object_t *pObj, uint8_t Duration) +{ + /* Set wake up duration. */ + if (lsm6dso_wkup_dur_set(&(pObj->Ctx), Duration) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable single tap detection + * @param pObj the device pObj + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Single_Tap_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 417.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable X direction in tap recognition. */ + if (lsm6dso_tap_detection_on_x_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable Y direction in tap recognition. */ + if (lsm6dso_tap_detection_on_y_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable Z direction in tap recognition. */ + if (lsm6dso_tap_detection_on_z_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap threshold. */ + if (lsm6dso_tap_threshold_x_set(&(pObj->Ctx), 0x08) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap shock time window. */ + if (lsm6dso_tap_shock_set(&(pObj->Ctx), 0x02) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap quiet time window. */ + if (lsm6dso_tap_quiet_set(&(pObj->Ctx), 0x01) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* _NOTE_: Tap duration time window - don't care for single tap. */ + + /* _NOTE_: Single/Double Tap event - don't care of this flag for single tap. */ + + /* Enable single tap event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.single_tap = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + case LSM6DSO_INT2_PIN: + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.single_tap = PROPERTY_ENABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable single tap detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Single_Tap_Detection(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Disable single tap event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.single_tap = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.single_tap = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap quiet time window. */ + if (lsm6dso_tap_quiet_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap shock time window. */ + if (lsm6dso_tap_shock_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap threshold. */ + if (lsm6dso_tap_threshold_x_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable Z direction in tap recognition. */ + if (lsm6dso_tap_detection_on_z_set(&(pObj->Ctx), PROPERTY_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable Y direction in tap recognition. */ + if (lsm6dso_tap_detection_on_y_set(&(pObj->Ctx), PROPERTY_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable X direction in tap recognition. */ + if (lsm6dso_tap_detection_on_x_set(&(pObj->Ctx), PROPERTY_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable double tap detection + * @param pObj the device pObj + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Double_Tap_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 417.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable X direction in tap recognition. */ + if (lsm6dso_tap_detection_on_x_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable Y direction in tap recognition. */ + if (lsm6dso_tap_detection_on_y_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable Z direction in tap recognition. */ + if (lsm6dso_tap_detection_on_z_set(&(pObj->Ctx), PROPERTY_ENABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap threshold. */ + if (lsm6dso_tap_threshold_x_set(&(pObj->Ctx), 0x08) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap shock time window. */ + if (lsm6dso_tap_shock_set(&(pObj->Ctx), 0x03) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap quiet time window. */ + if (lsm6dso_tap_quiet_set(&(pObj->Ctx), 0x03) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Set tap duration time window. */ + if (lsm6dso_tap_dur_set(&(pObj->Ctx), 0x08) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Single and double tap enabled. */ + if (lsm6dso_tap_mode_set(&(pObj->Ctx), LSM6DSO_BOTH_SINGLE_DOUBLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable double tap event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.double_tap = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + case LSM6DSO_INT2_PIN: + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.double_tap = PROPERTY_ENABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable double tap detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Double_Tap_Detection(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Disable double tap event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.double_tap = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.double_tap = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Only single tap enabled. */ + if (lsm6dso_tap_mode_set(&(pObj->Ctx), LSM6DSO_ONLY_SINGLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap duration time window. */ + if (lsm6dso_tap_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap quiet time window. */ + if (lsm6dso_tap_quiet_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap shock time window. */ + if (lsm6dso_tap_shock_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset tap threshold. */ + if (lsm6dso_tap_threshold_x_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable Z direction in tap recognition. */ + if (lsm6dso_tap_detection_on_z_set(&(pObj->Ctx), PROPERTY_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable Y direction in tap recognition. */ + if (lsm6dso_tap_detection_on_y_set(&(pObj->Ctx), PROPERTY_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable X direction in tap recognition. */ + if (lsm6dso_tap_detection_on_x_set(&(pObj->Ctx), PROPERTY_DISABLE) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set tap threshold + * @param pObj the device pObj + * @param Threshold tap threshold + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Tap_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold) +{ + /* Set tap threshold. */ + if (lsm6dso_tap_threshold_x_set(&(pObj->Ctx), Threshold) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set tap shock time + * @param pObj the device pObj + * @param Time tap shock time + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Tap_Shock_Time(LSM6DSO_Object_t *pObj, uint8_t Time) +{ + /* Set tap shock time window. */ + if (lsm6dso_tap_shock_set(&(pObj->Ctx), Time) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set tap quiet time + * @param pObj the device pObj + * @param Time tap quiet time + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Tap_Quiet_Time(LSM6DSO_Object_t *pObj, uint8_t Time) +{ + /* Set tap quiet time window. */ + if (lsm6dso_tap_quiet_set(&(pObj->Ctx), Time) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set tap duration time + * @param pObj the device pObj + * @param Time tap duration time + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Tap_Duration_Time(LSM6DSO_Object_t *pObj, uint8_t Time) +{ + /* Set tap duration time window. */ + if (lsm6dso_tap_dur_set(&(pObj->Ctx), Time) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable 6D orientation detection + * @param pObj the device pObj + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_6D_Orientation(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Output Data Rate selection */ + if (LSM6DSO_ACC_SetOutputDataRate(pObj, 417.0f) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* 6D orientation enabled. */ + if (lsm6dso_6d_threshold_set(&(pObj->Ctx), LSM6DSO_DEG_60) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable 6D orientation event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.six_d = PROPERTY_ENABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + case LSM6DSO_INT2_PIN: + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.six_d = PROPERTY_ENABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable 6D orientation detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_6D_Orientation(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Disable 6D orientation event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.six_d = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.six_d = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Reset 6D orientation. */ + if (lsm6dso_6d_threshold_set(&(pObj->Ctx), LSM6DSO_DEG_80) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set 6D orientation threshold + * @param pObj the device pObj + * @param Threshold 6D Orientation detection threshold + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_6D_Orientation_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_sixd_ths_t newThreshold = LSM6DSO_DEG_80; + + switch (Threshold) + { + case 0: + newThreshold = LSM6DSO_DEG_80; + break; + case 1: + newThreshold = LSM6DSO_DEG_70; + break; + case 2: + newThreshold = LSM6DSO_DEG_60; + break; + case 3: + newThreshold = LSM6DSO_DEG_50; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_6d_threshold_set(&(pObj->Ctx), newThreshold) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of XLow orientation + * @param pObj the device pObj + * @param XLow the status of XLow orientation + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_6D_Orientation_XL(LSM6DSO_Object_t *pObj, uint8_t *XLow) +{ + lsm6dso_d6d_src_t data; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *XLow = data.xl; + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of XHigh orientation + * @param pObj the device pObj + * @param XHigh the status of XHigh orientation + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_6D_Orientation_XH(LSM6DSO_Object_t *pObj, uint8_t *XHigh) +{ + lsm6dso_d6d_src_t data; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *XHigh = data.xh; + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of YLow orientation + * @param pObj the device pObj + * @param YLow the status of YLow orientation + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_6D_Orientation_YL(LSM6DSO_Object_t *pObj, uint8_t *YLow) +{ + lsm6dso_d6d_src_t data; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *YLow = data.yl; + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of YHigh orientation + * @param pObj the device pObj + * @param YHigh the status of YHigh orientation + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_6D_Orientation_YH(LSM6DSO_Object_t *pObj, uint8_t *YHigh) +{ + lsm6dso_d6d_src_t data; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *YHigh = data.yh; + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of ZLow orientation + * @param pObj the device pObj + * @param ZLow the status of ZLow orientation + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_6D_Orientation_ZL(LSM6DSO_Object_t *pObj, uint8_t *ZLow) +{ + lsm6dso_d6d_src_t data; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *ZLow = data.zl; + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of ZHigh orientation + * @param pObj the device pObj + * @param ZHigh the status of ZHigh orientation + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_6D_Orientation_ZH(LSM6DSO_Object_t *pObj, uint8_t *ZHigh) +{ + lsm6dso_d6d_src_t data; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&data, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *ZHigh = data.zh; + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO ACC data ready bit value + * @param pObj the device pObj + * @param Status the status of data ready bit + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_DRDY_Status(LSM6DSO_Object_t *pObj, uint8_t *Status) +{ + if (lsm6dso_xl_flag_data_ready_get(&(pObj->Ctx), Status) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the status of all hardware events + * @param pObj the device pObj + * @param Status the status of all hardware events + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Get_Event_Status(LSM6DSO_Object_t *pObj, LSM6DSO_Event_Status_t *Status) +{ + uint8_t tilt_ia; + lsm6dso_wake_up_src_t wake_up_src; + lsm6dso_tap_src_t tap_src; + lsm6dso_d6d_src_t d6d_src; + lsm6dso_emb_func_src_t func_src; + lsm6dso_md1_cfg_t md1_cfg; + lsm6dso_md2_cfg_t md2_cfg; + lsm6dso_emb_func_int1_t int1_ctrl; + lsm6dso_emb_func_int2_t int2_ctrl; + + (void)memset((void *)Status, 0x0, sizeof(LSM6DSO_Event_Status_t)); + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_WAKE_UP_SRC, (uint8_t *)&wake_up_src, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_TAP_SRC, (uint8_t *)&tap_src, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&d6d_src, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_mem_bank_set(&(pObj->Ctx), LSM6DSO_EMBEDDED_FUNC_BANK) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_EMB_FUNC_SRC, (uint8_t *)&func_src, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_EMB_FUNC_INT1, (uint8_t *)&int1_ctrl, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_EMB_FUNC_INT2, (uint8_t *)&int2_ctrl, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_mem_bank_set(&(pObj->Ctx), LSM6DSO_USER_BANK) != 0) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_MD1_CFG, (uint8_t *)&md1_cfg, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_tilt_flag_data_ready_get(&(pObj->Ctx), &tilt_ia) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if ((md1_cfg.int1_ff == 1U) || (md2_cfg.int2_ff == 1U)) + { + if (wake_up_src.ff_ia == 1U) + { + Status->FreeFallStatus = 1; + } + } + + if ((md1_cfg.int1_wu == 1U) || (md2_cfg.int2_wu == 1U)) + { + if (wake_up_src.wu_ia == 1U) + { + Status->WakeUpStatus = 1; + } + } + + if ((md1_cfg.int1_single_tap == 1U) || (md2_cfg.int2_single_tap == 1U)) + { + if (tap_src.single_tap == 1U) + { + Status->TapStatus = 1; + } + } + + if ((md1_cfg.int1_double_tap == 1U) || (md2_cfg.int2_double_tap == 1U)) + { + if (tap_src.double_tap == 1U) + { + Status->DoubleTapStatus = 1; + } + } + + if ((md1_cfg.int1_6d == 1U) || (md2_cfg.int2_6d == 1U)) + { + if (d6d_src.d6d_ia == 1U) + { + Status->D6DOrientationStatus = 1; + } + } + + if (int1_ctrl.int1_step_detector == 1U) + { + if (func_src.step_detected == 1U) + { + Status->StepStatus = 1; + } + } + + if ((int1_ctrl.int1_tilt == 1U) || (int2_ctrl.int2_tilt == 1U)) + { + if (tilt_ia == 1U) + { + Status->TiltStatus = 1; + } + } + + return LSM6DSO_OK; +} + +/** + * @brief Set self test + * @param pObj the device pObj + * @param val the value of st_xl in reg CTRL5_C + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_SelfTest(LSM6DSO_Object_t *pObj, uint8_t val) +{ + lsm6dso_st_xl_t reg; + + reg = (val == 0U) ? LSM6DSO_XL_ST_DISABLE + : (val == 1U) ? LSM6DSO_XL_ST_POSITIVE + : (val == 2U) ? LSM6DSO_XL_ST_NEGATIVE + : LSM6DSO_XL_ST_DISABLE; + + if (lsm6dso_xl_self_test_set(&(pObj->Ctx), reg) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO GYRO data ready bit value + * @param pObj the device pObj + * @param Status the status of data ready bit + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Get_DRDY_Status(LSM6DSO_Object_t *pObj, uint8_t *Status) +{ + if (lsm6dso_gy_flag_data_ready_get(&(pObj->Ctx), Status) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set self test + * @param pObj the device pObj + * @param val the value of st_xl in reg CTRL5_C + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Set_SelfTest(LSM6DSO_Object_t *pObj, uint8_t val) +{ + lsm6dso_st_g_t reg; + + reg = (val == 0U) ? LSM6DSO_GY_ST_DISABLE + : (val == 1U) ? LSM6DSO_GY_ST_POSITIVE + : (val == 2U) ? LSM6DSO_GY_ST_NEGATIVE + : LSM6DSO_GY_ST_DISABLE; + + + if (lsm6dso_gy_self_test_set(&(pObj->Ctx), reg) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO FIFO number of samples + * @param pObj the device pObj + * @param NumSamples number of samples + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Get_Num_Samples(LSM6DSO_Object_t *pObj, uint16_t *NumSamples) +{ + if (lsm6dso_fifo_data_level_get(&(pObj->Ctx), NumSamples) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO FIFO full status + * @param pObj the device pObj + * @param Status FIFO full status + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Get_Full_Status(LSM6DSO_Object_t *pObj, uint8_t *Status) +{ + lsm6dso_reg_t reg; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_FIFO_STATUS2, ®.byte, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *Status = reg.fifo_status2.fifo_full_ia; + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO FIFO full interrupt on INT1 pin + * @param pObj the device pObj + * @param Status FIFO full interrupt on INT1 pin status + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Set_INT1_FIFO_Full(LSM6DSO_Object_t *pObj, uint8_t Status) +{ + lsm6dso_reg_t reg; + + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_INT1_CTRL, ®.byte, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + reg.int1_ctrl.int1_fifo_full = Status; + + if (lsm6dso_write_reg(&(pObj->Ctx), LSM6DSO_INT1_CTRL, ®.byte, 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO FIFO watermark level + * @param pObj the device pObj + * @param Watermark FIFO watermark level + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Set_Watermark_Level(LSM6DSO_Object_t *pObj, uint16_t Watermark) +{ + if (lsm6dso_fifo_watermark_set(&(pObj->Ctx), Watermark) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO FIFO stop on watermark + * @param pObj the device pObj + * @param Status FIFO stop on watermark status + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Set_Stop_On_Fth(LSM6DSO_Object_t *pObj, uint8_t Status) +{ + if (lsm6dso_fifo_stop_on_wtm_set(&(pObj->Ctx), Status) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO FIFO mode + * @param pObj the device pObj + * @param Mode FIFO mode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Set_Mode(LSM6DSO_Object_t *pObj, uint8_t Mode) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_fifo_mode_t newMode = LSM6DSO_BYPASS_MODE; + + switch (Mode) + { + case 0: + newMode = LSM6DSO_BYPASS_MODE; + break; + case 1: + newMode = LSM6DSO_FIFO_MODE; + break; + case 3: + newMode = LSM6DSO_STREAM_TO_FIFO_MODE; + break; + case 4: + newMode = LSM6DSO_BYPASS_TO_STREAM_MODE; + break; + case 6: + newMode = LSM6DSO_STREAM_MODE; + break; + case 7: + newMode = LSM6DSO_BYPASS_TO_FIFO_MODE; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_fifo_mode_set(&(pObj->Ctx), newMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return ret; +} + +/** + * @brief Get the LSM6DSO FIFO tag + * @param pObj the device pObj + * @param Tag FIFO tag + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Get_Tag(LSM6DSO_Object_t *pObj, uint8_t *Tag) +{ + lsm6dso_fifo_tag_t tag_local; + + if (lsm6dso_fifo_sensor_tag_get(&(pObj->Ctx), &tag_local) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + *Tag = (uint8_t)tag_local; + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO FIFO raw data + * @param pObj the device pObj + * @param Data FIFO raw data array [6] + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_Get_Data(LSM6DSO_Object_t *pObj, uint8_t *Data) +{ + if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_FIFO_DATA_OUT_X_L, Data, 6) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO FIFO accelero single sample (16-bit data per 3 axes) and calculate acceleration [mg] + * @param pObj the device pObj + * @param Acceleration FIFO accelero axes [mg] + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_ACC_Get_Axes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *Acceleration) +{ + lsm6dso_axis3bit16_t data_raw; + float_t sensitivity = 0.0f; + float_t acceleration_float_t[3]; + + if (LSM6DSO_FIFO_Get_Data(pObj, data_raw.u8bit) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (LSM6DSO_ACC_GetSensitivity(pObj, &sensitivity) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + acceleration_float_t[0] = (float_t)data_raw.i16bit[0] * sensitivity; + acceleration_float_t[1] = (float_t)data_raw.i16bit[1] * sensitivity; + acceleration_float_t[2] = (float_t)data_raw.i16bit[2] * sensitivity; + + Acceleration->x = (int32_t)acceleration_float_t[0]; + Acceleration->y = (int32_t)acceleration_float_t[1]; + Acceleration->z = (int32_t)acceleration_float_t[2]; + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO FIFO accelero BDR value + * @param pObj the device pObj + * @param Bdr FIFO accelero BDR value + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_ACC_Set_BDR(LSM6DSO_Object_t *pObj, float_t Bdr) +{ + lsm6dso_bdr_xl_t new_bdr; + + new_bdr = (Bdr <= 0.0f) ? LSM6DSO_XL_NOT_BATCHED + : (Bdr <= 12.5f) ? LSM6DSO_XL_BATCHED_AT_12Hz5 + : (Bdr <= 26.0f) ? LSM6DSO_XL_BATCHED_AT_26Hz + : (Bdr <= 52.0f) ? LSM6DSO_XL_BATCHED_AT_52Hz + : (Bdr <= 104.0f) ? LSM6DSO_XL_BATCHED_AT_104Hz + : (Bdr <= 208.0f) ? LSM6DSO_XL_BATCHED_AT_208Hz + : (Bdr <= 417.0f) ? LSM6DSO_XL_BATCHED_AT_417Hz + : (Bdr <= 833.0f) ? LSM6DSO_XL_BATCHED_AT_833Hz + : (Bdr <= 1667.0f) ? LSM6DSO_XL_BATCHED_AT_1667Hz + : (Bdr <= 3333.0f) ? LSM6DSO_XL_BATCHED_AT_3333Hz + : LSM6DSO_XL_BATCHED_AT_6667Hz; + + if (lsm6dso_fifo_xl_batch_set(&(pObj->Ctx), new_bdr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Get the LSM6DSO FIFO gyro single sample (16-bit data per 3 axes) and calculate angular velocity [mDPS] + * @param pObj the device pObj + * @param AngularVelocity FIFO gyro axes [mDPS] + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_GYRO_Get_Axes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *AngularVelocity) +{ + lsm6dso_axis3bit16_t data_raw; + float_t sensitivity = 0.0f; + float_t angular_velocity_float_t[3]; + + if (LSM6DSO_FIFO_Get_Data(pObj, data_raw.u8bit) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (LSM6DSO_GYRO_GetSensitivity(pObj, &sensitivity) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + angular_velocity_float_t[0] = (float_t)data_raw.i16bit[0] * sensitivity; + angular_velocity_float_t[1] = (float_t)data_raw.i16bit[1] * sensitivity; + angular_velocity_float_t[2] = (float_t)data_raw.i16bit[2] * sensitivity; + + AngularVelocity->x = (int32_t)angular_velocity_float_t[0]; + AngularVelocity->y = (int32_t)angular_velocity_float_t[1]; + AngularVelocity->z = (int32_t)angular_velocity_float_t[2]; + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO FIFO gyro BDR value + * @param pObj the device pObj + * @param Bdr FIFO gyro BDR value + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_FIFO_GYRO_Set_BDR(LSM6DSO_Object_t *pObj, float_t Bdr) +{ + lsm6dso_bdr_gy_t new_bdr; + + new_bdr = (Bdr <= 0.0f) ? LSM6DSO_GY_NOT_BATCHED + : (Bdr <= 12.5f) ? LSM6DSO_GY_BATCHED_AT_12Hz5 + : (Bdr <= 26.0f) ? LSM6DSO_GY_BATCHED_AT_26Hz + : (Bdr <= 52.0f) ? LSM6DSO_GY_BATCHED_AT_52Hz + : (Bdr <= 104.0f) ? LSM6DSO_GY_BATCHED_AT_104Hz + : (Bdr <= 208.0f) ? LSM6DSO_GY_BATCHED_AT_208Hz + : (Bdr <= 417.0f) ? LSM6DSO_GY_BATCHED_AT_417Hz + : (Bdr <= 833.0f) ? LSM6DSO_GY_BATCHED_AT_833Hz + : (Bdr <= 1667.0f) ? LSM6DSO_GY_BATCHED_AT_1667Hz + : (Bdr <= 3333.0f) ? LSM6DSO_GY_BATCHED_AT_3333Hz + : LSM6DSO_GY_BATCHED_AT_6667Hz; + + if (lsm6dso_fifo_gy_batch_set(&(pObj->Ctx), new_bdr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable LSM6DSO accelerometer DRDY interrupt on INT1 + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_DRDY_On_INT1(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t pin_int1_route; + + /* Enable accelerometer DRDY Interrupt on INT1 */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &pin_int1_route) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + pin_int1_route.drdy_xl = 1; + pin_int1_route.drdy_g = 0; + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), pin_int1_route) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Disable LSM6DSO accelerometer DRDY interrupt on INT1 + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_DRDY_On_INT1(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t pin_int1_route; + + /* Disable accelerometer DRDY Interrupt on INT1 */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &pin_int1_route) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + pin_int1_route.drdy_xl = 0; + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), pin_int1_route) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO accelerometer power mode + * @param pObj the device pObj + * @param PowerMode Value of the powerMode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Power_Mode(LSM6DSO_Object_t *pObj, uint8_t PowerMode) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_xl_hm_mode_t newPowerMode = LSM6DSO_HIGH_PERFORMANCE_MD; + + switch (PowerMode) + { + case 0: + newPowerMode = LSM6DSO_HIGH_PERFORMANCE_MD; + break; + case 1: + newPowerMode = LSM6DSO_LOW_NORMAL_POWER_MD; + break; + case 2: + newPowerMode = LSM6DSO_ULTRA_LOW_POWER_MD; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_xl_power_mode_set(&(pObj->Ctx), newPowerMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO accelerometer filter mode + * @param pObj the device pObj + * @param LowHighPassFlag 0/1 for setting low-pass/high-pass filter mode + * @param FilterMode Value of the filter Mode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Filter_Mode(LSM6DSO_Object_t *pObj, uint8_t LowHighPassFlag, uint8_t FilterMode) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_hp_slope_xl_en_t newFilterMode = LSM6DSO_HP_PATH_DISABLE_ON_OUT; + + switch (FilterMode) + { + case 0x00: + newFilterMode = LSM6DSO_HP_PATH_DISABLE_ON_OUT; + break; + case 0x01: + newFilterMode = LSM6DSO_LP_ODR_DIV_10; + break; + case 0x02: + newFilterMode = LSM6DSO_LP_ODR_DIV_20; + break; + case 0x03: + newFilterMode = LSM6DSO_LP_ODR_DIV_45; + break; + case 0x04: + newFilterMode = LSM6DSO_LP_ODR_DIV_100; + break; + case 0x05: + newFilterMode = LSM6DSO_LP_ODR_DIV_200; + break; + case 0x06: + newFilterMode = LSM6DSO_LP_ODR_DIV_400; + break; + case 0x07: + newFilterMode = LSM6DSO_LP_ODR_DIV_800; + break; + case 0x10: + newFilterMode = LSM6DSO_SLOPE_ODR_DIV_4; + break; + case 0x11: + newFilterMode = LSM6DSO_HP_ODR_DIV_10; + break; + case 0x12: + newFilterMode = LSM6DSO_HP_ODR_DIV_20; + break; + case 0x13: + newFilterMode = LSM6DSO_HP_ODR_DIV_45; + break; + case 0x14: + newFilterMode = LSM6DSO_HP_ODR_DIV_100; + break; + case 0x15: + newFilterMode = LSM6DSO_HP_ODR_DIV_200; + break; + case 0x16: + newFilterMode = LSM6DSO_HP_ODR_DIV_400; + break; + case 0x17: + newFilterMode = LSM6DSO_HP_ODR_DIV_800; + break; + case 0x31: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_10; + break; + case 0x32: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_20; + break; + case 0x33: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_45; + break; + case 0x34: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_100; + break; + case 0x35: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_200; + break; + case 0x36: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_400; + break; + case 0x37: + newFilterMode = LSM6DSO_HP_REF_MD_ODR_DIV_800; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (LowHighPassFlag == 0U) + { + /*Set accelerometer low_pass filter-mode*/ + + /*Set to 1 LPF2 bit (CTRL8_XL)*/ + if (lsm6dso_xl_filter_lp2_set(&(pObj->Ctx), 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + if (lsm6dso_xl_hp_path_on_out_set(&(pObj->Ctx), newFilterMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + else + { + /*Set accelerometer high_pass filter-mode*/ + if (lsm6dso_xl_hp_path_on_out_set(&(pObj->Ctx), newFilterMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + return LSM6DSO_OK; +} + +/** + * @brief Enable LSM6DSO accelerometer inactivity detection + * @param pObj the device pObj + * @param InactMode inactivity detection mode + * @param IntPin interrupt pin line to be used + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Enable_Inactivity_Detection(LSM6DSO_Object_t *pObj, lsm6dso_inact_en_t InactMode, + LSM6DSO_SensorIntPin_t IntPin) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + int32_t ret = LSM6DSO_OK; + + /* Full scale selection */ + if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + if (LSM6DSO_GYRO_SetFullScale(pObj, 250) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* SLEEP_DUR setting */ + if (lsm6dso_act_sleep_dur_set(&(pObj->Ctx), 0x01) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Enable inactivity detection. */ + switch (InactMode) + { + case LSM6DSO_XL_AND_GY_NOT_AFFECTED: + { + if (lsm6dso_act_mode_set(&(pObj->Ctx), LSM6DSO_XL_AND_GY_NOT_AFFECTED) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + } + case LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED: + { + if (lsm6dso_act_mode_set(&(pObj->Ctx), LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + } + case LSM6DSO_XL_12Hz5_GY_SLEEP: + { + if (lsm6dso_act_mode_set(&(pObj->Ctx), LSM6DSO_XL_12Hz5_GY_SLEEP) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + } + case LSM6DSO_XL_12Hz5_GY_PD: + { + if (lsm6dso_act_mode_set(&(pObj->Ctx), LSM6DSO_XL_12Hz5_GY_PD) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + } + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + /* Enable Inactivity event on either INT1 or INT2 pin */ + switch (IntPin) + { + case LSM6DSO_INT1_PIN: + { + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.sleep_change = PROPERTY_ENABLE; + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + } + case LSM6DSO_INT2_PIN: + { + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.sleep_change = PROPERTY_ENABLE; + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + break; + } + default: + ret = LSM6DSO_ERROR; + break; + } + + return ret; +} + +/** + * @brief Disable LSM6DSO accelerometer inactivity detection + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Disable_Inactivity_Detection(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int1_route_t val1; + lsm6dso_pin_int2_route_t val2; + + /* Disable inactivity event on both INT1 and INT2 pins */ + if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val1.sleep_change = PROPERTY_DISABLE; + + if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), val1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + val2.sleep_change = PROPERTY_DISABLE; + + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, val2) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* Disable inactivity detection. */ + if (lsm6dso_act_mode_set(&(pObj->Ctx), LSM6DSO_XL_AND_GY_NOT_AFFECTED) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + /* SLEEP_DUR reset */ + if (lsm6dso_act_sleep_dur_set(&(pObj->Ctx), 0x00) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + return LSM6DSO_OK; +} + +/** + * @brief Set LSM6DSO accelerometer sleep duration + * @param pObj the device pObj + * @param Duration wake up detection duration + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_ACC_Set_Sleep_Duration(LSM6DSO_Object_t *pObj, uint8_t Duration) +{ + /* Set wake up duration. */ + if (lsm6dso_act_sleep_dur_set(&(pObj->Ctx), Duration) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Enable LSM6DSO gyroscope DRDY interrupt on INT2 + * @param pObj the device pObj + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Enable_DRDY_On_INT2(LSM6DSO_Object_t *pObj) +{ + lsm6dso_pin_int2_route_t pin_int2_route; + + /* Enable gyroscope DRDY Interrupts on INT2 */ + if (lsm6dso_pin_int2_route_get(&(pObj->Ctx), NULL, &pin_int2_route) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + pin_int2_route.drdy_xl = 0; + pin_int2_route.drdy_g = 1; + if (lsm6dso_pin_int2_route_set(&(pObj->Ctx), NULL, pin_int2_route) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO gyroscope power mode + * @param pObj the device pObj + * @param PowerMode Value of the powerMode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Set_Power_Mode(LSM6DSO_Object_t *pObj, uint8_t PowerMode) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_g_hm_mode_t newPowerMode = LSM6DSO_GY_HIGH_PERFORMANCE; + + switch (PowerMode) + { + case 0: + newPowerMode = LSM6DSO_GY_HIGH_PERFORMANCE; + break; + case 1: + newPowerMode = LSM6DSO_GY_NORMAL; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + if (lsm6dso_gy_power_mode_set(&(pObj->Ctx), newPowerMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO gyroscope filter mode + * @param pObj the device pObj + * @param LowHighPassFlag 0/1 for setting low-pass/high-pass filter mode + * @param FilterMode Value of the filter Mode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_GYRO_Set_Filter_Mode(LSM6DSO_Object_t *pObj, uint8_t LowHighPassFlag, uint8_t FilterMode) +{ + int32_t ret = LSM6DSO_OK; + + if (LowHighPassFlag == 0U) + { + lsm6dso_ftype_t newFilterMode = LSM6DSO_ULTRA_LIGHT; + + switch (FilterMode) + { + case 0: + newFilterMode = LSM6DSO_ULTRA_LIGHT; + break; + case 1: + newFilterMode = LSM6DSO_VERY_LIGHT; + break; + case 2: + newFilterMode = LSM6DSO_LIGHT; + break; + case 3: + newFilterMode = LSM6DSO_MEDIUM; + break; + case 4: + newFilterMode = LSM6DSO_STRONG; + break; + case 5: + newFilterMode = LSM6DSO_VERY_STRONG; + break; + case 6: + newFilterMode = LSM6DSO_AGGRESSIVE; + break; + case 7: + newFilterMode = LSM6DSO_XTREME; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + /*Set gyroscope low_pass 1 filter-mode*/ + /* Enable low-pass filter */ + if (lsm6dso_gy_filter_lp1_set(&(pObj->Ctx), 1) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + if (lsm6dso_gy_lp1_bandwidth_set(&(pObj->Ctx), newFilterMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + else + { + lsm6dso_hpm_g_t newFilterMode = LSM6DSO_HP_FILTER_NONE; + + switch (FilterMode) + { + case 0x00: + newFilterMode = LSM6DSO_HP_FILTER_NONE; + break; + case 0x80: + newFilterMode = LSM6DSO_HP_FILTER_16mHz; + break; + case 0x81: + newFilterMode = LSM6DSO_HP_FILTER_65mHz; + break; + case 0x82: + newFilterMode = LSM6DSO_HP_FILTER_260mHz; + break; + case 0x83: + newFilterMode = LSM6DSO_HP_FILTER_1Hz04; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + /*Set gyroscope high_pass filter-mode*/ + /* Enable high-pass filter */ + if (lsm6dso_gy_hp_path_internal_set(&(pObj->Ctx), newFilterMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + } + return LSM6DSO_OK; +} + +/** + * @brief Set LSM6DSO DRDY mode + * @param pObj the device pObj + * @param Mode DRDY mode + * @retval 0 in case of success, an error code otherwise + */ +int32_t LSM6DSO_DRDY_Set_Mode(LSM6DSO_Object_t *pObj, uint8_t Mode) +{ + int32_t ret = LSM6DSO_OK; + lsm6dso_dataready_pulsed_t newMode = LSM6DSO_DRDY_LATCHED; + + switch (Mode) + { + case 0: + newMode = LSM6DSO_DRDY_LATCHED; + break; + case 1: + newMode = LSM6DSO_DRDY_PULSED; + break; + default: + ret = LSM6DSO_ERROR; + break; + } + + if (ret == LSM6DSO_ERROR) + { + return LSM6DSO_ERROR; + } + + /* Set DRDY mode */ + if (lsm6dso_data_ready_mode_set(&(pObj->Ctx), newMode) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @} + */ + +/** @defgroup LSM6DSO_Private_Functions LSM6DSO Private Functions + * @{ + */ + +/** + * @brief Set the LSM6DSO accelerometer sensor output data rate when enabled + * @param pObj the device pObj + * @param Odr the functional output data rate to be set + * @retval 0 in case of success, an error code otherwise + */ +static int32_t LSM6DSO_ACC_SetOutputDataRate_When_Enabled(LSM6DSO_Object_t *pObj, float_t Odr) +{ + lsm6dso_odr_xl_t new_odr; + + new_odr = (Odr <= 1.6f) ? LSM6DSO_XL_ODR_1Hz6 + : (Odr <= 12.5f) ? LSM6DSO_XL_ODR_12Hz5 + : (Odr <= 26.0f) ? LSM6DSO_XL_ODR_26Hz + : (Odr <= 52.0f) ? LSM6DSO_XL_ODR_52Hz + : (Odr <= 104.0f) ? LSM6DSO_XL_ODR_104Hz + : (Odr <= 208.0f) ? LSM6DSO_XL_ODR_208Hz + : (Odr <= 417.0f) ? LSM6DSO_XL_ODR_417Hz + : (Odr <= 833.0f) ? LSM6DSO_XL_ODR_833Hz + : (Odr <= 1667.0f) ? LSM6DSO_XL_ODR_1667Hz + : (Odr <= 3333.0f) ? LSM6DSO_XL_ODR_3333Hz + : LSM6DSO_XL_ODR_6667Hz; + + /* Output data rate selection. */ + if (lsm6dso_xl_data_rate_set(&(pObj->Ctx), new_odr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO accelerometer sensor output data rate when disabled + * @param pObj the device pObj + * @param Odr the functional output data rate to be set + * @retval 0 in case of success, an error code otherwise + */ +static int32_t LSM6DSO_ACC_SetOutputDataRate_When_Disabled(LSM6DSO_Object_t *pObj, float_t Odr) +{ + pObj->acc_odr = (Odr <= 1.6f) ? LSM6DSO_XL_ODR_1Hz6 + : (Odr <= 12.5f) ? LSM6DSO_XL_ODR_12Hz5 + : (Odr <= 26.0f) ? LSM6DSO_XL_ODR_26Hz + : (Odr <= 52.0f) ? LSM6DSO_XL_ODR_52Hz + : (Odr <= 104.0f) ? LSM6DSO_XL_ODR_104Hz + : (Odr <= 208.0f) ? LSM6DSO_XL_ODR_208Hz + : (Odr <= 417.0f) ? LSM6DSO_XL_ODR_417Hz + : (Odr <= 833.0f) ? LSM6DSO_XL_ODR_833Hz + : (Odr <= 1667.0f) ? LSM6DSO_XL_ODR_1667Hz + : (Odr <= 3333.0f) ? LSM6DSO_XL_ODR_3333Hz + : LSM6DSO_XL_ODR_6667Hz; + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO gyroscope sensor output data rate when enabled + * @param pObj the device pObj + * @param Odr the functional output data rate to be set + * @retval 0 in case of success, an error code otherwise + */ +static int32_t LSM6DSO_GYRO_SetOutputDataRate_When_Enabled(LSM6DSO_Object_t *pObj, float_t Odr) +{ + lsm6dso_odr_g_t new_odr; + + new_odr = (Odr <= 12.5f) ? LSM6DSO_GY_ODR_12Hz5 + : (Odr <= 26.0f) ? LSM6DSO_GY_ODR_26Hz + : (Odr <= 52.0f) ? LSM6DSO_GY_ODR_52Hz + : (Odr <= 104.0f) ? LSM6DSO_GY_ODR_104Hz + : (Odr <= 208.0f) ? LSM6DSO_GY_ODR_208Hz + : (Odr <= 417.0f) ? LSM6DSO_GY_ODR_417Hz + : (Odr <= 833.0f) ? LSM6DSO_GY_ODR_833Hz + : (Odr <= 1667.0f) ? LSM6DSO_GY_ODR_1667Hz + : (Odr <= 3333.0f) ? LSM6DSO_GY_ODR_3333Hz + : LSM6DSO_GY_ODR_6667Hz; + + /* Output data rate selection. */ + if (lsm6dso_gy_data_rate_set(&(pObj->Ctx), new_odr) != LSM6DSO_OK) + { + return LSM6DSO_ERROR; + } + + return LSM6DSO_OK; +} + +/** + * @brief Set the LSM6DSO gyroscope sensor output data rate when disabled + * @param pObj the device pObj + * @param Odr the functional output data rate to be set + * @retval 0 in case of success, an error code otherwise + */ +static int32_t LSM6DSO_GYRO_SetOutputDataRate_When_Disabled(LSM6DSO_Object_t *pObj, float_t Odr) +{ + pObj->gyro_odr = (Odr <= 12.5f) ? LSM6DSO_GY_ODR_12Hz5 + : (Odr <= 26.0f) ? LSM6DSO_GY_ODR_26Hz + : (Odr <= 52.0f) ? LSM6DSO_GY_ODR_52Hz + : (Odr <= 104.0f) ? LSM6DSO_GY_ODR_104Hz + : (Odr <= 208.0f) ? LSM6DSO_GY_ODR_208Hz + : (Odr <= 417.0f) ? LSM6DSO_GY_ODR_417Hz + : (Odr <= 833.0f) ? LSM6DSO_GY_ODR_833Hz + : (Odr <= 1667.0f) ? LSM6DSO_GY_ODR_1667Hz + : (Odr <= 3333.0f) ? LSM6DSO_GY_ODR_3333Hz + : LSM6DSO_GY_ODR_6667Hz; + + return LSM6DSO_OK; +} + +/** + * @brief This function provides a minimum delay based on Tick counter + * @param pObj the device pObj + * @param msDelay delay expressed in ms + * @retval None + */ +static void LSM6DSO_Delay(LSM6DSO_Object_t *pObj, uint32_t msDelay) +{ + uint32_t tickstart = pObj->IO.GetTick(); + + while ((pObj->IO.GetTick() - tickstart) < msDelay) + { + } +} + +/** + * @brief Wrap Read register component function to Bus IO function + * @param Handle the device handler + * @param Reg the register address + * @param pData the stored data pointer + * @param Length the length + * @retval 0 in case of success, an error code otherwise + */ +static int32_t ReadRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length) +{ + LSM6DSO_Object_t *pObj = (LSM6DSO_Object_t *)Handle; + + return pObj->IO.ReadReg(pObj->IO.Address, Reg, pData, Length); +} + +/** + * @brief Wrap Write register component function to Bus IO function + * @param Handle the device handler + * @param Reg the register address + * @param pData the stored data pointer + * @param Length the length + * @retval 0 in case of success, an error code otherwise + */ +static int32_t WriteRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length) +{ + LSM6DSO_Object_t *pObj = (LSM6DSO_Object_t *)Handle; + + return pObj->IO.WriteReg(pObj->IO.Address, Reg, pData, Length); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.h b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.h new file mode 100644 index 00000000000..1843df0ac86 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso.h @@ -0,0 +1,369 @@ +/** + ****************************************************************************** + * @file lsm6dso.h + * @author MEMS Software Solutions Team + * @brief LSM6DSO header driver file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef LSM6DSO_H +#define LSM6DSO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "lsm6dso_reg.h" +#include + +/** @addtogroup BSP BSP + * @{ + */ + +/** @addtogroup Component Component + * @{ + */ + +/** @addtogroup LSM6DSO LSM6DSO + * @{ + */ + +/** @defgroup LSM6DSO_Exported_Types LSM6DSO Exported Types + * @{ + */ + +typedef int32_t (*LSM6DSO_Init_Func)(void); +typedef int32_t (*LSM6DSO_DeInit_Func)(void); +typedef int32_t (*LSM6DSO_GetTick_Func)(void); +typedef void (*LSM6DSO_Delay_Func)(uint32_t); +typedef int32_t (*LSM6DSO_WriteReg_Func)(uint16_t, uint16_t, uint8_t *, uint16_t); +typedef int32_t (*LSM6DSO_ReadReg_Func)(uint16_t, uint16_t, uint8_t *, uint16_t); + +typedef enum +{ + LSM6DSO_INT1_PIN, + LSM6DSO_INT2_PIN, +} LSM6DSO_SensorIntPin_t; + +typedef enum +{ + LSM6DSO_ACC_HIGH_PERFORMANCE_MODE, + LSM6DSO_ACC_LOW_POWER_NORMAL_MODE, + LSM6DSO_ACC_ULTRA_LOW_POWER_MODE +} LSM6DSO_ACC_Operating_Mode_t; + +typedef enum +{ + LSM6DSO_GYRO_HIGH_PERFORMANCE_MODE, + LSM6DSO_GYRO_LOW_POWER_NORMAL_MODE +} LSM6DSO_GYRO_Operating_Mode_t; + +typedef struct +{ + LSM6DSO_Init_Func Init; + LSM6DSO_DeInit_Func DeInit; + uint32_t BusType; /*0 means I2C, 1 means SPI 4-Wires, 2 means SPI-3-Wires */ + uint8_t Address; + LSM6DSO_WriteReg_Func WriteReg; + LSM6DSO_ReadReg_Func ReadReg; + LSM6DSO_GetTick_Func GetTick; + LSM6DSO_Delay_Func Delay; +} LSM6DSO_IO_t; + + +typedef struct +{ + int16_t x; + int16_t y; + int16_t z; +} LSM6DSO_AxesRaw_t; + +typedef struct +{ + int32_t x; + int32_t y; + int32_t z; +} LSM6DSO_Axes_t; + +typedef struct +{ + unsigned int FreeFallStatus : 1; + unsigned int TapStatus : 1; + unsigned int DoubleTapStatus : 1; + unsigned int WakeUpStatus : 1; + unsigned int StepStatus : 1; + unsigned int TiltStatus : 1; + unsigned int D6DOrientationStatus : 1; + unsigned int SleepStatus : 1; +} LSM6DSO_Event_Status_t; + +typedef struct +{ + LSM6DSO_IO_t IO; + stmdev_ctx_t Ctx; + uint8_t is_initialized; + uint8_t acc_is_enabled; + uint8_t gyro_is_enabled; + lsm6dso_odr_xl_t acc_odr; + lsm6dso_odr_g_t gyro_odr; +} LSM6DSO_Object_t; + +typedef struct +{ + uint8_t Acc; + uint8_t Gyro; + uint8_t Magneto; + uint8_t LowPower; + uint32_t GyroMaxFS; + uint32_t AccMaxFS; + uint32_t MagMaxFS; + float_t GyroMaxOdr; + float_t AccMaxOdr; + float_t MagMaxOdr; +} LSM6DSO_Capabilities_t; + +typedef struct +{ + int32_t (*Init)(LSM6DSO_Object_t *); + int32_t (*DeInit)(LSM6DSO_Object_t *); + int32_t (*ReadID)(LSM6DSO_Object_t *, uint8_t *); + int32_t (*GetCapabilities)(LSM6DSO_Object_t *, LSM6DSO_Capabilities_t *); +} LSM6DSO_CommonDrv_t; + +typedef struct +{ + int32_t (*Enable)(LSM6DSO_Object_t *); + int32_t (*Disable)(LSM6DSO_Object_t *); + int32_t (*GetSensitivity)(LSM6DSO_Object_t *, float_t *); + int32_t (*GetOutputDataRate)(LSM6DSO_Object_t *, float_t *); + int32_t (*SetOutputDataRate)(LSM6DSO_Object_t *, float_t); + int32_t (*GetFullScale)(LSM6DSO_Object_t *, int32_t *); + int32_t (*SetFullScale)(LSM6DSO_Object_t *, int32_t); + int32_t (*GetAxes)(LSM6DSO_Object_t *, LSM6DSO_Axes_t *); + int32_t (*GetAxesRaw)(LSM6DSO_Object_t *, LSM6DSO_AxesRaw_t *); +} LSM6DSO_ACC_Drv_t; + +typedef struct +{ + int32_t (*Enable)(LSM6DSO_Object_t *); + int32_t (*Disable)(LSM6DSO_Object_t *); + int32_t (*GetSensitivity)(LSM6DSO_Object_t *, float_t *); + int32_t (*GetOutputDataRate)(LSM6DSO_Object_t *, float_t *); + int32_t (*SetOutputDataRate)(LSM6DSO_Object_t *, float_t); + int32_t (*GetFullScale)(LSM6DSO_Object_t *, int32_t *); + int32_t (*SetFullScale)(LSM6DSO_Object_t *, int32_t); + int32_t (*GetAxes)(LSM6DSO_Object_t *, LSM6DSO_Axes_t *); + int32_t (*GetAxesRaw)(LSM6DSO_Object_t *, LSM6DSO_AxesRaw_t *); +} LSM6DSO_GYRO_Drv_t; + +typedef union +{ + int16_t i16bit[3]; + uint8_t u8bit[6]; +} lsm6dso_axis3bit16_t; + +typedef union +{ + int16_t i16bit; + uint8_t u8bit[2]; +} lsm6dso_axis1bit16_t; + +typedef union +{ + int32_t i32bit[3]; + uint8_t u8bit[12]; +} lsm6dso_axis3bit32_t; + +typedef union +{ + int32_t i32bit; + uint8_t u8bit[4]; +} lsm6dso_axis1bit32_t; + +/** + * @} + */ + +/** @defgroup LSM6DSO_Exported_Constants LSM6DSO Exported Constants + * @{ + */ + +#define LSM6DSO_OK 0 +#define LSM6DSO_ERROR -1 + +#define LSM6DSO_I2C_BUS 0U +#define LSM6DSO_SPI_4WIRES_BUS 1U +#define LSM6DSO_SPI_3WIRES_BUS 2U + +#define LSM6DSO_ACC_SENSITIVITY_FS_2G 0.061f +#define LSM6DSO_ACC_SENSITIVITY_FS_4G 0.122f +#define LSM6DSO_ACC_SENSITIVITY_FS_8G 0.244f +#define LSM6DSO_ACC_SENSITIVITY_FS_16G 0.488f + +#define LSM6DSO_GYRO_SENSITIVITY_FS_125DPS 4.375f +#define LSM6DSO_GYRO_SENSITIVITY_FS_250DPS 8.750f +#define LSM6DSO_GYRO_SENSITIVITY_FS_500DPS 17.500f +#define LSM6DSO_GYRO_SENSITIVITY_FS_1000DPS 35.000f +#define LSM6DSO_GYRO_SENSITIVITY_FS_2000DPS 70.000f + +/** + * @} + */ + +/** @addtogroup LSM6DSO_Exported_Functions LSM6DSO Exported Functions + * @{ + */ + +int32_t LSM6DSO_RegisterBusIO(LSM6DSO_Object_t *pObj, LSM6DSO_IO_t *pIO); +int32_t LSM6DSO_Init(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_DeInit(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ReadID(LSM6DSO_Object_t *pObj, uint8_t *Id); +int32_t LSM6DSO_GetCapabilities(LSM6DSO_Object_t *pObj, LSM6DSO_Capabilities_t *Capabilities); + +int32_t LSM6DSO_ACC_Enable(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Disable(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_GetSensitivity(LSM6DSO_Object_t *pObj, float_t *Sensitivity); +int32_t LSM6DSO_ACC_GetOutputDataRate(LSM6DSO_Object_t *pObj, float_t *Odr); +int32_t LSM6DSO_ACC_SetOutputDataRate(LSM6DSO_Object_t *pObj, float_t Odr); +int32_t LSM6DSO_ACC_SetOutputDataRate_With_Mode(LSM6DSO_Object_t *pObj, float_t Odr, LSM6DSO_ACC_Operating_Mode_t Mode); +int32_t LSM6DSO_ACC_GetFullScale(LSM6DSO_Object_t *pObj, int32_t *FullScale); +int32_t LSM6DSO_ACC_SetFullScale(LSM6DSO_Object_t *pObj, int32_t FullScale); +int32_t LSM6DSO_ACC_GetAxesRaw(LSM6DSO_Object_t *pObj, LSM6DSO_AxesRaw_t *Value); +int32_t LSM6DSO_ACC_GetAxes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *Acceleration); + +int32_t LSM6DSO_GYRO_Enable(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_GYRO_Disable(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_GYRO_GetSensitivity(LSM6DSO_Object_t *pObj, float_t *Sensitivity); +int32_t LSM6DSO_GYRO_GetOutputDataRate(LSM6DSO_Object_t *pObj, float_t *Odr); +int32_t LSM6DSO_GYRO_SetOutputDataRate(LSM6DSO_Object_t *pObj, float_t Odr); +int32_t LSM6DSO_GYRO_SetOutputDataRate_With_Mode(LSM6DSO_Object_t *pObj, float_t Odr, + LSM6DSO_GYRO_Operating_Mode_t Mode); +int32_t LSM6DSO_GYRO_GetFullScale(LSM6DSO_Object_t *pObj, int32_t *FullScale); +int32_t LSM6DSO_GYRO_SetFullScale(LSM6DSO_Object_t *pObj, int32_t FullScale); +int32_t LSM6DSO_GYRO_GetAxesRaw(LSM6DSO_Object_t *pObj, LSM6DSO_AxesRaw_t *Value); +int32_t LSM6DSO_GYRO_GetAxes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *AngularRate); + +int32_t LSM6DSO_Read_Reg(LSM6DSO_Object_t *pObj, uint8_t reg, uint8_t *Data); +int32_t LSM6DSO_Write_Reg(LSM6DSO_Object_t *pObj, uint8_t reg, uint8_t Data); +int32_t LSM6DSO_Set_Interrupt_Latch(LSM6DSO_Object_t *pObj, uint8_t Status); + +int32_t LSM6DSO_ACC_Enable_Free_Fall_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_Free_Fall_Detection(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Set_Free_Fall_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold); +int32_t LSM6DSO_ACC_Set_Free_Fall_Duration(LSM6DSO_Object_t *pObj, uint8_t Duration); + +int32_t LSM6DSO_ACC_Enable_Pedometer(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Disable_Pedometer(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Get_Step_Count(LSM6DSO_Object_t *pObj, uint16_t *StepCount); +int32_t LSM6DSO_ACC_Step_Counter_Reset(LSM6DSO_Object_t *pObj); + +int32_t LSM6DSO_ACC_Enable_Tilt_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_Tilt_Detection(LSM6DSO_Object_t *pObj); + +int32_t LSM6DSO_ACC_Enable_Wake_Up_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_Wake_Up_Detection(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Set_Wake_Up_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold); +int32_t LSM6DSO_ACC_Set_Wake_Up_Duration(LSM6DSO_Object_t *pObj, uint8_t Duration); + +int32_t LSM6DSO_ACC_Enable_Single_Tap_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_Single_Tap_Detection(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Enable_Double_Tap_Detection(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_Double_Tap_Detection(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Set_Tap_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold); +int32_t LSM6DSO_ACC_Set_Tap_Shock_Time(LSM6DSO_Object_t *pObj, uint8_t Time); +int32_t LSM6DSO_ACC_Set_Tap_Quiet_Time(LSM6DSO_Object_t *pObj, uint8_t Time); +int32_t LSM6DSO_ACC_Set_Tap_Duration_Time(LSM6DSO_Object_t *pObj, uint8_t Time); + +int32_t LSM6DSO_ACC_Enable_6D_Orientation(LSM6DSO_Object_t *pObj, LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_6D_Orientation(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Set_6D_Orientation_Threshold(LSM6DSO_Object_t *pObj, uint8_t Threshold); +int32_t LSM6DSO_ACC_Get_6D_Orientation_XL(LSM6DSO_Object_t *pObj, uint8_t *XLow); +int32_t LSM6DSO_ACC_Get_6D_Orientation_XH(LSM6DSO_Object_t *pObj, uint8_t *XHigh); +int32_t LSM6DSO_ACC_Get_6D_Orientation_YL(LSM6DSO_Object_t *pObj, uint8_t *YLow); +int32_t LSM6DSO_ACC_Get_6D_Orientation_YH(LSM6DSO_Object_t *pObj, uint8_t *YHigh); +int32_t LSM6DSO_ACC_Get_6D_Orientation_ZL(LSM6DSO_Object_t *pObj, uint8_t *ZLow); +int32_t LSM6DSO_ACC_Get_6D_Orientation_ZH(LSM6DSO_Object_t *pObj, uint8_t *ZHigh); + +int32_t LSM6DSO_ACC_Get_DRDY_Status(LSM6DSO_Object_t *pObj, uint8_t *Status); +int32_t LSM6DSO_ACC_Get_Event_Status(LSM6DSO_Object_t *pObj, LSM6DSO_Event_Status_t *Status); +int32_t LSM6DSO_ACC_Set_SelfTest(LSM6DSO_Object_t *pObj, uint8_t Status); + +int32_t LSM6DSO_GYRO_Get_DRDY_Status(LSM6DSO_Object_t *pObj, uint8_t *Status); +int32_t LSM6DSO_GYRO_Set_SelfTest(LSM6DSO_Object_t *pObj, uint8_t Status); + +int32_t LSM6DSO_FIFO_Get_Num_Samples(LSM6DSO_Object_t *pObj, uint16_t *NumSamples); +int32_t LSM6DSO_FIFO_Get_Full_Status(LSM6DSO_Object_t *pObj, uint8_t *Status); +int32_t LSM6DSO_FIFO_Set_INT1_FIFO_Full(LSM6DSO_Object_t *pObj, uint8_t Status); +int32_t LSM6DSO_FIFO_Set_Watermark_Level(LSM6DSO_Object_t *pObj, uint16_t Watermark); +int32_t LSM6DSO_FIFO_Set_Stop_On_Fth(LSM6DSO_Object_t *pObj, uint8_t Status); +int32_t LSM6DSO_FIFO_Set_Mode(LSM6DSO_Object_t *pObj, uint8_t Mode); +int32_t LSM6DSO_FIFO_Get_Tag(LSM6DSO_Object_t *pObj, uint8_t *Tag); +int32_t LSM6DSO_FIFO_Get_Data(LSM6DSO_Object_t *pObj, uint8_t *Data); +int32_t LSM6DSO_FIFO_Get_Empty_Status(LSM6DSO_Object_t *pObj, uint8_t *Status); +int32_t LSM6DSO_FIFO_Get_Overrun_Status(LSM6DSO_Object_t *pObj, uint8_t *Status); +int32_t LSM6DSO_FIFO_ACC_Get_Axes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *Acceleration); +int32_t LSM6DSO_FIFO_ACC_Set_BDR(LSM6DSO_Object_t *pObj, float_t Bdr); +int32_t LSM6DSO_FIFO_GYRO_Get_Axes(LSM6DSO_Object_t *pObj, LSM6DSO_Axes_t *AngularVelocity); +int32_t LSM6DSO_FIFO_GYRO_Set_BDR(LSM6DSO_Object_t *pObj, float_t Bdr); + +int32_t LSM6DSO_ACC_Enable_DRDY_On_INT1(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Disable_DRDY_On_INT1(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Set_Power_Mode(LSM6DSO_Object_t *pObj, uint8_t PowerMode); +int32_t LSM6DSO_ACC_Set_Filter_Mode(LSM6DSO_Object_t *pObj, uint8_t LowHighPassFlag, uint8_t FilterMode); +int32_t LSM6DSO_ACC_Enable_Inactivity_Detection(LSM6DSO_Object_t *pObj, lsm6dso_inact_en_t InactMode, + LSM6DSO_SensorIntPin_t IntPin); +int32_t LSM6DSO_ACC_Disable_Inactivity_Detection(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_ACC_Set_Sleep_Duration(LSM6DSO_Object_t *pObj, uint8_t Duration); + +int32_t LSM6DSO_GYRO_Enable_DRDY_On_INT2(LSM6DSO_Object_t *pObj); +int32_t LSM6DSO_GYRO_Set_Power_Mode(LSM6DSO_Object_t *pObj, uint8_t PowerMode); +int32_t LSM6DSO_GYRO_Set_Filter_Mode(LSM6DSO_Object_t *pObj, uint8_t LowHighPassFlag, uint8_t FilterMode); + +int32_t LSM6DSO_DRDY_Set_Mode(LSM6DSO_Object_t *pObj, uint8_t Mode); + +/** + * @} + */ + +/** @addtogroup LSM6DSO_Exported_Variables LSM6DSO Exported Variables + * @{ + */ + +extern LSM6DSO_CommonDrv_t LSM6DSO_COMMON_Driver; +extern LSM6DSO_ACC_Drv_t LSM6DSO_ACC_Driver; +extern LSM6DSO_GYRO_Drv_t LSM6DSO_GYRO_Driver; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.c b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.c new file mode 100644 index 00000000000..9eb6542ee37 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.c @@ -0,0 +1,13139 @@ +/** + ****************************************************************************** + * @file lsm6dso_reg.c + * @author Sensors Software Solution Team + * @brief LSM6DSO driver file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include "lsm6dso_reg.h" +#include + +/** + * @defgroup LSM6DSO + * @brief This file provides a set of functions needed to drive the + * lsm6dso enhanced inertial module. + * @{ + * + */ + +/** + * @defgroup LSM6DSO_Interfaces_Functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +/** + * @brief Read generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to read + * @param data pointer to buffer that store the data read(ptr) + * @param len number of consecutive register to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t __weak lsm6dso_read_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len) +{ + int32_t ret; + + ret = ctx->read_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @brief Write generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to write + * @param data pointer to data to write in register reg(ptr) + * @param len number of consecutive register to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t __weak lsm6dso_write_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len) +{ + int32_t ret; + + ret = ctx->write_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSOX_Private_functions + * @brief Section collect all the utility functions needed by APIs. + * @{ + * + */ + +static void bytecpy(uint8_t *target, uint8_t *source) +{ + if ((target != NULL) && (source != NULL)) + { + *target = *source; + } +} + +/** + * @defgroup LSM6DSO_Sensitivity + * @brief These functions convert raw-data into engineering units. + * @{ + * + */ +float_t lsm6dso_from_fs2_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.061f; +} + +float_t lsm6dso_from_fs4_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.122f; +} + +float_t lsm6dso_from_fs8_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.244f; +} + +float_t lsm6dso_from_fs16_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.488f; +} + +float_t lsm6dso_from_fs125_to_mdps(int16_t lsb) +{ + return ((float_t)lsb) * 4.375f; +} + +float_t lsm6dso_from_fs500_to_mdps(int16_t lsb) +{ + return ((float_t)lsb) * 17.50f; +} + +float_t lsm6dso_from_fs250_to_mdps(int16_t lsb) +{ + return ((float_t)lsb) * 8.750f; +} + +float_t lsm6dso_from_fs1000_to_mdps(int16_t lsb) +{ + return ((float_t)lsb) * 35.0f; +} + +float_t lsm6dso_from_fs2000_to_mdps(int16_t lsb) +{ + return ((float_t)lsb) * 70.0f; +} + +float_t lsm6dso_from_lsb_to_celsius(int16_t lsb) +{ + return (((float_t)lsb / 256.0f) + 25.0f); +} + +float_t lsm6dso_from_lsb_to_nsec(int16_t lsb) +{ + return ((float_t)lsb * 25000.0f); +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_Data_Generation + * @brief This section groups all the functions concerning + * data generation. + * + */ + +/** + * @brief Accelerometer full-scale selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fs_xl in reg CTRL1_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_t val) +{ + lsm6dso_ctrl1_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fs_xl = (uint8_t) val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer full-scale selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fs_xl in reg CTRL1_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_t *val) +{ + lsm6dso_ctrl1_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + + switch (reg.fs_xl) + { + case LSM6DSO_2g: + *val = LSM6DSO_2g; + break; + + case LSM6DSO_16g: + *val = LSM6DSO_16g; + break; + + case LSM6DSO_4g: + *val = LSM6DSO_4g; + break; + + case LSM6DSO_8g: + *val = LSM6DSO_8g; + break; + + default: + *val = LSM6DSO_2g; + break; + } + + return ret; +} + +/** + * @brief Accelerometer UI data rate selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of odr_xl in reg CTRL1_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_odr_xl_t val) +{ + lsm6dso_odr_xl_t odr_xl = val; + lsm6dso_emb_fsm_enable_t fsm_enable; + lsm6dso_fsm_odr_t fsm_odr; + lsm6dso_ctrl1_xl_t reg; + int32_t ret; + + /* Check the Finite State Machine data rate constraints */ + ret = lsm6dso_fsm_enable_get(ctx, &fsm_enable); + + if (ret == 0) + { + if ((fsm_enable.fsm_enable_a.fsm1_en | + fsm_enable.fsm_enable_a.fsm2_en | + fsm_enable.fsm_enable_a.fsm3_en | + fsm_enable.fsm_enable_a.fsm4_en | + fsm_enable.fsm_enable_a.fsm5_en | + fsm_enable.fsm_enable_a.fsm6_en | + fsm_enable.fsm_enable_a.fsm7_en | + fsm_enable.fsm_enable_a.fsm8_en | + fsm_enable.fsm_enable_b.fsm9_en | + fsm_enable.fsm_enable_b.fsm10_en | + fsm_enable.fsm_enable_b.fsm11_en | + fsm_enable.fsm_enable_b.fsm12_en | + fsm_enable.fsm_enable_b.fsm13_en | + fsm_enable.fsm_enable_b.fsm14_en | + fsm_enable.fsm_enable_b.fsm15_en | + fsm_enable.fsm_enable_b.fsm16_en) == PROPERTY_ENABLE) + { + ret = lsm6dso_fsm_data_rate_get(ctx, &fsm_odr); + + if (ret == 0) + { + switch (fsm_odr) + { + case LSM6DSO_ODR_FSM_12Hz5: + if (val == LSM6DSO_XL_ODR_OFF) + { + odr_xl = LSM6DSO_XL_ODR_12Hz5; + } + + else + { + odr_xl = val; + } + + break; + + case LSM6DSO_ODR_FSM_26Hz: + if (val == LSM6DSO_XL_ODR_OFF) + { + odr_xl = LSM6DSO_XL_ODR_26Hz; + } + + else if (val == LSM6DSO_XL_ODR_12Hz5) + { + odr_xl = LSM6DSO_XL_ODR_26Hz; + } + + else + { + odr_xl = val; + } + + break; + + case LSM6DSO_ODR_FSM_52Hz: + if (val == LSM6DSO_XL_ODR_OFF) + { + odr_xl = LSM6DSO_XL_ODR_52Hz; + } + + else if (val == LSM6DSO_XL_ODR_12Hz5) + { + odr_xl = LSM6DSO_XL_ODR_52Hz; + } + + else if (val == LSM6DSO_XL_ODR_26Hz) + { + odr_xl = LSM6DSO_XL_ODR_52Hz; + } + + else + { + odr_xl = val; + } + + break; + + case LSM6DSO_ODR_FSM_104Hz: + if (val == LSM6DSO_XL_ODR_OFF) + { + odr_xl = LSM6DSO_XL_ODR_104Hz; + } + + else if (val == LSM6DSO_XL_ODR_12Hz5) + { + odr_xl = LSM6DSO_XL_ODR_104Hz; + } + + else if (val == LSM6DSO_XL_ODR_26Hz) + { + odr_xl = LSM6DSO_XL_ODR_104Hz; + } + + else if (val == LSM6DSO_XL_ODR_52Hz) + { + odr_xl = LSM6DSO_XL_ODR_104Hz; + } + + else + { + odr_xl = val; + } + + break; + + default: + odr_xl = val; + break; + } + } + } + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.odr_xl = (uint8_t) odr_xl; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer UI data rate selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of odr_xl in reg CTRL1_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_odr_xl_t *val) +{ + lsm6dso_ctrl1_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + + switch (reg.odr_xl) + { + case LSM6DSO_XL_ODR_OFF: + *val = LSM6DSO_XL_ODR_OFF; + break; + + case LSM6DSO_XL_ODR_12Hz5: + *val = LSM6DSO_XL_ODR_12Hz5; + break; + + case LSM6DSO_XL_ODR_26Hz: + *val = LSM6DSO_XL_ODR_26Hz; + break; + + case LSM6DSO_XL_ODR_52Hz: + *val = LSM6DSO_XL_ODR_52Hz; + break; + + case LSM6DSO_XL_ODR_104Hz: + *val = LSM6DSO_XL_ODR_104Hz; + break; + + case LSM6DSO_XL_ODR_208Hz: + *val = LSM6DSO_XL_ODR_208Hz; + break; + + case LSM6DSO_XL_ODR_417Hz: + *val = LSM6DSO_XL_ODR_417Hz; + break; + + case LSM6DSO_XL_ODR_833Hz: + *val = LSM6DSO_XL_ODR_833Hz; + break; + + case LSM6DSO_XL_ODR_1667Hz: + *val = LSM6DSO_XL_ODR_1667Hz; + break; + + case LSM6DSO_XL_ODR_3333Hz: + *val = LSM6DSO_XL_ODR_3333Hz; + break; + + case LSM6DSO_XL_ODR_6667Hz: + *val = LSM6DSO_XL_ODR_6667Hz; + break; + + case LSM6DSO_XL_ODR_1Hz6: + *val = LSM6DSO_XL_ODR_1Hz6; + break; + + default: + *val = LSM6DSO_XL_ODR_OFF; + break; + } + + return ret; +} + +/** + * @brief Gyroscope UI chain full-scale selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fs_g in reg CTRL2_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_g_t val) +{ + lsm6dso_ctrl2_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fs_g = (uint8_t) val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Gyroscope UI chain full-scale selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fs_g in reg CTRL2_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_g_t *val) +{ + lsm6dso_ctrl2_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t *)®, 1); + + switch (reg.fs_g) + { + case LSM6DSO_250dps: + *val = LSM6DSO_250dps; + break; + + case LSM6DSO_125dps: + *val = LSM6DSO_125dps; + break; + + case LSM6DSO_500dps: + *val = LSM6DSO_500dps; + break; + + case LSM6DSO_1000dps: + *val = LSM6DSO_1000dps; + break; + + case LSM6DSO_2000dps: + *val = LSM6DSO_2000dps; + break; + + default: + *val = LSM6DSO_250dps; + break; + } + + return ret; +} + +/** + * @brief Gyroscope UI data rate selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of odr_g in reg CTRL2_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_odr_g_t val) +{ + lsm6dso_odr_g_t odr_gy = val; + lsm6dso_emb_fsm_enable_t fsm_enable; + lsm6dso_fsm_odr_t fsm_odr; + lsm6dso_ctrl2_g_t reg; + int32_t ret; + + /* Check the Finite State Machine data rate constraints */ + ret = lsm6dso_fsm_enable_get(ctx, &fsm_enable); + + if (ret == 0) + { + if ((fsm_enable.fsm_enable_a.fsm1_en | + fsm_enable.fsm_enable_a.fsm2_en | + fsm_enable.fsm_enable_a.fsm3_en | + fsm_enable.fsm_enable_a.fsm4_en | + fsm_enable.fsm_enable_a.fsm5_en | + fsm_enable.fsm_enable_a.fsm6_en | + fsm_enable.fsm_enable_a.fsm7_en | + fsm_enable.fsm_enable_a.fsm8_en | + fsm_enable.fsm_enable_b.fsm9_en | + fsm_enable.fsm_enable_b.fsm10_en | + fsm_enable.fsm_enable_b.fsm11_en | + fsm_enable.fsm_enable_b.fsm12_en | + fsm_enable.fsm_enable_b.fsm13_en | + fsm_enable.fsm_enable_b.fsm14_en | + fsm_enable.fsm_enable_b.fsm15_en | + fsm_enable.fsm_enable_b.fsm16_en) == PROPERTY_ENABLE) + { + ret = lsm6dso_fsm_data_rate_get(ctx, &fsm_odr); + + if (ret == 0) + { + switch (fsm_odr) + { + case LSM6DSO_ODR_FSM_12Hz5: + if (val == LSM6DSO_GY_ODR_OFF) + { + odr_gy = LSM6DSO_GY_ODR_12Hz5; + } + + else + { + odr_gy = val; + } + + break; + + case LSM6DSO_ODR_FSM_26Hz: + if (val == LSM6DSO_GY_ODR_OFF) + { + odr_gy = LSM6DSO_GY_ODR_26Hz; + } + + else if (val == LSM6DSO_GY_ODR_12Hz5) + { + odr_gy = LSM6DSO_GY_ODR_26Hz; + } + + else + { + odr_gy = val; + } + + break; + + case LSM6DSO_ODR_FSM_52Hz: + if (val == LSM6DSO_GY_ODR_OFF) + { + odr_gy = LSM6DSO_GY_ODR_52Hz; + } + + else if (val == LSM6DSO_GY_ODR_12Hz5) + { + odr_gy = LSM6DSO_GY_ODR_52Hz; + } + + else if (val == LSM6DSO_GY_ODR_26Hz) + { + odr_gy = LSM6DSO_GY_ODR_52Hz; + } + + else + { + odr_gy = val; + } + + break; + + case LSM6DSO_ODR_FSM_104Hz: + if (val == LSM6DSO_GY_ODR_OFF) + { + odr_gy = LSM6DSO_GY_ODR_104Hz; + } + + else if (val == LSM6DSO_GY_ODR_12Hz5) + { + odr_gy = LSM6DSO_GY_ODR_104Hz; + } + + else if (val == LSM6DSO_GY_ODR_26Hz) + { + odr_gy = LSM6DSO_GY_ODR_104Hz; + } + + else if (val == LSM6DSO_GY_ODR_52Hz) + { + odr_gy = LSM6DSO_GY_ODR_104Hz; + } + + else + { + odr_gy = val; + } + + break; + + default: + odr_gy = val; + break; + } + } + } + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.odr_g = (uint8_t) odr_gy; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Gyroscope UI data rate selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of odr_g in reg CTRL2_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_odr_g_t *val) +{ + lsm6dso_ctrl2_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_G, (uint8_t *)®, 1); + + switch (reg.odr_g) + { + case LSM6DSO_GY_ODR_OFF: + *val = LSM6DSO_GY_ODR_OFF; + break; + + case LSM6DSO_GY_ODR_12Hz5: + *val = LSM6DSO_GY_ODR_12Hz5; + break; + + case LSM6DSO_GY_ODR_26Hz: + *val = LSM6DSO_GY_ODR_26Hz; + break; + + case LSM6DSO_GY_ODR_52Hz: + *val = LSM6DSO_GY_ODR_52Hz; + break; + + case LSM6DSO_GY_ODR_104Hz: + *val = LSM6DSO_GY_ODR_104Hz; + break; + + case LSM6DSO_GY_ODR_208Hz: + *val = LSM6DSO_GY_ODR_208Hz; + break; + + case LSM6DSO_GY_ODR_417Hz: + *val = LSM6DSO_GY_ODR_417Hz; + break; + + case LSM6DSO_GY_ODR_833Hz: + *val = LSM6DSO_GY_ODR_833Hz; + break; + + case LSM6DSO_GY_ODR_1667Hz: + *val = LSM6DSO_GY_ODR_1667Hz; + break; + + case LSM6DSO_GY_ODR_3333Hz: + *val = LSM6DSO_GY_ODR_3333Hz; + break; + + case LSM6DSO_GY_ODR_6667Hz: + *val = LSM6DSO_GY_ODR_6667Hz; + break; + + default: + *val = LSM6DSO_GY_ODR_OFF; + break; + } + + return ret; +} + +/** + * @brief Block data update.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of bdu in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_block_data_update_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.bdu = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Block data update.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of bdu in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_block_data_update_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + *val = reg.bdu; + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers X_OFS_USR (73h), + * Y_OFS_USR (74h), Z_OFS_USR (75h).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of usr_off_w in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_offset_weight_set(stmdev_ctx_t *ctx, + lsm6dso_usr_off_w_t val) +{ + lsm6dso_ctrl6_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.usr_off_w = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers X_OFS_USR (73h), + * Y_OFS_USR (74h), Z_OFS_USR (75h).[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of usr_off_w in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_offset_weight_get(stmdev_ctx_t *ctx, + lsm6dso_usr_off_w_t *val) +{ + lsm6dso_ctrl6_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + + switch (reg.usr_off_w) + { + case LSM6DSO_LSb_1mg: + *val = LSM6DSO_LSb_1mg; + break; + + case LSM6DSO_LSb_16mg: + *val = LSM6DSO_LSb_16mg; + break; + + default: + *val = LSM6DSO_LSb_1mg; + break; + } + + return ret; +} + +/** + * @brief Accelerometer power mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of xl_hm_mode in + * reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_power_mode_set(stmdev_ctx_t *ctx, + lsm6dso_xl_hm_mode_t val) +{ + lsm6dso_ctrl5_c_t ctrl5_c; + lsm6dso_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *) &ctrl5_c, 1); + + if (ret == 0) + { + ctrl5_c.xl_ulp_en = ((uint8_t)val & 0x02U) >> 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *) &ctrl5_c, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *) &ctrl6_c, 1); + } + + if (ret == 0) + { + ctrl6_c.xl_hm_mode = (uint8_t)val & 0x01U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *) &ctrl6_c, 1); + } + + return ret; +} + +/** + * @brief Accelerometer power mode.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of xl_hm_mode in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_power_mode_get(stmdev_ctx_t *ctx, + lsm6dso_xl_hm_mode_t *val) +{ + lsm6dso_ctrl5_c_t ctrl5_c; + lsm6dso_ctrl6_c_t ctrl6_c; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *) &ctrl5_c, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *) &ctrl6_c, 1); + + switch ((ctrl5_c.xl_ulp_en << 1) | ctrl6_c.xl_hm_mode) + { + case LSM6DSO_HIGH_PERFORMANCE_MD: + *val = LSM6DSO_HIGH_PERFORMANCE_MD; + break; + + case LSM6DSO_LOW_NORMAL_POWER_MD: + *val = LSM6DSO_LOW_NORMAL_POWER_MD; + break; + + case LSM6DSO_ULTRA_LOW_POWER_MD: + *val = LSM6DSO_ULTRA_LOW_POWER_MD; + break; + + default: + *val = LSM6DSO_HIGH_PERFORMANCE_MD; + break; + } + } + + return ret; +} + +/** + * @brief Operating mode for gyroscope.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of g_hm_mode in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_power_mode_set(stmdev_ctx_t *ctx, + lsm6dso_g_hm_mode_t val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.g_hm_mode = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Operating mode for gyroscope.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of g_hm_mode in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_power_mode_get(stmdev_ctx_t *ctx, + lsm6dso_g_hm_mode_t *val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + switch (reg.g_hm_mode) + { + case LSM6DSO_GY_HIGH_PERFORMANCE: + *val = LSM6DSO_GY_HIGH_PERFORMANCE; + break; + + case LSM6DSO_GY_NORMAL: + *val = LSM6DSO_GY_NORMAL; + break; + + default: + *val = LSM6DSO_GY_HIGH_PERFORMANCE; + break; + } + + return ret; +} + +/** + * @brief The STATUS_REG register is read by the primary interface.[get] + * + * @param ctx read / write interface definitions + * @param val register STATUS_REG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_status_reg_get(stmdev_ctx_t *ctx, + lsm6dso_status_reg_t *val) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief Accelerometer new data available.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of xlda in reg STATUS_REG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_status_reg_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t *)®, 1); + *val = reg.xlda; + + return ret; +} + +/** + * @brief Gyroscope new data available.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of gda in reg STATUS_REG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_status_reg_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t *)®, 1); + *val = reg.gda; + + return ret; +} + +/** + * @brief Temperature new data available.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tda in reg STATUS_REG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_temp_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_status_reg_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, (uint8_t *)®, 1); + *val = reg.tda; + + return ret; +} + +/** + * @brief Accelerometer X-axis user offset correction expressed in + * two's complement, weight depends on USR_OFF_W in CTRL6_C (15h). + * The value must be in the range [-127 127].[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_x_set(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_write_reg(ctx, LSM6DSO_X_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer X-axis user offset correction expressed in two's + * complement, weight depends on USR_OFF_W in CTRL6_C (15h). + * The value must be in the range [-127 127].[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_x_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_X_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Y-axis user offset correction expressed in two's + * complement, weight depends on USR_OFF_W in CTRL6_C (15h). + * The value must be in the range [-127 127].[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_y_set(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_write_reg(ctx, LSM6DSO_Y_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Y-axis user offset correction expressed in two's + * complement, weight depends on USR_OFF_W in CTRL6_C (15h). + * The value must be in the range [-127 127].[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_y_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_Y_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Z-axis user offset correction expressed in two's + * complement, weight depends on USR_OFF_W in CTRL6_C (15h). + * The value must be in the range [-127 127].[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_z_set(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_write_reg(ctx, LSM6DSO_Z_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Z-axis user offset correction expressed in two's + * complement, weight depends on USR_OFF_W in CTRL6_C (15h). + * The value must be in the range [-127 127].[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_z_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_Z_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Enables user offset on out.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of usr_off_on_out in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.usr_off_on_out = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief User offset on out flag.[get] + * + * @param ctx read / write interface definitions + * @param val values of usr_off_on_out in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + *val = reg.usr_off_on_out; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_Timestamp + * @brief This section groups all the functions that manage the + * timestamp generation. + * @{ + * + */ + +/** + * @brief Reset timestamp counter.[set] + * + * @param ctx Read / write interface definitions.(ptr) + * @retval Interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_timestamp_rst(stmdev_ctx_t *ctx) +{ + uint8_t rst_val = 0xAA; + return lsm6dso_write_reg(ctx, LSM6DSO_TIMESTAMP2, &rst_val, 1); +} + +/** + * @brief Enables timestamp counter.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of timestamp_en in reg CTRL10_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_timestamp_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl10_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL10_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.timestamp_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL10_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables timestamp counter.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of timestamp_en in reg CTRL10_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_timestamp_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl10_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL10_C, (uint8_t *)®, 1); + *val = reg.timestamp_en; + + return ret; +} + +/** + * @brief Timestamp first data output register (r). + * The value is expressed as a 32-bit word and the bit + * resolution is 25 us.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_timestamp_raw_get(stmdev_ctx_t *ctx, uint32_t *val) +{ + uint8_t buff[4]; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TIMESTAMP0, buff, 4); + *val = buff[3]; + *val = (*val * 256U) + buff[2]; + *val = (*val * 256U) + buff[1]; + *val = (*val * 256U) + buff[0]; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_Data output + * @brief This section groups all the data output functions. + * @{ + * + */ + +/** + * @brief Circular burst-mode (rounding) read of the output + * registers.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of rounding in reg CTRL5_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_rounding_mode_set(stmdev_ctx_t *ctx, + lsm6dso_rounding_t val) +{ + lsm6dso_ctrl5_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.rounding = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Gyroscope UI chain full-scale selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of rounding in reg CTRL5_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_rounding_mode_get(stmdev_ctx_t *ctx, + lsm6dso_rounding_t *val) +{ + lsm6dso_ctrl5_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + + switch (reg.rounding) + { + case LSM6DSO_NO_ROUND: + *val = LSM6DSO_NO_ROUND; + break; + + case LSM6DSO_ROUND_XL: + *val = LSM6DSO_ROUND_XL; + break; + + case LSM6DSO_ROUND_GY: + *val = LSM6DSO_ROUND_GY; + break; + + case LSM6DSO_ROUND_GY_XL: + *val = LSM6DSO_ROUND_GY_XL; + break; + + default: + *val = LSM6DSO_NO_ROUND; + break; + } + + return ret; +} + +/** + * @brief Temperature data output register (r). + * L and H registers together express a 16-bit word in two's + * complement.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_temperature_raw_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_OUT_TEMP_L, buff, 2); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + + return ret; +} + +/** + * @brief Angular rate sensor. The value is expressed as a 16-bit + * word in two's complement.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_angular_rate_raw_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_OUTX_L_G, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief Linear acceleration output register. + * The value is expressed as a 16-bit word in two's complement.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_acceleration_raw_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_OUTX_L_A, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @brief FIFO data output [get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_out_raw_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_DATA_OUT_X_L, buff, 6); + + return ret; +} + +/** + * @brief Step counter output register.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_number_of_steps_get(stmdev_ctx_t *ctx, uint16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_STEP_COUNTER_L, buff, 2); + } + + if (ret == 0) + { + *val = buff[1]; + *val = (*val * 256U) + buff[0]; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Reset step counter register.[get] + * + * @param ctx read / write interface definitions + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_steps_reset(stmdev_ctx_t *ctx) +{ + lsm6dso_emb_func_src_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_SRC, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.pedo_rst_step = PROPERTY_ENABLE; + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_SRC, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_common + * @brief This section groups common useful functions. + * @{ + * + */ + +/** + * @brief Difference in percentage of the effective ODR(and timestamp rate) + * with respect to the typical. + * Step: 0.15%. 8-bit format, 2's complement.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of freq_fine in reg + * INTERNAL_FREQ_FINE + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_odr_cal_reg_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_internal_freq_fine_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INTERNAL_FREQ_FINE, + (uint8_t *)®, 1); + + if (ret == 0) + { + reg.freq_fine = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INTERNAL_FREQ_FINE, + (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Difference in percentage of the effective ODR(and timestamp rate) + * with respect to the typical. + * Step: 0.15%. 8-bit format, 2's complement.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of freq_fine in reg INTERNAL_FREQ_FINE + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_odr_cal_reg_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_internal_freq_fine_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INTERNAL_FREQ_FINE, + (uint8_t *)®, 1); + *val = reg.freq_fine; + + return ret; +} + + +/** + * @brief Enable access to the embedded functions/sensor + * hub configuration registers.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of reg_access in + * reg FUNC_CFG_ACCESS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mem_bank_set(stmdev_ctx_t *ctx, + lsm6dso_reg_access_t val) +{ + lsm6dso_func_cfg_access_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.reg_access = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enable access to the embedded functions/sensor + * hub configuration registers.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of reg_access in + * reg FUNC_CFG_ACCESS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mem_bank_get(stmdev_ctx_t *ctx, + lsm6dso_reg_access_t *val) +{ + lsm6dso_func_cfg_access_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, (uint8_t *)®, 1); + + switch (reg.reg_access) + { + case LSM6DSO_USER_BANK: + *val = LSM6DSO_USER_BANK; + break; + + case LSM6DSO_SENSOR_HUB_BANK: + *val = LSM6DSO_SENSOR_HUB_BANK; + break; + + case LSM6DSO_EMBEDDED_FUNC_BANK: + *val = LSM6DSO_EMBEDDED_FUNC_BANK; + break; + + default: + *val = LSM6DSO_USER_BANK; + break; + } + + return ret; +} + +/** + * @brief Write a line(byte) in a page.[set] + * + * @param ctx read / write interface definitions + * @param uint8_t address: page line address + * @param val value to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ln_pg_write_byte(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *val) +{ + lsm6dso_page_rw_t page_rw; + lsm6dso_page_sel_t page_sel; + lsm6dso_page_address_t page_address; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.page_rw = 0x02; /* page_write enable */ + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + page_sel.page_sel = ((uint8_t)(address >> 8) & 0x0FU); + page_sel.not_used_01 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + page_address.page_addr = (uint8_t)address & 0xFFU; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_ADDRESS, + (uint8_t *)&page_address, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_VALUE, val, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.page_rw = 0x00; /* page_write disable */ + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Write buffer in a page.[set] + * + * @param ctx read / write interface definitions + * @param uint8_t address: page line address + * @param uint8_t *buf: buffer to write + * @param uint8_t len: buffer len + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ln_pg_write(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *buf, uint8_t len) +{ + lsm6dso_page_rw_t page_rw; + lsm6dso_page_sel_t page_sel; + lsm6dso_page_address_t page_address; + uint16_t addr_pointed; + int32_t ret; + + uint8_t i ; + addr_pointed = address; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.page_rw = 0x02; /* page_write enable*/ + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + page_sel.page_sel = ((uint8_t)(addr_pointed >> 8) & 0x0FU); + page_sel.not_used_01 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + page_address.page_addr = (uint8_t)(addr_pointed & 0x00FFU); + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_ADDRESS, + (uint8_t *)&page_address, 1); + } + + if (ret == 0) + { + for (i = 0; ((i < len) && (ret == 0)); i++) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_VALUE, &buf[i], 1); + addr_pointed++; + + /* Check if page wrap */ + if (((addr_pointed % 0x0100U) == 0x00U) && (ret == 0)) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *)&page_sel, 1); + + if (ret == 0) + { + page_sel.page_sel = ((uint8_t)(addr_pointed >> 8) & 0x0FU); + page_sel.not_used_01 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, + (uint8_t *)&page_sel, 1); + } + } + } + + page_sel.page_sel = 0; + page_sel.not_used_01 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.page_rw = 0x00; /* page_write disable */ + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Read a line(byte) in a page.[get] + * + * @param ctx read / write interface definitions + * @param uint8_t address: page line address + * @param val read value + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ln_pg_read_byte(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *val) +{ + lsm6dso_page_rw_t page_rw; + lsm6dso_page_sel_t page_sel; + lsm6dso_page_address_t page_address; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.page_rw = 0x01; /* page_read enable*/ + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + page_sel.page_sel = ((uint8_t)(address >> 8) & 0x0FU); + page_sel.not_used_01 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_SEL, (uint8_t *) &page_sel, 1); + } + + if (ret == 0) + { + page_address.page_addr = (uint8_t)address & 0x00FFU; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_ADDRESS, + (uint8_t *)&page_address, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_VALUE, val, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.page_rw = 0x00; /* page_read disable */ + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of + * dataready_pulsed in + * reg COUNTER_BDR_REG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_data_ready_mode_set(stmdev_ctx_t *ctx, + lsm6dso_dataready_pulsed_t val) +{ + lsm6dso_counter_bdr_reg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.dataready_pulsed = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, + (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of + * dataready_pulsed in + * reg COUNTER_BDR_REG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_data_ready_mode_get(stmdev_ctx_t *ctx, + lsm6dso_dataready_pulsed_t *val) +{ + lsm6dso_counter_bdr_reg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t *)®, 1); + + switch (reg.dataready_pulsed) + { + case LSM6DSO_DRDY_LATCHED: + *val = LSM6DSO_DRDY_LATCHED; + break; + + case LSM6DSO_DRDY_PULSED: + *val = LSM6DSO_DRDY_PULSED; + break; + + default: + *val = LSM6DSO_DRDY_LATCHED; + break; + } + + return ret; +} + +/** + * @brief Device "Who am I".[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_device_id_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WHO_AM_I, buff, 1); + + return ret; +} + +/** + * @brief Software reset. Restore the default values + * in user registers[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sw_reset in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_reset_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sw_reset = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of sw_reset in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_reset_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + *val = reg.sw_reset; + + return ret; +} + +/** + * @brief Register address automatically incremented during a multiple byte + * access with a serial interface.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of if_inc in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_auto_increment_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.if_inc = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Register address automatically incremented during a multiple byte + * access with a serial interface.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of if_inc in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_auto_increment_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + *val = reg.if_inc; + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of boot in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_boot_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.boot = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of boot in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_boot_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + *val = reg.boot; + + return ret; +} + +/** + * @brief Linear acceleration sensor self-test enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of st_xl in reg CTRL5_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_xl_t val) +{ + lsm6dso_ctrl5_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.st_xl = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Linear acceleration sensor self-test enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of st_xl in reg CTRL5_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_xl_t *val) +{ + lsm6dso_ctrl5_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + + switch (reg.st_xl) + { + case LSM6DSO_XL_ST_DISABLE: + *val = LSM6DSO_XL_ST_DISABLE; + break; + + case LSM6DSO_XL_ST_POSITIVE: + *val = LSM6DSO_XL_ST_POSITIVE; + break; + + case LSM6DSO_XL_ST_NEGATIVE: + *val = LSM6DSO_XL_ST_NEGATIVE; + break; + + default: + *val = LSM6DSO_XL_ST_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Angular rate sensor self-test enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of st_g in reg CTRL5_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_g_t val) +{ + lsm6dso_ctrl5_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.st_g = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Angular rate sensor self-test enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of st_g in reg CTRL5_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_g_t *val) +{ + lsm6dso_ctrl5_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL5_C, (uint8_t *)®, 1); + + switch (reg.st_g) + { + case LSM6DSO_GY_ST_DISABLE: + *val = LSM6DSO_GY_ST_DISABLE; + break; + + case LSM6DSO_GY_ST_POSITIVE: + *val = LSM6DSO_GY_ST_POSITIVE; + break; + + case LSM6DSO_GY_ST_NEGATIVE: + *val = LSM6DSO_GY_ST_NEGATIVE; + break; + + default: + *val = LSM6DSO_GY_ST_DISABLE; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_filters + * @brief This section group all the functions concerning the + * filters configuration + * @{ + * + */ + +/** + * @brief Accelerometer output from LPF2 filtering stage selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of lpf2_xl_en in reg CTRL1_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_filter_lp2_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl1_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.lpf2_xl_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer output from LPF2 filtering stage selection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of lpf2_xl_en in reg CTRL1_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_filter_lp2_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl1_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 1); + *val = reg.lpf2_xl_en; + + return ret; +} + +/** + * @brief Enables gyroscope digital LPF1 if auxiliary SPI is disabled; + * the bandwidth can be selected through FTYPE [2:0] + * in CTRL6_C (15h).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of lpf1_sel_g in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_filter_lp1_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.lpf1_sel_g = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables gyroscope digital LPF1 if auxiliary SPI is disabled; + * the bandwidth can be selected through FTYPE [2:0] + * in CTRL6_C (15h).[get] + * + * @param ctx read / write interface definitions + * @param val change the values of lpf1_sel_g in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_filter_lp1_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + *val = reg.lpf1_sel_g; + + return ret; +} + +/** + * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends + * (XL and Gyro independently masked).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of drdy_mask in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_filter_settling_mask_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.drdy_mask = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends + * (XL and Gyro independently masked).[get] + * + * @param ctx read / write interface definitions + * @param val change the values of drdy_mask in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_filter_settling_mask_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + *val = reg.drdy_mask; + + return ret; +} + +/** + * @brief Gyroscope lp1 bandwidth.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ftype in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_lp1_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_ftype_t val) +{ + lsm6dso_ctrl6_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.ftype = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Gyroscope lp1 bandwidth.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of ftype in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_lp1_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_ftype_t *val) +{ + lsm6dso_ctrl6_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + + switch (reg.ftype) + { + case LSM6DSO_ULTRA_LIGHT: + *val = LSM6DSO_ULTRA_LIGHT; + break; + + case LSM6DSO_VERY_LIGHT: + *val = LSM6DSO_VERY_LIGHT; + break; + + case LSM6DSO_LIGHT: + *val = LSM6DSO_LIGHT; + break; + + case LSM6DSO_MEDIUM: + *val = LSM6DSO_MEDIUM; + break; + + case LSM6DSO_STRONG: + *val = LSM6DSO_STRONG; + break; + + case LSM6DSO_VERY_STRONG: + *val = LSM6DSO_VERY_STRONG; + break; + + case LSM6DSO_AGGRESSIVE: + *val = LSM6DSO_AGGRESSIVE; + break; + + case LSM6DSO_XTREME: + *val = LSM6DSO_XTREME; + break; + + default: + *val = LSM6DSO_ULTRA_LIGHT; + break; + } + + return ret; +} + +/** + * @brief Low pass filter 2 on 6D function selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of low_pass_on_6d in reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_lp2_on_6d_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.low_pass_on_6d = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Low pass filter 2 on 6D function selection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of low_pass_on_6d in reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_lp2_on_6d_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + *val = reg.low_pass_on_6d; + + return ret; +} + +/** + * @brief Accelerometer slope filter / high-pass filter selection + * on output.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of hp_slope_xl_en + * in reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_hp_path_on_out_set(stmdev_ctx_t *ctx, + lsm6dso_hp_slope_xl_en_t val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.hp_slope_xl_en = ((uint8_t)val & 0x10U) >> 4; + reg.hp_ref_mode_xl = ((uint8_t)val & 0x20U) >> 5; + reg.hpcf_xl = (uint8_t)val & 0x07U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer slope filter / high-pass filter selection + * on output.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of hp_slope_xl_en + * in reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_hp_path_on_out_get(stmdev_ctx_t *ctx, + lsm6dso_hp_slope_xl_en_t *val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + + switch ((reg.hp_ref_mode_xl << 5) | (reg.hp_slope_xl_en << 4) | + reg.hpcf_xl) + { + case LSM6DSO_HP_PATH_DISABLE_ON_OUT: + *val = LSM6DSO_HP_PATH_DISABLE_ON_OUT; + break; + + case LSM6DSO_SLOPE_ODR_DIV_4: + *val = LSM6DSO_SLOPE_ODR_DIV_4; + break; + + case LSM6DSO_HP_ODR_DIV_10: + *val = LSM6DSO_HP_ODR_DIV_10; + break; + + case LSM6DSO_HP_ODR_DIV_20: + *val = LSM6DSO_HP_ODR_DIV_20; + break; + + case LSM6DSO_HP_ODR_DIV_45: + *val = LSM6DSO_HP_ODR_DIV_45; + break; + + case LSM6DSO_HP_ODR_DIV_100: + *val = LSM6DSO_HP_ODR_DIV_100; + break; + + case LSM6DSO_HP_ODR_DIV_200: + *val = LSM6DSO_HP_ODR_DIV_200; + break; + + case LSM6DSO_HP_ODR_DIV_400: + *val = LSM6DSO_HP_ODR_DIV_400; + break; + + case LSM6DSO_HP_ODR_DIV_800: + *val = LSM6DSO_HP_ODR_DIV_800; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_10: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_10; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_20: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_20; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_45: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_45; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_100: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_100; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_200: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_200; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_400: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_400; + break; + + case LSM6DSO_HP_REF_MD_ODR_DIV_800: + *val = LSM6DSO_HP_REF_MD_ODR_DIV_800; + break; + + case LSM6DSO_LP_ODR_DIV_10: + *val = LSM6DSO_LP_ODR_DIV_10; + break; + + case LSM6DSO_LP_ODR_DIV_20: + *val = LSM6DSO_LP_ODR_DIV_20; + break; + + case LSM6DSO_LP_ODR_DIV_45: + *val = LSM6DSO_LP_ODR_DIV_45; + break; + + case LSM6DSO_LP_ODR_DIV_100: + *val = LSM6DSO_LP_ODR_DIV_100; + break; + + case LSM6DSO_LP_ODR_DIV_200: + *val = LSM6DSO_LP_ODR_DIV_200; + break; + + case LSM6DSO_LP_ODR_DIV_400: + *val = LSM6DSO_LP_ODR_DIV_400; + break; + + case LSM6DSO_LP_ODR_DIV_800: + *val = LSM6DSO_LP_ODR_DIV_800; + break; + + default: + *val = LSM6DSO_HP_PATH_DISABLE_ON_OUT; + break; + } + + return ret; +} + +/** + * @brief Enables accelerometer LPF2 and HPF fast-settling mode. + * The filter sets the second samples after writing this bit. + * Active only during device exit from power-down mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fastsettl_mode_xl in + * reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_fast_settling_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fastsettl_mode_xl = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables accelerometer LPF2 and HPF fast-settling mode. + * The filter sets the second samples after writing this bit. + * Active only during device exit from power-down mode.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fastsettl_mode_xl in reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_fast_settling_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + *val = reg.fastsettl_mode_xl; + + return ret; +} + +/** + * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity + * functions.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of slope_fds in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_hp_path_internal_set(stmdev_ctx_t *ctx, + lsm6dso_slope_fds_t val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.slope_fds = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity + * functions.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of slope_fds in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_hp_path_internal_get(stmdev_ctx_t *ctx, + lsm6dso_slope_fds_t *val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + switch (reg.slope_fds) + { + case LSM6DSO_USE_SLOPE: + *val = LSM6DSO_USE_SLOPE; + break; + + case LSM6DSO_USE_HPF: + *val = LSM6DSO_USE_HPF; + break; + + default: + *val = LSM6DSO_USE_SLOPE; + break; + } + + return ret; +} + +/** + * @brief Enables gyroscope digital high-pass filter. The filter is + * enabled only if the gyro is in HP mode.[set] + * + * @param ctx read / write interface definitions + * @param val Get the values of hp_en_g and hp_en_g + * in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_hp_path_internal_set(stmdev_ctx_t *ctx, + lsm6dso_hpm_g_t val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.hp_en_g = ((uint8_t)val & 0x80U) >> 7; + reg.hpm_g = (uint8_t)val & 0x03U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables gyroscope digital high-pass filter. The filter is + * enabled only if the gyro is in HP mode.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of hp_en_g and hp_en_g + * in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_hp_path_internal_get(stmdev_ctx_t *ctx, + lsm6dso_hpm_g_t *val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + switch ((reg.hp_en_g << 7) + reg.hpm_g) + { + case LSM6DSO_HP_FILTER_NONE: + *val = LSM6DSO_HP_FILTER_NONE; + break; + + case LSM6DSO_HP_FILTER_16mHz: + *val = LSM6DSO_HP_FILTER_16mHz; + break; + + case LSM6DSO_HP_FILTER_65mHz: + *val = LSM6DSO_HP_FILTER_65mHz; + break; + + case LSM6DSO_HP_FILTER_260mHz: + *val = LSM6DSO_HP_FILTER_260mHz; + break; + + case LSM6DSO_HP_FILTER_1Hz04: + *val = LSM6DSO_HP_FILTER_1Hz04; + break; + + default: + *val = LSM6DSO_HP_FILTER_NONE; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_ Auxiliary_interface + * @brief This section groups all the functions concerning + * auxiliary interface. + * @{ + * + */ + +/** + * @brief aOn auxiliary interface connect/disconnect SDO and OCS + * internal pull-up.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ois_pu_dis in + * reg PIN_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_sdo_ocs_mode_set(stmdev_ctx_t *ctx, + lsm6dso_ois_pu_dis_t val) +{ + lsm6dso_pin_ctrl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.ois_pu_dis = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief On auxiliary interface connect/disconnect SDO and OCS + * internal pull-up.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of ois_pu_dis in reg PIN_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_sdo_ocs_mode_get(stmdev_ctx_t *ctx, + lsm6dso_ois_pu_dis_t *val) +{ + lsm6dso_pin_ctrl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)®, 1); + + switch (reg.ois_pu_dis) + { + case LSM6DSO_AUX_PULL_UP_DISC: + *val = LSM6DSO_AUX_PULL_UP_DISC; + break; + + case LSM6DSO_AUX_PULL_UP_CONNECT: + *val = LSM6DSO_AUX_PULL_UP_CONNECT; + break; + + default: + *val = LSM6DSO_AUX_PULL_UP_DISC; + break; + } + + return ret; +} + +/** + * @brief OIS chain on aux interface power on mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ois_on in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_pw_on_ctrl_set(stmdev_ctx_t *ctx, + lsm6dso_ois_on_t val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.ois_on_en = (uint8_t)val & 0x01U; + reg.ois_on = (uint8_t)val & 0x01U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief aux_pw_on_ctrl: [get] OIS chain on aux interface power on mode + * + * @param ctx read / write interface definitions + * @param val Get the values of ois_on in reg CTRL7_G + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_pw_on_ctrl_get(stmdev_ctx_t *ctx, + lsm6dso_ois_on_t *val) +{ + lsm6dso_ctrl7_g_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL7_G, (uint8_t *)®, 1); + + switch (reg.ois_on) + { + case LSM6DSO_AUX_ON: + *val = LSM6DSO_AUX_ON; + break; + + case LSM6DSO_AUX_ON_BY_AUX_INTERFACE: + *val = LSM6DSO_AUX_ON_BY_AUX_INTERFACE; + break; + + default: + *val = LSM6DSO_AUX_ON; + break; + } + + return ret; +} + +/** + * @brief Accelerometer full-scale management between UI chain and + * OIS chain. When XL UI is on, the full scale is the same + * between UI/OIS and is chosen by the UI CTRL registers; + * when XL UI is in PD, the OIS can choose the FS. + * Full scales are independent between the UI/OIS chain + * but both bound to 8 g.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of xl_fs_mode in + * reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_fs_mode_set(stmdev_ctx_t *ctx, + lsm6dso_xl_fs_mode_t val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.xl_fs_mode = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer full-scale management between UI chain and + * OIS chain. When XL UI is on, the full scale is the same + * between UI/OIS and is chosen by the UI CTRL registers; + * when XL UI is in PD, the OIS can choose the FS. + * Full scales are independent between the UI/OIS chain + * but both bound to 8 g.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of xl_fs_mode in reg CTRL8_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_fs_mode_get(stmdev_ctx_t *ctx, + lsm6dso_xl_fs_mode_t *val) +{ + lsm6dso_ctrl8_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL8_XL, (uint8_t *)®, 1); + + switch (reg.xl_fs_mode) + { + case LSM6DSO_USE_SAME_XL_FS: + *val = LSM6DSO_USE_SAME_XL_FS; + break; + + case LSM6DSO_USE_DIFFERENT_XL_FS: + *val = LSM6DSO_USE_DIFFERENT_XL_FS; + break; + + default: + *val = LSM6DSO_USE_SAME_XL_FS; + break; + } + + return ret; +} + +/** + * @brief The STATUS_SPIAux register is read by the auxiliary SPI.[get] + * + * @param ctx read / write interface definitions + * @param lsm6dso_status_spiaux_t: registers STATUS_SPIAUX + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_status_reg_get(stmdev_ctx_t *ctx, + lsm6dso_status_spiaux_t *val) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief aux_xl_flag_data_ready: [get] AUX accelerometer data available + * + * @param ctx read / write interface definitions + * @param val change the values of xlda in reg STATUS_SPIAUX + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_status_spiaux_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t *)®, 1); + *val = reg.xlda; + + return ret; +} + +/** + * @brief aux_gy_flag_data_ready: [get] AUX gyroscope data available. + * + * @param ctx read / write interface definitions + * @param val change the values of gda in reg STATUS_SPIAUX + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_status_spiaux_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t *)®, 1); + *val = reg.gda; + + return ret; +} + +/** + * @brief High when the gyroscope output is in the settling phase.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of gyro_settling in reg STATUS_SPIAUX + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_flag_settling_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_status_spiaux_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_SPIAUX, (uint8_t *)®, 1); + *val = reg.gyro_settling; + + return ret; +} + +/** + * @brief Selects accelerometer self-test. Effective only if XL OIS + * chain is enabled.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of st_xl_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_xl_ois_t val) +{ + lsm6dso_int_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.st_xl_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects accelerometer self-test. Effective only if XL OIS + * chain is enabled.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of st_xl_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_xl_ois_t *val) +{ + lsm6dso_int_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + + switch (reg.st_xl_ois) + { + case LSM6DSO_AUX_XL_DISABLE: + *val = LSM6DSO_AUX_XL_DISABLE; + break; + + case LSM6DSO_AUX_XL_POS: + *val = LSM6DSO_AUX_XL_POS; + break; + + case LSM6DSO_AUX_XL_NEG: + *val = LSM6DSO_AUX_XL_NEG; + break; + + default: + *val = LSM6DSO_AUX_XL_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Indicates polarity of DEN signal on OIS chain.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_lh_ois in + * reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_den_polarity_set(stmdev_ctx_t *ctx, + lsm6dso_den_lh_ois_t val) +{ + lsm6dso_int_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_lh_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Indicates polarity of DEN signal on OIS chain.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of den_lh_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_den_polarity_get(stmdev_ctx_t *ctx, + lsm6dso_den_lh_ois_t *val) +{ + lsm6dso_int_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + + switch (reg.den_lh_ois) + { + case LSM6DSO_AUX_DEN_ACTIVE_LOW: + *val = LSM6DSO_AUX_DEN_ACTIVE_LOW; + break; + + case LSM6DSO_AUX_DEN_ACTIVE_HIGH: + *val = LSM6DSO_AUX_DEN_ACTIVE_HIGH; + break; + + default: + *val = LSM6DSO_AUX_DEN_ACTIVE_LOW; + break; + } + + return ret; +} + +/** + * @brief Configure DEN mode on the OIS chain.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of lvl2_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_den_mode_set(stmdev_ctx_t *ctx, + lsm6dso_lvl2_ois_t val) +{ + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_int_ois_t int_ois; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *) &int_ois, 1); + + if (ret == 0) + { + int_ois.lvl2_ois = (uint8_t)val & 0x01U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *) &int_ois, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *) &ctrl1_ois, 1); + } + + if (ret == 0) + { + ctrl1_ois.lvl1_ois = ((uint8_t)val & 0x02U) >> 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, + (uint8_t *) &ctrl1_ois, 1); + } + + return ret; +} + +/** + * @brief Configure DEN mode on the OIS chain.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of lvl2_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_den_mode_get(stmdev_ctx_t *ctx, + lsm6dso_lvl2_ois_t *val) +{ + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_int_ois_t int_ois; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *) &int_ois, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *) &ctrl1_ois, 1); + + switch ((ctrl1_ois.lvl1_ois << 1) + int_ois.lvl2_ois) + { + case LSM6DSO_AUX_DEN_DISABLE: + *val = LSM6DSO_AUX_DEN_DISABLE; + break; + + case LSM6DSO_AUX_DEN_LEVEL_LATCH: + *val = LSM6DSO_AUX_DEN_LEVEL_LATCH; + break; + + case LSM6DSO_AUX_DEN_LEVEL_TRIG: + *val = LSM6DSO_AUX_DEN_LEVEL_TRIG; + break; + + default: + *val = LSM6DSO_AUX_DEN_DISABLE; + break; + } + } + + return ret; +} + +/** + * @brief Enables/Disable OIS chain DRDY on INT2 pin. + * This setting has priority over all other INT2 settings.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of int2_drdy_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_drdy_on_int2_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_int_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.int2_drdy_ois = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables/Disable OIS chain DRDY on INT2 pin. + * This setting has priority over all other INT2 settings.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of int2_drdy_ois in reg INT_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_drdy_on_int2_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_int_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_OIS, (uint8_t *)®, 1); + *val = reg.int2_drdy_ois; + + return ret; +} + +/** + * @brief Enables OIS chain data processing for gyro in Mode 3 and Mode 4 + * (mode4_en = 1) and accelerometer data in and Mode 4 (mode4_en = 1). + * When the OIS chain is enabled, the OIS outputs are available + * through the SPI2 in registers OUTX_L_G (22h) through + * OUTZ_H_G (27h) and STATUS_REG (1Eh) / STATUS_SPIAux, and + * LPF1 is dedicated to this chain.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ois_en_spi2 in + * reg CTRL1_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_mode_set(stmdev_ctx_t *ctx, + lsm6dso_ois_en_spi2_t val) +{ + lsm6dso_ctrl1_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.ois_en_spi2 = (uint8_t)val & 0x01U; + reg.mode4_en = ((uint8_t)val & 0x02U) >> 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables OIS chain data processing for gyro in Mode 3 and Mode 4 + * (mode4_en = 1) and accelerometer data in and Mode 4 (mode4_en = 1). + * When the OIS chain is enabled, the OIS outputs are available + * through the SPI2 in registers OUTX_L_G (22h) through + * OUTZ_H_G (27h) and STATUS_REG (1Eh) / STATUS_SPIAux, and + * LPF1 is dedicated to this chain.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of ois_en_spi2 in + * reg CTRL1_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_mode_get(stmdev_ctx_t *ctx, + lsm6dso_ois_en_spi2_t *val) +{ + lsm6dso_ctrl1_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + + switch ((reg.mode4_en << 1) | reg.ois_en_spi2) + { + case LSM6DSO_AUX_DISABLE: + *val = LSM6DSO_AUX_DISABLE; + break; + + case LSM6DSO_MODE_3_GY: + *val = LSM6DSO_MODE_3_GY; + break; + + case LSM6DSO_MODE_4_GY_XL: + *val = LSM6DSO_MODE_4_GY_XL; + break; + + default: + *val = LSM6DSO_AUX_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Selects gyroscope OIS chain full-scale.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fs_g_ois in reg CTRL1_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_g_ois_t val) +{ + lsm6dso_ctrl1_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fs_g_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects gyroscope OIS chain full-scale.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fs_g_ois in reg CTRL1_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_g_ois_t *val) +{ + lsm6dso_ctrl1_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + + switch (reg.fs_g_ois) + { + case LSM6DSO_250dps_AUX: + *val = LSM6DSO_250dps_AUX; + break; + + case LSM6DSO_125dps_AUX: + *val = LSM6DSO_125dps_AUX; + break; + + case LSM6DSO_500dps_AUX: + *val = LSM6DSO_500dps_AUX; + break; + + case LSM6DSO_1000dps_AUX: + *val = LSM6DSO_1000dps_AUX; + break; + + case LSM6DSO_2000dps_AUX: + *val = LSM6DSO_2000dps_AUX; + break; + + default: + *val = LSM6DSO_250dps_AUX; + break; + } + + return ret; +} + +/** + * @brief SPI2 3- or 4-wire interface.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sim_ois in reg CTRL1_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_spi_mode_set(stmdev_ctx_t *ctx, + lsm6dso_sim_ois_t val) +{ + lsm6dso_ctrl1_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sim_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief SPI2 3- or 4-wire interface.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sim_ois in reg CTRL1_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_spi_mode_get(stmdev_ctx_t *ctx, + lsm6dso_sim_ois_t *val) +{ + lsm6dso_ctrl1_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, (uint8_t *)®, 1); + + switch (reg.sim_ois) + { + case LSM6DSO_AUX_SPI_4_WIRE: + *val = LSM6DSO_AUX_SPI_4_WIRE; + break; + + case LSM6DSO_AUX_SPI_3_WIRE: + *val = LSM6DSO_AUX_SPI_3_WIRE; + break; + + default: + *val = LSM6DSO_AUX_SPI_4_WIRE; + break; + } + + return ret; +} + +/** + * @brief Selects gyroscope digital LPF1 filter bandwidth.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ftype_ois in + * reg CTRL2_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_lp1_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_ftype_ois_t val) +{ + lsm6dso_ctrl2_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.ftype_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects gyroscope digital LPF1 filter bandwidth.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of ftype_ois in reg CTRL2_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_lp1_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_ftype_ois_t *val) +{ + lsm6dso_ctrl2_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t *)®, 1); + + switch (reg.ftype_ois) + { + case LSM6DSO_351Hz39: + *val = LSM6DSO_351Hz39; + break; + + case LSM6DSO_236Hz63: + *val = LSM6DSO_236Hz63; + break; + + case LSM6DSO_172Hz70: + *val = LSM6DSO_172Hz70; + break; + + case LSM6DSO_937Hz91: + *val = LSM6DSO_937Hz91; + break; + + default: + *val = LSM6DSO_351Hz39; + break; + } + + return ret; +} + +/** + * @brief Selects gyroscope OIS chain digital high-pass filter cutoff.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of hpm_ois in reg CTRL2_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_hp_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_hpm_ois_t val) +{ + lsm6dso_ctrl2_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.hpm_ois = (uint8_t)val & 0x03U; + reg.hp_en_ois = ((uint8_t)val & 0x10U) >> 4; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects gyroscope OIS chain digital high-pass filter cutoff.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of hpm_ois in reg CTRL2_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_hp_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_hpm_ois_t *val) +{ + lsm6dso_ctrl2_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL2_OIS, (uint8_t *)®, 1); + + switch ((reg.hp_en_ois << 4) | reg.hpm_ois) + { + case LSM6DSO_AUX_HP_DISABLE: + *val = LSM6DSO_AUX_HP_DISABLE; + break; + + case LSM6DSO_AUX_HP_Hz016: + *val = LSM6DSO_AUX_HP_Hz016; + break; + + case LSM6DSO_AUX_HP_Hz065: + *val = LSM6DSO_AUX_HP_Hz065; + break; + + case LSM6DSO_AUX_HP_Hz260: + *val = LSM6DSO_AUX_HP_Hz260; + break; + + case LSM6DSO_AUX_HP_1Hz040: + *val = LSM6DSO_AUX_HP_1Hz040; + break; + + default: + *val = LSM6DSO_AUX_HP_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Enable / Disables OIS chain clamp. + * Enable: All OIS chain outputs = 8000h + * during self-test; Disable: OIS chain self-test + * outputs dependent from the aux gyro full + * scale selected.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of st_ois_clampdis in + * reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_clamp_set(stmdev_ctx_t *ctx, + lsm6dso_st_ois_clampdis_t val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.st_ois_clampdis = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enable / Disables OIS chain clamp. + * Enable: All OIS chain outputs = 8000h + * during self-test; Disable: OIS chain self-test + * outputs dependent from the aux gyro full + * scale selected.[set] + * + * @param ctx read / write interface definitions + * @param val Get the values of st_ois_clampdis in + * reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_clamp_get(stmdev_ctx_t *ctx, + lsm6dso_st_ois_clampdis_t *val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + switch (reg.st_ois_clampdis) + { + case LSM6DSO_ENABLE_CLAMP: + *val = LSM6DSO_ENABLE_CLAMP; + break; + + case LSM6DSO_DISABLE_CLAMP: + *val = LSM6DSO_DISABLE_CLAMP; + break; + + default: + *val = LSM6DSO_ENABLE_CLAMP; + break; + } + + return ret; +} + +/** + * @brief Selects gyroscope OIS chain self-test.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of st_ois in reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_ois_t val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.st_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects gyroscope OIS chain self-test.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of st_ois in reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_gy_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_ois_t *val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + switch (reg.st_ois) + { + case LSM6DSO_AUX_GY_DISABLE: + *val = LSM6DSO_AUX_GY_DISABLE; + break; + + case LSM6DSO_AUX_GY_POS: + *val = LSM6DSO_AUX_GY_POS; + break; + + case LSM6DSO_AUX_GY_NEG: + *val = LSM6DSO_AUX_GY_NEG; + break; + + default: + *val = LSM6DSO_AUX_GY_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Selects accelerometer OIS channel bandwidth.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of + * filter_xl_conf_ois in reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_filter_xl_conf_ois_t val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.filter_xl_conf_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects accelerometer OIS channel bandwidth.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of + * filter_xl_conf_ois in reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_filter_xl_conf_ois_t *val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + switch (reg.filter_xl_conf_ois) + { + case LSM6DSO_289Hz: + *val = LSM6DSO_289Hz; + break; + + case LSM6DSO_258Hz: + *val = LSM6DSO_258Hz; + break; + + case LSM6DSO_120Hz: + *val = LSM6DSO_120Hz; + break; + + case LSM6DSO_65Hz2: + *val = LSM6DSO_65Hz2; + break; + + case LSM6DSO_33Hz2: + *val = LSM6DSO_33Hz2; + break; + + case LSM6DSO_16Hz6: + *val = LSM6DSO_16Hz6; + break; + + case LSM6DSO_8Hz30: + *val = LSM6DSO_8Hz30; + break; + + case LSM6DSO_4Hz15: + *val = LSM6DSO_4Hz15; + break; + + default: + *val = LSM6DSO_289Hz; + break; + } + + return ret; +} + +/** + * @brief Selects accelerometer OIS channel full-scale.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fs_xl_ois in + * reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_ois_t val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fs_xl_ois = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects accelerometer OIS channel full-scale.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fs_xl_ois in reg CTRL3_OIS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_aux_xl_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_ois_t *val) +{ + lsm6dso_ctrl3_ois_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_OIS, (uint8_t *)®, 1); + + switch (reg.fs_xl_ois) + { + case LSM6DSO_AUX_2g: + *val = LSM6DSO_AUX_2g; + break; + + case LSM6DSO_AUX_16g: + *val = LSM6DSO_AUX_16g; + break; + + case LSM6DSO_AUX_4g: + *val = LSM6DSO_AUX_4g; + break; + + case LSM6DSO_AUX_8g: + *val = LSM6DSO_AUX_8g; + break; + + default: + *val = LSM6DSO_AUX_2g; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_ main_serial_interface + * @brief This section groups all the functions concerning main + * serial interface management (not auxiliary) + * @{ + * + */ + +/** + * @brief Connect/Disconnect SDO/SA0 internal pull-up.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sdo_pu_en in + * reg PIN_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sdo_sa0_mode_set(stmdev_ctx_t *ctx, + lsm6dso_sdo_pu_en_t val) +{ + lsm6dso_pin_ctrl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sdo_pu_en = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Connect/Disconnect SDO/SA0 internal pull-up.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sdo_pu_en in reg PIN_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sdo_sa0_mode_get(stmdev_ctx_t *ctx, + lsm6dso_sdo_pu_en_t *val) +{ + lsm6dso_pin_ctrl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)®, 1); + + switch (reg.sdo_pu_en) + { + case LSM6DSO_PULL_UP_DISC: + *val = LSM6DSO_PULL_UP_DISC; + break; + + case LSM6DSO_PULL_UP_CONNECT: + *val = LSM6DSO_PULL_UP_CONNECT; + break; + + default: + *val = LSM6DSO_PULL_UP_DISC; + break; + } + + return ret; +} + +/** + * @brief SPI Serial Interface Mode selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sim in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_spi_mode_set(stmdev_ctx_t *ctx, lsm6dso_sim_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sim = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief SPI Serial Interface Mode selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sim in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_spi_mode_get(stmdev_ctx_t *ctx, lsm6dso_sim_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + switch (reg.sim) + { + case LSM6DSO_SPI_4_WIRE: + *val = LSM6DSO_SPI_4_WIRE; + break; + + case LSM6DSO_SPI_3_WIRE: + *val = LSM6DSO_SPI_3_WIRE; + break; + + default: + *val = LSM6DSO_SPI_4_WIRE; + break; + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of i2c_disable in + * reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_i2c_interface_set(stmdev_ctx_t *ctx, + lsm6dso_i2c_disable_t val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.i2c_disable = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of i2c_disable in + * reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_i2c_interface_get(stmdev_ctx_t *ctx, + lsm6dso_i2c_disable_t *val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + + switch (reg.i2c_disable) + { + case LSM6DSO_I2C_ENABLE: + *val = LSM6DSO_I2C_ENABLE; + break; + + case LSM6DSO_I2C_DISABLE: + *val = LSM6DSO_I2C_DISABLE; + break; + + default: + *val = LSM6DSO_I2C_ENABLE; + break; + } + + return ret; +} + +/** + * @brief I3C Enable/Disable communication protocol[.set] + * + * @param ctx read / write interface definitions + * @param val change the values of i3c_disable + * in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_i3c_disable_set(stmdev_ctx_t *ctx, + lsm6dso_i3c_disable_t val) +{ + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + lsm6dso_ctrl9_xl_t ctrl9_xl; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ctrl9_xl.i3c_disable = ((uint8_t)val & 0x80U) >> 7; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)&ctrl9_xl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + if (ret == 0) + { + i3c_bus_avb.i3c_bus_avb_sel = (uint8_t)val & 0x03U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + return ret; +} + +/** + * @brief I3C Enable/Disable communication protocol.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of i3c_disable in + * reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_i3c_disable_get(stmdev_ctx_t *ctx, + lsm6dso_i3c_disable_t *val) +{ + lsm6dso_ctrl9_xl_t ctrl9_xl; + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)&ctrl9_xl, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + + switch ((ctrl9_xl.i3c_disable << 7) | i3c_bus_avb.i3c_bus_avb_sel) + { + case LSM6DSO_I3C_DISABLE: + *val = LSM6DSO_I3C_DISABLE; + break; + + case LSM6DSO_I3C_ENABLE_T_50us: + *val = LSM6DSO_I3C_ENABLE_T_50us; + break; + + case LSM6DSO_I3C_ENABLE_T_2us: + *val = LSM6DSO_I3C_ENABLE_T_2us; + break; + + case LSM6DSO_I3C_ENABLE_T_1ms: + *val = LSM6DSO_I3C_ENABLE_T_1ms; + break; + + case LSM6DSO_I3C_ENABLE_T_25ms: + *val = LSM6DSO_I3C_ENABLE_T_25ms; + break; + + default: + *val = LSM6DSO_I3C_DISABLE; + break; + } + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_interrupt_pins + * @brief This section groups all the functions that manage interrupt pins + * @{ + * + */ + +/** + * @brief Connect/Disconnect INT1 internal pull-down.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of pd_dis_int1 in reg I3C_BUS_AVB + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_int1_mode_set(stmdev_ctx_t *ctx, + lsm6dso_int1_pd_en_t val) +{ + lsm6dso_i3c_bus_avb_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.pd_dis_int1 = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_I3C_BUS_AVB, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Connect/Disconnect INT1 internal pull-down.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of pd_dis_int1 in reg I3C_BUS_AVB + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_int1_mode_get(stmdev_ctx_t *ctx, + lsm6dso_int1_pd_en_t *val) +{ + lsm6dso_i3c_bus_avb_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, (uint8_t *)®, 1); + + switch (reg.pd_dis_int1) + { + case LSM6DSO_PULL_DOWN_DISC: + *val = LSM6DSO_PULL_DOWN_DISC; + break; + + case LSM6DSO_PULL_DOWN_CONNECT: + *val = LSM6DSO_PULL_DOWN_CONNECT; + break; + + default: + *val = LSM6DSO_PULL_DOWN_DISC; + break; + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of pp_od in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_mode_set(stmdev_ctx_t *ctx, lsm6dso_pp_od_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.pp_od = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of pp_od in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_mode_get(stmdev_ctx_t *ctx, lsm6dso_pp_od_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + switch (reg.pp_od) + { + case LSM6DSO_PUSH_PULL: + *val = LSM6DSO_PUSH_PULL; + break; + + case LSM6DSO_OPEN_DRAIN: + *val = LSM6DSO_OPEN_DRAIN; + break; + + default: + *val = LSM6DSO_PUSH_PULL; + break; + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of h_lactive in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_polarity_set(stmdev_ctx_t *ctx, + lsm6dso_h_lactive_t val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.h_lactive = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of h_lactive in reg CTRL3_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_polarity_get(stmdev_ctx_t *ctx, + lsm6dso_h_lactive_t *val) +{ + lsm6dso_ctrl3_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)®, 1); + + switch (reg.h_lactive) + { + case LSM6DSO_ACTIVE_HIGH: + *val = LSM6DSO_ACTIVE_HIGH; + break; + + case LSM6DSO_ACTIVE_LOW: + *val = LSM6DSO_ACTIVE_LOW; + break; + + default: + *val = LSM6DSO_ACTIVE_HIGH; + break; + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of int2_on_int1 in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_all_on_int1_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.int2_on_int1 = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of int2_on_int1 in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_all_on_int1_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + *val = reg.int2_on_int1; + + return ret; +} + +/** + * @brief Interrupt notification mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of lir in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_int_notification_set(stmdev_ctx_t *ctx, + lsm6dso_lir_t val) +{ + lsm6dso_tap_cfg0_t tap_cfg0; + lsm6dso_page_rw_t page_rw; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *) &tap_cfg0, 1); + + if (ret == 0) + { + tap_cfg0.lir = (uint8_t)val & 0x01U; + tap_cfg0.int_clr_on_read = (uint8_t)val & 0x01U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *) &tap_cfg0, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.emb_func_lir = ((uint8_t)val & 0x02U) >> 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Interrupt notification mode.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of lir in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_int_notification_get(stmdev_ctx_t *ctx, + lsm6dso_lir_t *val) +{ + lsm6dso_tap_cfg0_t tap_cfg0; + lsm6dso_page_rw_t page_rw; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *) &tap_cfg0, 1); + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + if (ret == 0) + { + switch ((page_rw.emb_func_lir << 1) | tap_cfg0.lir) + { + case LSM6DSO_ALL_INT_PULSED: + *val = LSM6DSO_ALL_INT_PULSED; + break; + + case LSM6DSO_BASE_LATCHED_EMB_PULSED: + *val = LSM6DSO_BASE_LATCHED_EMB_PULSED; + break; + + case LSM6DSO_BASE_PULSED_EMB_LATCHED: + *val = LSM6DSO_BASE_PULSED_EMB_LATCHED; + break; + + case LSM6DSO_ALL_INT_LATCHED: + *val = LSM6DSO_ALL_INT_LATCHED; + break; + + default: + *val = LSM6DSO_ALL_INT_PULSED; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_Wake_Up_event + * @brief This section groups all the functions that manage the Wake Up + * event generation. + * @{ + * + */ + +/** + * @brief Weight of 1 LSB of wakeup threshold.[set] + * 0: 1 LSB =FS_XL / 64 + * 1: 1 LSB = FS_XL / 256 + * + * @param ctx read / write interface definitions + * @param val change the values of wake_ths_w in + * reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_wkup_ths_weight_set(stmdev_ctx_t *ctx, + lsm6dso_wake_ths_w_t val) +{ + lsm6dso_wake_up_dur_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.wake_ths_w = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Weight of 1 LSB of wakeup threshold.[get] + * 0: 1 LSB =FS_XL / 64 + * 1: 1 LSB = FS_XL / 256 + * + * @param ctx read / write interface definitions + * @param val Get the values of wake_ths_w in + * reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_wkup_ths_weight_get(stmdev_ctx_t *ctx, + lsm6dso_wake_ths_w_t *val) +{ + lsm6dso_wake_up_dur_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + + switch (reg.wake_ths_w) + { + case LSM6DSO_LSb_FS_DIV_64: + *val = LSM6DSO_LSb_FS_DIV_64; + break; + + case LSM6DSO_LSb_FS_DIV_256: + *val = LSM6DSO_LSb_FS_DIV_256; + break; + + default: + *val = LSM6DSO_LSb_FS_DIV_64; + break; + } + + return ret; +} + +/** + * @brief Threshold for wakeup: 1 LSB weight depends on WAKE_THS_W in + * WAKE_UP_DUR.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of wk_ths in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_wkup_threshold_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_wake_up_ths_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.wk_ths = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Threshold for wakeup: 1 LSB weight depends on WAKE_THS_W in + * WAKE_UP_DUR.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of wk_ths in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_wkup_threshold_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_wake_up_ths_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + *val = reg.wk_ths; + + return ret; +} + +/** + * @brief Wake up duration event.[set] + * 1LSb = 1 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of usr_off_on_wu in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_on_wkup_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6dso_wake_up_ths_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.usr_off_on_wu = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Wake up duration event.[get] + * 1LSb = 1 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of usr_off_on_wu in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_xl_usr_offset_on_wkup_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_wake_up_ths_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + *val = reg.usr_off_on_wu; + + return ret; +} + +/** + * @brief Wake up duration event.[set] + * 1LSb = 1 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of wake_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_wkup_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_wake_up_dur_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.wake_dur = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Wake up duration event.[get] + * 1LSb = 1 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of wake_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_wkup_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_wake_up_dur_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + *val = reg.wake_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_ Activity/Inactivity_detection + * @brief This section groups all the functions concerning + * activity/inactivity detection. + * @{ + * + */ + +/** + * @brief Enables gyroscope Sleep mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_g in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_sleep_mode_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sleep_g = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables gyroscope Sleep mode.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_g in reg CTRL4_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_gy_sleep_mode_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl4_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)®, 1); + *val = reg.sleep_g; + + return ret; +} + +/** + * @brief Drives the sleep status instead of + * sleep change on INT pins + * (only if INT1_SLEEP_CHANGE or + * INT2_SLEEP_CHANGE bits are enabled).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_status_on_int in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_act_pin_notification_set(stmdev_ctx_t *ctx, + lsm6dso_sleep_status_on_int_t val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sleep_status_on_int = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Drives the sleep status instead of + * sleep change on INT pins (only if + * INT1_SLEEP_CHANGE or + * INT2_SLEEP_CHANGE bits are enabled).[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sleep_status_on_int in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_act_pin_notification_get(stmdev_ctx_t *ctx, + lsm6dso_sleep_status_on_int_t *val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + switch (reg.sleep_status_on_int) + { + case LSM6DSO_DRIVE_SLEEP_CHG_EVENT: + *val = LSM6DSO_DRIVE_SLEEP_CHG_EVENT; + break; + + case LSM6DSO_DRIVE_SLEEP_STATUS: + *val = LSM6DSO_DRIVE_SLEEP_STATUS; + break; + + default: + *val = LSM6DSO_DRIVE_SLEEP_CHG_EVENT; + break; + } + + return ret; +} + +/** + * @brief Enable inactivity function.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of inact_en in reg TAP_CFG2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_act_mode_set(stmdev_ctx_t *ctx, + lsm6dso_inact_en_t val) +{ + lsm6dso_tap_cfg2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.inact_en = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enable inactivity function.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of inact_en in reg TAP_CFG2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_act_mode_get(stmdev_ctx_t *ctx, + lsm6dso_inact_en_t *val) +{ + lsm6dso_tap_cfg2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *)®, 1); + + switch (reg.inact_en) + { + case LSM6DSO_XL_AND_GY_NOT_AFFECTED: + *val = LSM6DSO_XL_AND_GY_NOT_AFFECTED; + break; + + case LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED: + *val = LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED; + break; + + case LSM6DSO_XL_12Hz5_GY_SLEEP: + *val = LSM6DSO_XL_12Hz5_GY_SLEEP; + break; + + case LSM6DSO_XL_12Hz5_GY_PD: + *val = LSM6DSO_XL_12Hz5_GY_PD; + break; + + default: + *val = LSM6DSO_XL_AND_GY_NOT_AFFECTED; + break; + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode.[set] + * 1 LSb = 512 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_act_sleep_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_wake_up_dur_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sleep_dur = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode.[get] + * 1 LSb = 512 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_act_sleep_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_wake_up_dur_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, (uint8_t *)®, 1); + *val = reg.sleep_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_tap_generator + * @brief This section groups all the functions that manage the + * tap and double tap event generation. + * @{ + * + */ + +/** + * @brief Enable Z direction in tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_z_en in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_detection_on_z_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_z_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_z_en in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_detection_on_z_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + *val = reg.tap_z_en; + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_y_en in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_detection_on_y_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_y_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_y_en in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_detection_on_y_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + *val = reg.tap_y_en; + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_x_en in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_detection_on_x_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_x_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_x_en in reg TAP_CFG0 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_detection_on_x_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_tap_cfg0_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *)®, 1); + *val = reg.tap_x_en; + + return ret; +} + +/** + * @brief X-axis tap recognition threshold.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_ths_x in reg TAP_CFG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_threshold_x_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_cfg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_ths_x = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief X-axis tap recognition threshold.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_ths_x in reg TAP_CFG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_threshold_x_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_tap_cfg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t *)®, 1); + *val = reg.tap_ths_x; + + return ret; +} + +/** + * @brief Selection of axis priority for TAP detection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_priority in + * reg TAP_CFG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_axis_priority_set(stmdev_ctx_t *ctx, + lsm6dso_tap_priority_t val) +{ + lsm6dso_tap_cfg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_priority = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selection of axis priority for TAP detection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of tap_priority in + * reg TAP_CFG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_axis_priority_get(stmdev_ctx_t *ctx, + lsm6dso_tap_priority_t *val) +{ + lsm6dso_tap_cfg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG1, (uint8_t *)®, 1); + + switch (reg.tap_priority) + { + case LSM6DSO_XYZ: + *val = LSM6DSO_XYZ; + break; + + case LSM6DSO_YXZ: + *val = LSM6DSO_YXZ; + break; + + case LSM6DSO_XZY: + *val = LSM6DSO_XZY; + break; + + case LSM6DSO_ZYX: + *val = LSM6DSO_ZYX; + break; + + case LSM6DSO_YZX: + *val = LSM6DSO_YZX; + break; + + case LSM6DSO_ZXY: + *val = LSM6DSO_ZXY; + break; + + default: + *val = LSM6DSO_XYZ; + break; + } + + return ret; +} + +/** + * @brief Y-axis tap recognition threshold.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_ths_y in reg TAP_CFG2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_threshold_y_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_cfg2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_ths_y = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Y-axis tap recognition threshold.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_ths_y in reg TAP_CFG2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_threshold_y_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_tap_cfg2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *)®, 1); + *val = reg.tap_ths_y; + + return ret; +} + +/** + * @brief Z-axis recognition threshold.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_ths_z in reg TAP_THS_6D + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_threshold_z_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_ths_6d_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.tap_ths_z = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Z-axis recognition threshold.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_ths_z in reg TAP_THS_6D + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_threshold_z_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_tap_ths_6d_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + *val = reg.tap_ths_z; + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an + * over threshold signal detection to be recognized + * as a tap event. The default value of these bits + * is 00b which corresponds to 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different + * value, 1LSB corresponds to 8*ODR_XL time.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of shock in reg INT_DUR2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_shock_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_int_dur2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.shock = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an + * over threshold signal detection to be recognized + * as a tap event. The default value of these bits + * is 00b which corresponds to 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different + * value, 1LSB corresponds to 8*ODR_XL time.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of shock in reg INT_DUR2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_shock_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_int_dur2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + *val = reg.shock; + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected + * tap in which there must not be any over threshold + * event. + * The default value of these bits is 00b which + * corresponds to 2*ODR_XL time. If the QUIET[1:0] + * bits are set to a different value, + * 1LSB corresponds to 4*ODR_XL time.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of quiet in reg INT_DUR2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_quiet_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_int_dur2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.quiet = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected + * tap in which there must not be any over threshold + * event. + * The default value of these bits is 00b which + * corresponds to 2*ODR_XL time. + * If the QUIET[1:0] bits are set to a different + * value, 1LSB corresponds to 4*ODR_XL time.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of quiet in reg INT_DUR2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_quiet_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_int_dur2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + *val = reg.quiet; + + return ret; +} + +/** + * @brief When double tap recognition is enabled, + * this register expresses the maximum time + * between two consecutive detected taps to + * determine a double tap event. + * The default value of these bits is 0000b which + * corresponds to 16*ODR_XL time. + * If the DUR[3:0] bits are set to a different value, + * 1LSB corresponds to 32*ODR_XL time.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of dur in reg INT_DUR2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_int_dur2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.dur = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief When double tap recognition is enabled, + * this register expresses the maximum time + * between two consecutive detected taps to + * determine a double tap event. + * The default value of these bits is 0000b which + * corresponds to 16*ODR_XL time. If the DUR[3:0] + * bits are set to a different value, + * 1LSB corresponds to 32*ODR_XL time.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of dur in reg INT_DUR2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_int_dur2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT_DUR2, (uint8_t *)®, 1); + *val = reg.dur; + + return ret; +} + +/** + * @brief Single/double-tap event enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of single_double_tap in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_mode_set(stmdev_ctx_t *ctx, + lsm6dso_single_double_tap_t val) +{ + lsm6dso_wake_up_ths_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.single_double_tap = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Single/double-tap event enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of single_double_tap in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tap_mode_get(stmdev_ctx_t *ctx, + lsm6dso_single_double_tap_t *val) +{ + lsm6dso_wake_up_ths_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_THS, (uint8_t *)®, 1); + + switch (reg.single_double_tap) + { + case LSM6DSO_ONLY_SINGLE: + *val = LSM6DSO_ONLY_SINGLE; + break; + + case LSM6DSO_BOTH_SINGLE_DOUBLE: + *val = LSM6DSO_BOTH_SINGLE_DOUBLE; + break; + + default: + *val = LSM6DSO_ONLY_SINGLE; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_ Six_position_detection(6D/4D) + * @brief This section groups all the functions concerning six position + * detection (6D). + * @{ + * + */ + +/** + * @brief Threshold for 4D/6D function.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sixd_ths in reg TAP_THS_6D + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_6d_threshold_set(stmdev_ctx_t *ctx, + lsm6dso_sixd_ths_t val) +{ + lsm6dso_tap_ths_6d_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.sixd_ths = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Threshold for 4D/6D function.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sixd_ths in reg TAP_THS_6D + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_6d_threshold_get(stmdev_ctx_t *ctx, + lsm6dso_sixd_ths_t *val) +{ + lsm6dso_tap_ths_6d_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + + switch (reg.sixd_ths) + { + case LSM6DSO_DEG_80: + *val = LSM6DSO_DEG_80; + break; + + case LSM6DSO_DEG_70: + *val = LSM6DSO_DEG_70; + break; + + case LSM6DSO_DEG_60: + *val = LSM6DSO_DEG_60; + break; + + case LSM6DSO_DEG_50: + *val = LSM6DSO_DEG_50; + break; + + default: + *val = LSM6DSO_DEG_80; + break; + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of d4d_en in reg TAP_THS_6D + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_4d_mode_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_tap_ths_6d_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.d4d_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of d4d_en in reg TAP_THS_6D + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_4d_mode_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_tap_ths_6d_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_THS_6D, (uint8_t *)®, 1); + *val = reg.d4d_en; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_free_fall + * @brief This section group all the functions concerning the free + * fall detection. + * @{ + * + */ +/** + * @brief Free fall threshold setting.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ff_ths in reg FREE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ff_threshold_set(stmdev_ctx_t *ctx, + lsm6dso_ff_ths_t val) +{ + lsm6dso_free_fall_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.ff_ths = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Free fall threshold setting.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of ff_ths in reg FREE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ff_threshold_get(stmdev_ctx_t *ctx, + lsm6dso_ff_ths_t *val) +{ + lsm6dso_free_fall_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t *)®, 1); + + switch (reg.ff_ths) + { + case LSM6DSO_FF_TSH_156mg: + *val = LSM6DSO_FF_TSH_156mg; + break; + + case LSM6DSO_FF_TSH_219mg: + *val = LSM6DSO_FF_TSH_219mg; + break; + + case LSM6DSO_FF_TSH_250mg: + *val = LSM6DSO_FF_TSH_250mg; + break; + + case LSM6DSO_FF_TSH_312mg: + *val = LSM6DSO_FF_TSH_312mg; + break; + + case LSM6DSO_FF_TSH_344mg: + *val = LSM6DSO_FF_TSH_344mg; + break; + + case LSM6DSO_FF_TSH_406mg: + *val = LSM6DSO_FF_TSH_406mg; + break; + + case LSM6DSO_FF_TSH_469mg: + *val = LSM6DSO_FF_TSH_469mg; + break; + + case LSM6DSO_FF_TSH_500mg: + *val = LSM6DSO_FF_TSH_500mg; + break; + + default: + *val = LSM6DSO_FF_TSH_156mg; + break; + } + + return ret; +} + +/** + * @brief Free-fall duration event.[set] + * 1LSb = 1 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of ff_dur in reg FREE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ff_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_wake_up_dur_t wake_up_dur; + lsm6dso_free_fall_t free_fall; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t *)&free_fall, 1); + } + + if (ret == 0) + { + wake_up_dur.ff_dur = ((uint8_t)val & 0x20U) >> 5; + free_fall.ff_dur = (uint8_t)val & 0x1FU; + ret = lsm6dso_write_reg(ctx, LSM6DSO_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t *)&free_fall, 1); + } + + return ret; +} + +/** + * @brief Free-fall duration event.[get] + * 1LSb = 1 / ODR + * + * @param ctx read / write interface definitions + * @param val change the values of ff_dur in reg FREE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_ff_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_wake_up_dur_t wake_up_dur; + lsm6dso_free_fall_t free_fall; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_WAKE_UP_DUR, + (uint8_t *)&wake_up_dur, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FREE_FALL, (uint8_t *)&free_fall, 1); + *val = (wake_up_dur.ff_dur << 5) + free_fall.ff_dur; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_fifo + * @brief This section group all the functions concerning the fifo usage + * @{ + * + */ + +/** + * @brief FIFO watermark level selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of wtm in reg FIFO_CTRL1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_watermark_set(stmdev_ctx_t *ctx, uint16_t val) +{ + lsm6dso_fifo_ctrl1_t fifo_ctrl1; + lsm6dso_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + fifo_ctrl1.wtm = 0x00FFU & (uint8_t)val; + fifo_ctrl2.wtm = (uint8_t)((0x0100U & val) >> 8); + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL1, + (uint8_t *)&fifo_ctrl1, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + } + + return ret; +} + +/** + * @brief FIFO watermark level selection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of wtm in reg FIFO_CTRL1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_watermark_get(stmdev_ctx_t *ctx, uint16_t *val) +{ + lsm6dso_fifo_ctrl1_t fifo_ctrl1; + lsm6dso_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL1, + (uint8_t *)&fifo_ctrl1, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + *val = ((uint16_t)fifo_ctrl2.wtm << 8) + (uint16_t)fifo_ctrl1.wtm; + } + + return ret; +} + +/** + * @brief FIFO compression feature initialization request [set]. + * + * @param ctx read / write interface definitions + * @param val change the values of FIFO_COMPR_INIT in + * reg EMB_FUNC_INIT_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_compression_algo_init_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6dso_emb_func_init_b_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.fifo_compr_init = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FIFO compression feature initialization request [get]. + * + * @param ctx read / write interface definitions + * @param val change the values of FIFO_COMPR_INIT in + * reg EMB_FUNC_INIT_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_compression_algo_init_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_emb_func_init_b_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.fifo_compr_init; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable and configure compression algo.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of uncoptr_rate in + * reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_compression_algo_set(stmdev_ctx_t *ctx, + lsm6dso_uncoptr_rate_t val) +{ + lsm6dso_fifo_ctrl2_t fifo_ctrl2; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + + if (ret == 0) + { + fifo_ctrl2.fifo_compr_rt_en = ((uint8_t)val & 0x04U) >> 2; + fifo_ctrl2.uncoptr_rate = (uint8_t)val & 0x03U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, + (uint8_t *)&fifo_ctrl2, 1); + } + + return ret; +} + +/** + * @brief Enable and configure compression algo.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of uncoptr_rate in + * reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_compression_algo_get(stmdev_ctx_t *ctx, + lsm6dso_uncoptr_rate_t *val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + + switch ((reg.fifo_compr_rt_en << 2) | reg.uncoptr_rate) + { + case LSM6DSO_CMP_DISABLE: + *val = LSM6DSO_CMP_DISABLE; + break; + + case LSM6DSO_CMP_ALWAYS: + *val = LSM6DSO_CMP_ALWAYS; + break; + + case LSM6DSO_CMP_8_TO_1: + *val = LSM6DSO_CMP_8_TO_1; + break; + + case LSM6DSO_CMP_16_TO_1: + *val = LSM6DSO_CMP_16_TO_1; + break; + + case LSM6DSO_CMP_32_TO_1: + *val = LSM6DSO_CMP_32_TO_1; + break; + + default: + *val = LSM6DSO_CMP_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Enables ODR CHANGE virtual sensor to be batched in FIFO.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of odrchg_en in reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_virtual_sens_odr_chg_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.odrchg_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables ODR CHANGE virtual sensor to be batched in FIFO.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of odrchg_en in reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_virtual_sens_odr_chg_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + *val = reg.odrchg_en; + + return ret; +} + +/** + * @brief Enables/Disables compression algorithm runtime.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_compr_rt_en in + * reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_compression_algo_real_time_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fifo_compr_rt_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Enables/Disables compression algorithm runtime. [get] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_compr_rt_en in reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_compression_algo_real_time_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + *val = reg.fifo_compr_rt_en; + + return ret; +} + +/** + * @brief Sensing chain FIFO stop values memorization at + * threshold level.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of stop_on_wtm in reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_stop_on_wtm_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.stop_on_wtm = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Sensing chain FIFO stop values memorization at + * threshold level.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of stop_on_wtm in reg FIFO_CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_stop_on_wtm_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_fifo_ctrl2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL2, (uint8_t *)®, 1); + *val = reg.stop_on_wtm; + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for accelerometer data.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of bdr_xl in reg FIFO_CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_xl_batch_set(stmdev_ctx_t *ctx, + lsm6dso_bdr_xl_t val) +{ + lsm6dso_fifo_ctrl3_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.bdr_xl = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for accelerometer data.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of bdr_xl in reg FIFO_CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_xl_batch_get(stmdev_ctx_t *ctx, + lsm6dso_bdr_xl_t *val) +{ + lsm6dso_fifo_ctrl3_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t *)®, 1); + + switch (reg.bdr_xl) + { + case LSM6DSO_XL_NOT_BATCHED: + *val = LSM6DSO_XL_NOT_BATCHED; + break; + + case LSM6DSO_XL_BATCHED_AT_12Hz5: + *val = LSM6DSO_XL_BATCHED_AT_12Hz5; + break; + + case LSM6DSO_XL_BATCHED_AT_26Hz: + *val = LSM6DSO_XL_BATCHED_AT_26Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_52Hz: + *val = LSM6DSO_XL_BATCHED_AT_52Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_104Hz: + *val = LSM6DSO_XL_BATCHED_AT_104Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_208Hz: + *val = LSM6DSO_XL_BATCHED_AT_208Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_417Hz: + *val = LSM6DSO_XL_BATCHED_AT_417Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_833Hz: + *val = LSM6DSO_XL_BATCHED_AT_833Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_1667Hz: + *val = LSM6DSO_XL_BATCHED_AT_1667Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_3333Hz: + *val = LSM6DSO_XL_BATCHED_AT_3333Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_6667Hz: + *val = LSM6DSO_XL_BATCHED_AT_6667Hz; + break; + + case LSM6DSO_XL_BATCHED_AT_6Hz5: + *val = LSM6DSO_XL_BATCHED_AT_6Hz5; + break; + + default: + *val = LSM6DSO_XL_NOT_BATCHED; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for gyroscope data.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of bdr_gy in reg FIFO_CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_gy_batch_set(stmdev_ctx_t *ctx, + lsm6dso_bdr_gy_t val) +{ + lsm6dso_fifo_ctrl3_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.bdr_gy = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for gyroscope data.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of bdr_gy in reg FIFO_CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_gy_batch_get(stmdev_ctx_t *ctx, + lsm6dso_bdr_gy_t *val) +{ + lsm6dso_fifo_ctrl3_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL3, (uint8_t *)®, 1); + + switch (reg.bdr_gy) + { + case LSM6DSO_GY_NOT_BATCHED: + *val = LSM6DSO_GY_NOT_BATCHED; + break; + + case LSM6DSO_GY_BATCHED_AT_12Hz5: + *val = LSM6DSO_GY_BATCHED_AT_12Hz5; + break; + + case LSM6DSO_GY_BATCHED_AT_26Hz: + *val = LSM6DSO_GY_BATCHED_AT_26Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_52Hz: + *val = LSM6DSO_GY_BATCHED_AT_52Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_104Hz: + *val = LSM6DSO_GY_BATCHED_AT_104Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_208Hz: + *val = LSM6DSO_GY_BATCHED_AT_208Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_417Hz: + *val = LSM6DSO_GY_BATCHED_AT_417Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_833Hz: + *val = LSM6DSO_GY_BATCHED_AT_833Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_1667Hz: + *val = LSM6DSO_GY_BATCHED_AT_1667Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_3333Hz: + *val = LSM6DSO_GY_BATCHED_AT_3333Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_6667Hz: + *val = LSM6DSO_GY_BATCHED_AT_6667Hz; + break; + + case LSM6DSO_GY_BATCHED_AT_6Hz5: + *val = LSM6DSO_GY_BATCHED_AT_6Hz5; + break; + + default: + *val = LSM6DSO_GY_NOT_BATCHED; + break; + } + + return ret; +} + +/** + * @brief FIFO mode selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_mode in reg FIFO_CTRL4 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_mode_set(stmdev_ctx_t *ctx, + lsm6dso_fifo_mode_t val) +{ + lsm6dso_fifo_ctrl4_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.fifo_mode = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief FIFO mode selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fifo_mode in reg FIFO_CTRL4 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_mode_get(stmdev_ctx_t *ctx, + lsm6dso_fifo_mode_t *val) +{ + lsm6dso_fifo_ctrl4_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + + switch (reg.fifo_mode) + { + case LSM6DSO_BYPASS_MODE: + *val = LSM6DSO_BYPASS_MODE; + break; + + case LSM6DSO_FIFO_MODE: + *val = LSM6DSO_FIFO_MODE; + break; + + case LSM6DSO_STREAM_TO_FIFO_MODE: + *val = LSM6DSO_STREAM_TO_FIFO_MODE; + break; + + case LSM6DSO_BYPASS_TO_STREAM_MODE: + *val = LSM6DSO_BYPASS_TO_STREAM_MODE; + break; + + case LSM6DSO_STREAM_MODE: + *val = LSM6DSO_STREAM_MODE; + break; + + case LSM6DSO_BYPASS_TO_FIFO_MODE: + *val = LSM6DSO_BYPASS_TO_FIFO_MODE; + break; + + default: + *val = LSM6DSO_BYPASS_MODE; + break; + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for temperature data.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of odr_t_batch in reg FIFO_CTRL4 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_temp_batch_set(stmdev_ctx_t *ctx, + lsm6dso_odr_t_batch_t val) +{ + lsm6dso_fifo_ctrl4_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.odr_t_batch = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects Batching Data Rate (writing frequency in FIFO) + * for temperature data.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of odr_t_batch in reg FIFO_CTRL4 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_temp_batch_get(stmdev_ctx_t *ctx, + lsm6dso_odr_t_batch_t *val) +{ + lsm6dso_fifo_ctrl4_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + + switch (reg.odr_t_batch) + { + case LSM6DSO_TEMP_NOT_BATCHED: + *val = LSM6DSO_TEMP_NOT_BATCHED; + break; + + case LSM6DSO_TEMP_BATCHED_AT_1Hz6: + *val = LSM6DSO_TEMP_BATCHED_AT_1Hz6; + break; + + case LSM6DSO_TEMP_BATCHED_AT_12Hz5: + *val = LSM6DSO_TEMP_BATCHED_AT_12Hz5; + break; + + case LSM6DSO_TEMP_BATCHED_AT_52Hz: + *val = LSM6DSO_TEMP_BATCHED_AT_52Hz; + break; + + default: + *val = LSM6DSO_TEMP_NOT_BATCHED; + break; + } + + return ret; +} + +/** + * @brief Selects decimation for timestamp batching in FIFO. + * Writing rate will be the maximum rate between XL and + * GYRO BDR divided by decimation decoder.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of odr_ts_batch in reg FIFO_CTRL4 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_timestamp_decimation_set(stmdev_ctx_t *ctx, + lsm6dso_odr_ts_batch_t val) +{ + lsm6dso_fifo_ctrl4_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.odr_ts_batch = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects decimation for timestamp batching in FIFO. + * Writing rate will be the maximum rate between XL and + * GYRO BDR divided by decimation decoder.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of odr_ts_batch in reg FIFO_CTRL4 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_timestamp_decimation_get(stmdev_ctx_t *ctx, + lsm6dso_odr_ts_batch_t *val) +{ + lsm6dso_fifo_ctrl4_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_CTRL4, (uint8_t *)®, 1); + + switch (reg.odr_ts_batch) + { + case LSM6DSO_NO_DECIMATION: + *val = LSM6DSO_NO_DECIMATION; + break; + + case LSM6DSO_DEC_1: + *val = LSM6DSO_DEC_1; + break; + + case LSM6DSO_DEC_8: + *val = LSM6DSO_DEC_8; + break; + + case LSM6DSO_DEC_32: + *val = LSM6DSO_DEC_32; + break; + + default: + *val = LSM6DSO_NO_DECIMATION; + break; + } + + return ret; +} + +/** + * @brief Selects the trigger for the internal counter of batching events + * between XL and gyro.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of trig_counter_bdr + * in reg COUNTER_BDR_REG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_cnt_event_batch_set(stmdev_ctx_t *ctx, + lsm6dso_trig_counter_bdr_t val) +{ + lsm6dso_counter_bdr_reg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.trig_counter_bdr = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, + (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Selects the trigger for the internal counter of batching events + * between XL and gyro.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of trig_counter_bdr + * in reg COUNTER_BDR_REG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_cnt_event_batch_get(stmdev_ctx_t *ctx, + lsm6dso_trig_counter_bdr_t *val) +{ + lsm6dso_counter_bdr_reg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t *)®, 1); + + switch (reg.trig_counter_bdr) + { + case LSM6DSO_XL_BATCH_EVENT: + *val = LSM6DSO_XL_BATCH_EVENT; + break; + + case LSM6DSO_GYRO_BATCH_EVENT: + *val = LSM6DSO_GYRO_BATCH_EVENT; + break; + + default: + *val = LSM6DSO_XL_BATCH_EVENT; + break; + } + + return ret; +} + +/** + * @brief Resets the internal counter of batching vents for a single sensor. + * This bit is automatically reset to zero if it was set to '1'.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of rst_counter_bdr in + * reg COUNTER_BDR_REG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_rst_batch_counter_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_counter_bdr_reg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.rst_counter_bdr = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, + (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief Resets the internal counter of batching events for a single sensor. + * This bit is automatically reset to zero if it was set to '1'.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of rst_counter_bdr in + * reg COUNTER_BDR_REG1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_rst_batch_counter_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_counter_bdr_reg1_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, (uint8_t *)®, 1); + *val = reg.rst_counter_bdr; + + return ret; +} + +/** + * @brief Batch data rate counter.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of cnt_bdr_th in + * reg COUNTER_BDR_REG2 and COUNTER_BDR_REG1. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_batch_counter_threshold_set(stmdev_ctx_t *ctx, + uint16_t val) +{ + lsm6dso_counter_bdr_reg1_t counter_bdr_reg1; + lsm6dso_counter_bdr_reg2_t counter_bdr_reg2; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, + (uint8_t *)&counter_bdr_reg1, 1); + + if (ret == 0) + { + counter_bdr_reg2.cnt_bdr_th = 0x00FFU & (uint8_t)val; + counter_bdr_reg1.cnt_bdr_th = (uint8_t)(0x0700U & val) >> 8; + ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, + (uint8_t *)&counter_bdr_reg1, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_COUNTER_BDR_REG2, + (uint8_t *)&counter_bdr_reg2, 1); + } + + return ret; +} + +/** + * @brief Batch data rate counter.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of cnt_bdr_th in + * reg COUNTER_BDR_REG2 and COUNTER_BDR_REG1. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_batch_counter_threshold_get(stmdev_ctx_t *ctx, + uint16_t *val) +{ + lsm6dso_counter_bdr_reg1_t counter_bdr_reg1; + lsm6dso_counter_bdr_reg2_t counter_bdr_reg2; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG1, + (uint8_t *)&counter_bdr_reg1, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_COUNTER_BDR_REG2, + (uint8_t *)&counter_bdr_reg2, 1); + *val = ((uint16_t)counter_bdr_reg1.cnt_bdr_th << 8) + + (uint16_t)counter_bdr_reg2.cnt_bdr_th; + } + + return ret; +} + +/** + * @brief Number of unread sensor data(TAG + 6 bytes) stored in FIFO.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of diff_fifo in reg FIFO_STATUS1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_data_level_get(stmdev_ctx_t *ctx, uint16_t *val) +{ + lsm6dso_fifo_status1_t fifo_status1; + lsm6dso_fifo_status2_t fifo_status2; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS1, + (uint8_t *)&fifo_status1, 1); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, + (uint8_t *)&fifo_status2, 1); + *val = ((uint16_t)fifo_status2.diff_fifo << 8) + + (uint16_t)fifo_status1.diff_fifo; + } + + return ret; +} + +/** + * @brief FIFO status.[get] + * + * @param ctx read / write interface definitions + * @param val registers FIFO_STATUS2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_status_get(stmdev_ctx_t *ctx, + lsm6dso_fifo_status2_t *val) +{ + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief Smart FIFO full status.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_full_ia in reg FIFO_STATUS2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_full_flag_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_fifo_status2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t *)®, 1); + *val = reg.fifo_full_ia; + + return ret; +} + +/** + * @brief FIFO overrun status.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_over_run_latched in + * reg FIFO_STATUS2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_ovr_flag_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_fifo_status2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t *)®, 1); + *val = reg.fifo_ovr_ia; + + return ret; +} + +/** + * @brief FIFO watermark status.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_wtm_ia in reg FIFO_STATUS2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_wtm_flag_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_fifo_status2_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_STATUS2, (uint8_t *)®, 1); + *val = reg.fifo_wtm_ia; + + return ret; +} + +/** + * @brief Identifies the sensor in FIFO_DATA_OUT.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tag_sensor in reg FIFO_DATA_OUT_TAG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_sensor_tag_get(stmdev_ctx_t *ctx, + lsm6dso_fifo_tag_t *val) +{ + lsm6dso_fifo_data_out_tag_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_FIFO_DATA_OUT_TAG, + (uint8_t *)®, 1); + + switch (reg.tag_sensor) + { + case LSM6DSO_GYRO_NC_TAG: + *val = LSM6DSO_GYRO_NC_TAG; + break; + + case LSM6DSO_XL_NC_TAG: + *val = LSM6DSO_XL_NC_TAG; + break; + + case LSM6DSO_TEMPERATURE_TAG: + *val = LSM6DSO_TEMPERATURE_TAG; + break; + + case LSM6DSO_CFG_CHANGE_TAG: + *val = LSM6DSO_CFG_CHANGE_TAG; + break; + + case LSM6DSO_XL_NC_T_2_TAG: + *val = LSM6DSO_XL_NC_T_2_TAG; + break; + + case LSM6DSO_XL_NC_T_1_TAG: + *val = LSM6DSO_XL_NC_T_1_TAG; + break; + + case LSM6DSO_XL_2XC_TAG: + *val = LSM6DSO_XL_2XC_TAG; + break; + + case LSM6DSO_XL_3XC_TAG: + *val = LSM6DSO_XL_3XC_TAG; + break; + + case LSM6DSO_GYRO_NC_T_2_TAG: + *val = LSM6DSO_GYRO_NC_T_2_TAG; + break; + + case LSM6DSO_GYRO_NC_T_1_TAG: + *val = LSM6DSO_GYRO_NC_T_1_TAG; + break; + + case LSM6DSO_GYRO_2XC_TAG: + *val = LSM6DSO_GYRO_2XC_TAG; + break; + + case LSM6DSO_GYRO_3XC_TAG: + *val = LSM6DSO_GYRO_3XC_TAG; + break; + + case LSM6DSO_SENSORHUB_SLAVE0_TAG: + *val = LSM6DSO_SENSORHUB_SLAVE0_TAG; + break; + + case LSM6DSO_SENSORHUB_SLAVE1_TAG: + *val = LSM6DSO_SENSORHUB_SLAVE1_TAG; + break; + + case LSM6DSO_SENSORHUB_SLAVE2_TAG: + *val = LSM6DSO_SENSORHUB_SLAVE2_TAG; + break; + + case LSM6DSO_SENSORHUB_SLAVE3_TAG: + *val = LSM6DSO_SENSORHUB_SLAVE3_TAG; + break; + + case LSM6DSO_STEP_CPUNTER_TAG: + *val = LSM6DSO_STEP_CPUNTER_TAG; + break; + + case LSM6DSO_GAME_ROTATION_TAG: + *val = LSM6DSO_GAME_ROTATION_TAG; + break; + + case LSM6DSO_GEOMAG_ROTATION_TAG: + *val = LSM6DSO_GEOMAG_ROTATION_TAG; + break; + + case LSM6DSO_ROTATION_TAG: + *val = LSM6DSO_ROTATION_TAG; + break; + + case LSM6DSO_SENSORHUB_NACK_TAG: + *val = LSM6DSO_SENSORHUB_NACK_TAG; + break; + + default: + *val = LSM6DSO_GYRO_NC_TAG; + break; + } + + return ret; +} + +/** + * @brief : Enable FIFO batching of pedometer embedded + * function values.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of gbias_fifo_en in + * reg LSM6DSO_EMB_FUNC_FIFO_CFG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_pedo_batch_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_emb_func_fifo_cfg_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_FIFO_CFG, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.pedo_fifo_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_FIFO_CFG, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching of pedometer embedded function values.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of pedo_fifo_en in + * reg LSM6DSO_EMB_FUNC_FIFO_CFG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fifo_pedo_batch_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_emb_func_fifo_cfg_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_FIFO_CFG, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.pedo_fifo_en; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of first slave.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_0_en in + * reg SLV0_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_0_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_slv0_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.batch_ext_sens_0_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of first slave.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_0_en in + * reg SLV0_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_0_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_slv0_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.batch_ext_sens_0_en; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of second slave.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_1_en in + * reg SLV1_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_1_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_slv1_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.batch_ext_sens_1_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of second slave.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_1_en in + * reg SLV1_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_1_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_slv1_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, (uint8_t *)®, 1); + *val = reg.batch_ext_sens_1_en; + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of third slave.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_2_en in + * reg SLV2_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_2_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_slv2_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV2_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.batch_ext_sens_2_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of third slave.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_2_en in + * reg SLV2_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_2_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_slv2_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV2_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.batch_ext_sens_2_en; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of fourth slave.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_3_en + * in reg SLV3_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_3_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_slv3_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV3_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.batch_ext_sens_3_en = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Enable FIFO batching data of fourth slave.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of batch_ext_sens_3_en in + * reg SLV3_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_batch_slave_3_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_slv3_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV3_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.batch_ext_sens_3_en; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_DEN_functionality + * @brief This section groups all the functions concerning + * DEN functionality. + * @{ + * + */ + +/** + * @brief DEN functionality marking mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_mode in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mode_set(stmdev_ctx_t *ctx, + lsm6dso_den_mode_t val) +{ + lsm6dso_ctrl6_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_mode = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief DEN functionality marking mode.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of den_mode in reg CTRL6_C + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mode_get(stmdev_ctx_t *ctx, + lsm6dso_den_mode_t *val) +{ + lsm6dso_ctrl6_c_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL6_C, (uint8_t *)®, 1); + + switch (reg.den_mode) + { + case LSM6DSO_DEN_DISABLE: + *val = LSM6DSO_DEN_DISABLE; + break; + + case LSM6DSO_LEVEL_FIFO: + *val = LSM6DSO_LEVEL_FIFO; + break; + + case LSM6DSO_LEVEL_LETCHED: + *val = LSM6DSO_LEVEL_LETCHED; + break; + + case LSM6DSO_LEVEL_TRIGGER: + *val = LSM6DSO_LEVEL_TRIGGER; + break; + + case LSM6DSO_EDGE_TRIGGER: + *val = LSM6DSO_EDGE_TRIGGER; + break; + + default: + *val = LSM6DSO_DEN_DISABLE; + break; + } + + return ret; +} + +/** + * @brief DEN active level configuration.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_lh in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_polarity_set(stmdev_ctx_t *ctx, + lsm6dso_den_lh_t val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_lh = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief DEN active level configuration.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of den_lh in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_polarity_get(stmdev_ctx_t *ctx, + lsm6dso_den_lh_t *val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + switch (reg.den_lh) + { + case LSM6DSO_DEN_ACT_LOW: + *val = LSM6DSO_DEN_ACT_LOW; + break; + + case LSM6DSO_DEN_ACT_HIGH: + *val = LSM6DSO_DEN_ACT_HIGH; + break; + + default: + *val = LSM6DSO_DEN_ACT_LOW; + break; + } + + return ret; +} + +/** + * @brief DEN enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_xl_g in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_enable_set(stmdev_ctx_t *ctx, + lsm6dso_den_xl_g_t val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_xl_g = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief DEN enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of den_xl_g in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_enable_get(stmdev_ctx_t *ctx, + lsm6dso_den_xl_g_t *val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + switch (reg.den_xl_g) + { + case LSM6DSO_STAMP_IN_GY_DATA: + *val = LSM6DSO_STAMP_IN_GY_DATA; + break; + + case LSM6DSO_STAMP_IN_XL_DATA: + *val = LSM6DSO_STAMP_IN_XL_DATA; + break; + + case LSM6DSO_STAMP_IN_GY_XL_DATA: + *val = LSM6DSO_STAMP_IN_GY_XL_DATA; + break; + + default: + *val = LSM6DSO_STAMP_IN_GY_DATA; + break; + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of X-axis.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_z in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mark_axis_x_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_z = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of X-axis.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of den_z in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mark_axis_x_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + *val = reg.den_z; + + return ret; +} + +/** + * @brief DEN value stored in LSB of Y-axis.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_y in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mark_axis_y_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_y = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Y-axis.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of den_y in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mark_axis_y_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + *val = reg.den_y; + + return ret; +} + +/** + * @brief DEN value stored in LSB of Z-axis.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of den_x in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mark_axis_z_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + + if (ret == 0) + { + reg.den_x = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + } + + return ret; +} + +/** + * @brief DEN value stored in LSB of Z-axis.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of den_x in reg CTRL9_XL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_den_mark_axis_z_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_ctrl9_xl_t reg; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, (uint8_t *)®, 1); + *val = reg.den_x; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_Pedometer + * @brief This section groups all the functions that manage pedometer. + * @{ + * + */ + +/** + * @brief Enable pedometer algorithm.[set] + * + * @param ctx read / write interface definitions + * @param val turn on and configure pedometer + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_sens_set(stmdev_ctx_t *ctx, + lsm6dso_pedo_md_t val) +{ + lsm6dso_pedo_cmd_reg_t pedo_cmd_reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG, + (uint8_t *)&pedo_cmd_reg); + + if (ret == 0) + { + pedo_cmd_reg.fp_rejection_en = ((uint8_t)val & 0x10U) >> 4; + pedo_cmd_reg.ad_det_en = ((uint8_t)val & 0x20U) >> 5; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_CMD_REG, + (uint8_t *)&pedo_cmd_reg); + } + + return ret; +} + +/** + * @brief Enable pedometer algorithm.[get] + * + * @param ctx read / write interface definitions + * @param val turn on and configure pedometer + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_sens_get(stmdev_ctx_t *ctx, + lsm6dso_pedo_md_t *val) +{ + lsm6dso_pedo_cmd_reg_t pedo_cmd_reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG, + (uint8_t *)&pedo_cmd_reg); + + switch ((pedo_cmd_reg.ad_det_en << 5) | (pedo_cmd_reg.fp_rejection_en + << 4)) + { + case LSM6DSO_PEDO_BASE_MODE: + *val = LSM6DSO_PEDO_BASE_MODE; + break; + + case LSM6DSO_FALSE_STEP_REJ: + *val = LSM6DSO_FALSE_STEP_REJ; + break; + + case LSM6DSO_FALSE_STEP_REJ_ADV_MODE: + *val = LSM6DSO_FALSE_STEP_REJ_ADV_MODE; + break; + + default: + *val = LSM6DSO_PEDO_BASE_MODE; + break; + } + + return ret; +} + +/** + * @brief Interrupt status bit for step detection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of is_step_det in reg EMB_FUNC_STATUS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_step_detect_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_emb_func_status_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.is_step_det; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Pedometer debounce configuration register (r/w).[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_debounce_steps_set(stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_DEB_STEPS_CONF, + buff); + + return ret; +} + +/** + * @brief Pedometer debounce configuration register (r/w).[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_debounce_steps_get(stmdev_ctx_t *ctx, + uint8_t *buff) +{ + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_DEB_STEPS_CONF, buff); + + return ret; +} + +/** + * @brief Time period register for step detection on delta time (r/w).[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_steps_period_set(stmdev_ctx_t *ctx, uint16_t val) +{ + uint8_t buff[2]; + int32_t ret; + + buff[1] = (uint8_t)(val / 256U); + buff[0] = (uint8_t)(val - (buff[1] * 256U)); + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_H, + &buff[1]); + } + + return ret; +} + +/** + * @brief Time period register for step detection on delta time (r/w).[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_steps_period_get(stmdev_ctx_t *ctx, + uint16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_SC_DELTAT_H, + &buff[1]); + *val = buff[1]; + *val = (*val * 256U) + buff[0]; + } + + return ret; +} + +/** + * @brief Set when user wants to generate interrupt on count overflow + * event/every step.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of carry_count_en in reg PEDO_CMD_REG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_int_mode_set(stmdev_ctx_t *ctx, + lsm6dso_carry_count_en_t val) +{ + lsm6dso_pedo_cmd_reg_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG, + (uint8_t *)®); + + if (ret == 0) + { + reg.carry_count_en = (uint8_t)val; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_PEDO_CMD_REG, + (uint8_t *)®); + } + + return ret; +} + +/** + * @brief Set when user wants to generate interrupt on count overflow + * event/every step.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of carry_count_en in reg PEDO_CMD_REG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pedo_int_mode_get(stmdev_ctx_t *ctx, + lsm6dso_carry_count_en_t *val) +{ + lsm6dso_pedo_cmd_reg_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_PEDO_CMD_REG, + (uint8_t *)®); + + switch (reg.carry_count_en) + { + case LSM6DSO_EVERY_STEP: + *val = LSM6DSO_EVERY_STEP; + break; + + case LSM6DSO_COUNT_OVERFLOW: + *val = LSM6DSO_COUNT_OVERFLOW; + break; + + default: + *val = LSM6DSO_EVERY_STEP; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_significant_motion + * @brief This section groups all the functions that manage the + * significant motion detection. + * @{ + * + */ + +/** + * @brief Interrupt status bit for significant motion detection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of is_sigmot in reg EMB_FUNC_STATUS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_motion_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_emb_func_status_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.is_sigmot; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_tilt_detection + * @brief This section groups all the functions that manage the tilt + * event detection. + * @{ + * + */ + +/** + * @brief Interrupt status bit for tilt detection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of is_tilt in reg EMB_FUNC_STATUS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_tilt_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_emb_func_status_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.is_tilt; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_ magnetometer_sensor + * @brief This section groups all the functions that manage additional + * magnetometer sensor. + * @{ + * + */ + +/** + * @brief External magnetometer sensitivity value register.[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_sensitivity_set(stmdev_ctx_t *ctx, uint16_t val) +{ + uint8_t buff[2]; + int32_t ret; + + buff[1] = (uint8_t)(val / 256U); + buff[0] = (uint8_t)(val - (buff[1] * 256U)); + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SENSITIVITY_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SENSITIVITY_H, + &buff[1]); + } + + return ret; +} + +/** + * @brief External magnetometer sensitivity value register.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_sensitivity_get(stmdev_ctx_t *ctx, uint16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SENSITIVITY_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SENSITIVITY_H, + &buff[1]); + *val = buff[1]; + *val = (*val * 256U) + buff[0]; + } + + return ret; +} + +/** + * @brief Offset for hard-iron compensation register (r/w).[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_offset_set(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + buff[1] = (uint8_t)((uint16_t)val[0] / 256U); + buff[0] = (uint8_t)((uint16_t)val[0] - (buff[1] * 256U)); + buff[3] = (uint8_t)((uint16_t)val[1] / 256U); + buff[2] = (uint8_t)((uint16_t)val[1] - (buff[3] * 256U)); + buff[5] = (uint8_t)((uint16_t)val[2] / 256U); + buff[4] = (uint8_t)((uint16_t)val[2] - (buff[5] * 256U)); + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFX_L, &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFX_H, &buff[1]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFY_L, &buff[2]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFY_H, &buff[3]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFZ_L, &buff[4]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_OFFZ_H, &buff[5]); + } + + return ret; +} + +/** + * @brief Offset for hard-iron compensation register (r/w).[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_offset_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFX_L, &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFX_H, &buff[1]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFY_L, &buff[2]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFY_H, &buff[3]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFZ_L, &buff[4]); + } + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_OFFZ_H, &buff[5]); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + } + + return ret; +} + +/** + * @brief Soft-iron (3x3 symmetric) matrix correction + * register (r/w). The value is expressed as + * half-precision floating-point format: + * SEEEEEFFFFFFFFFF + * S: 1 sign bit; + * E: 5 exponent bits; + * F: 10 fraction bits).[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_soft_iron_set(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[12]; + int32_t ret; + + uint8_t index; + buff[1] = (uint8_t)((uint16_t)val[0] / 256U); + buff[0] = (uint8_t)((uint16_t)val[0] - (buff[1] * 256U)); + buff[3] = (uint8_t)((uint16_t)val[1] / 256U); + buff[2] = (uint8_t)((uint16_t)val[1] - (buff[3] * 256U)); + buff[5] = (uint8_t)((uint16_t)val[2] / 256U); + buff[4] = (uint8_t)((uint16_t)val[2] - (buff[5] * 256U)); + buff[7] = (uint8_t)((uint16_t)val[3] / 256U); + buff[6] = (uint8_t)((uint16_t)val[3] - (buff[7] * 256U)); + buff[9] = (uint8_t)((uint16_t)val[4] / 256U); + buff[8] = (uint8_t)((uint16_t)val[4] - (buff[9] * 256U)); + buff[11] = (uint8_t)((uint16_t)val[5] / 256U); + buff[10] = (uint8_t)((uint16_t)val[5] - (buff[11] * 256U)); + index = 0x00U; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XX_L, + &buff[index]); + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XX_H, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XY_L, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XY_H, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XZ_L, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_XZ_H, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YY_L, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YY_H, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YZ_L, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_YZ_H, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_ZZ_L, + &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_SI_ZZ_H, + &buff[index]); + } + + return ret; +} + +/** + * @brief Soft-iron (3x3 symmetric) matrix + * correction register (r/w). + * The value is expressed as half-precision + * floating-point format: + * SEEEEEFFFFFFFFFF + * S: 1 sign bit; + * E: 5 exponent bits; + * F: 10 fraction bits.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_soft_iron_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[12]; + int32_t ret; + + uint8_t index; + index = 0x00U; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XX_L, &buff[index]); + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XX_H, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XY_L, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XY_H, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XZ_L, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_XZ_H, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YY_L, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YY_H, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YZ_L, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_YZ_H, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_ZZ_L, &buff[index]); + } + + if (ret == 0) + { + index++; + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_SI_ZZ_H, &buff[index]); + } + + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + val[3] = (int16_t)buff[7]; + val[3] = (val[3] * 256) + (int16_t)buff[6]; + val[4] = (int16_t)buff[9]; + val[4] = (val[4] * 256) + (int16_t)buff[8]; + val[5] = (int16_t)buff[11]; + val[5] = (val[5] * 256) + (int16_t)buff[10]; + + return ret; +} + +/** + * @brief Magnetometer Z-axis coordinates + * rotation (to be aligned to + * accelerometer/gyroscope axes + * orientation).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of mag_z_axis in reg MAG_CFG_A + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_z_orient_set(stmdev_ctx_t *ctx, + lsm6dso_mag_z_axis_t val) +{ + lsm6dso_mag_cfg_a_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, + (uint8_t *)®); + + if (ret == 0) + { + reg.mag_z_axis = (uint8_t) val; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_CFG_A, + (uint8_t *)®); + } + + return ret; +} + +/** + * @brief Magnetometer Z-axis coordinates + * rotation (to be aligned to + * accelerometer/gyroscope axes + * orientation).[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of mag_z_axis in reg MAG_CFG_A + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_z_orient_get(stmdev_ctx_t *ctx, + lsm6dso_mag_z_axis_t *val) +{ + lsm6dso_mag_cfg_a_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, + (uint8_t *)®); + + switch (reg.mag_z_axis) + { + case LSM6DSO_Z_EQ_Y: + *val = LSM6DSO_Z_EQ_Y; + break; + + case LSM6DSO_Z_EQ_MIN_Y: + *val = LSM6DSO_Z_EQ_MIN_Y; + break; + + case LSM6DSO_Z_EQ_X: + *val = LSM6DSO_Z_EQ_X; + break; + + case LSM6DSO_Z_EQ_MIN_X: + *val = LSM6DSO_Z_EQ_MIN_X; + break; + + case LSM6DSO_Z_EQ_MIN_Z: + *val = LSM6DSO_Z_EQ_MIN_Z; + break; + + case LSM6DSO_Z_EQ_Z: + *val = LSM6DSO_Z_EQ_Z; + break; + + default: + *val = LSM6DSO_Z_EQ_Y; + break; + } + + return ret; +} + +/** + * @brief Magnetometer Y-axis coordinates + * rotation (to be aligned to + * accelerometer/gyroscope axes + * orientation).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of mag_y_axis in reg MAG_CFG_A + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_y_orient_set(stmdev_ctx_t *ctx, + lsm6dso_mag_y_axis_t val) +{ + lsm6dso_mag_cfg_a_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, + (uint8_t *)®); + + if (ret == 0) + { + reg.mag_y_axis = (uint8_t)val; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_CFG_A, + (uint8_t *) ®); + } + + return ret; +} + +/** + * @brief Magnetometer Y-axis coordinates + * rotation (to be aligned to + * accelerometer/gyroscope axes + * orientation).[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of mag_y_axis in reg MAG_CFG_A + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_y_orient_get(stmdev_ctx_t *ctx, + lsm6dso_mag_y_axis_t *val) +{ + lsm6dso_mag_cfg_a_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_A, + (uint8_t *)®); + + switch (reg.mag_y_axis) + { + case LSM6DSO_Y_EQ_Y: + *val = LSM6DSO_Y_EQ_Y; + break; + + case LSM6DSO_Y_EQ_MIN_Y: + *val = LSM6DSO_Y_EQ_MIN_Y; + break; + + case LSM6DSO_Y_EQ_X: + *val = LSM6DSO_Y_EQ_X; + break; + + case LSM6DSO_Y_EQ_MIN_X: + *val = LSM6DSO_Y_EQ_MIN_X; + break; + + case LSM6DSO_Y_EQ_MIN_Z: + *val = LSM6DSO_Y_EQ_MIN_Z; + break; + + case LSM6DSO_Y_EQ_Z: + *val = LSM6DSO_Y_EQ_Z; + break; + + default: + *val = LSM6DSO_Y_EQ_Y; + break; + } + + return ret; +} + +/** + * @brief Magnetometer X-axis coordinates + * rotation (to be aligned to + * accelerometer/gyroscope axes + * orientation).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of mag_x_axis in reg MAG_CFG_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_x_orient_set(stmdev_ctx_t *ctx, + lsm6dso_mag_x_axis_t val) +{ + lsm6dso_mag_cfg_b_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_B, + (uint8_t *)®); + + if (ret == 0) + { + reg.mag_x_axis = (uint8_t)val; + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_MAG_CFG_B, + (uint8_t *)®); + } + + return ret; +} + +/** + * @brief Magnetometer X-axis coordinates + * rotation (to be aligned to + * accelerometer/gyroscope axes + * orientation).[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of mag_x_axis in reg MAG_CFG_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mag_x_orient_get(stmdev_ctx_t *ctx, + lsm6dso_mag_x_axis_t *val) +{ + lsm6dso_mag_cfg_b_t reg; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_MAG_CFG_B, + (uint8_t *)®); + + switch (reg.mag_x_axis) + { + case LSM6DSO_X_EQ_Y: + *val = LSM6DSO_X_EQ_Y; + break; + + case LSM6DSO_X_EQ_MIN_Y: + *val = LSM6DSO_X_EQ_MIN_Y; + break; + + case LSM6DSO_X_EQ_X: + *val = LSM6DSO_X_EQ_X; + break; + + case LSM6DSO_X_EQ_MIN_X: + *val = LSM6DSO_X_EQ_MIN_X; + break; + + case LSM6DSO_X_EQ_MIN_Z: + *val = LSM6DSO_X_EQ_MIN_Z; + break; + + case LSM6DSO_X_EQ_Z: + *val = LSM6DSO_X_EQ_Z; + break; + + default: + *val = LSM6DSO_X_EQ_Y; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_finite_state_machine + * @brief This section groups all the functions that manage the + * state_machine. + * @{ + * + */ + +/** + * @brief Interrupt status bit for FSM long counter + * timeout interrupt event.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of is_fsm_lc in reg EMB_FUNC_STATUS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_cnt_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lsm6dso_emb_func_status_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.is_fsm_lc; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Final State Machine enable.[set] + * + * @param ctx read / write interface definitions + * @param val union of registers from FSM_ENABLE_A to FSM_ENABLE_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_enable_set(stmdev_ctx_t *ctx, + lsm6dso_emb_fsm_enable_t *val) +{ + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_ENABLE_A, + (uint8_t *)&val->fsm_enable_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_ENABLE_B, + (uint8_t *)&val->fsm_enable_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Final State Machine enable.[get] + * + * @param ctx read / write interface definitions + * @param val union of registers from FSM_ENABLE_A to FSM_ENABLE_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_enable_get(stmdev_ctx_t *ctx, + lsm6dso_emb_fsm_enable_t *val) +{ + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_ENABLE_A, (uint8_t *) val, 2); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FSM long counter status register. Long counter value is an + * unsigned integer value (16-bit format).[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_cnt_set(stmdev_ctx_t *ctx, uint16_t val) +{ + uint8_t buff[2]; + int32_t ret; + + buff[1] = (uint8_t)(val / 256U); + buff[0] = (uint8_t)(val - (buff[1] * 256U)); + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_L, buff, 2); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FSM long counter status register. Long counter value is an + * unsigned integer value (16-bit format).[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_cnt_get(stmdev_ctx_t *ctx, uint16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_L, buff, 2); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + *val = buff[1]; + *val = (*val * 256U) + buff[0]; + } + + return ret; +} + +/** + * @brief Clear FSM long counter value.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fsm_lc_clr in + * reg FSM_LONG_COUNTER_CLEAR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_clr_set(stmdev_ctx_t *ctx, + lsm6dso_fsm_lc_clr_t val) +{ + lsm6dso_fsm_long_counter_clear_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_CLEAR, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg. fsm_lc_clr = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_CLEAR, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Clear FSM long counter value.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fsm_lc_clr in + * reg FSM_LONG_COUNTER_CLEAR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_clr_get(stmdev_ctx_t *ctx, + lsm6dso_fsm_lc_clr_t *val) +{ + lsm6dso_fsm_long_counter_clear_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_LONG_COUNTER_CLEAR, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.fsm_lc_clr) + { + case LSM6DSO_LC_NORMAL: + *val = LSM6DSO_LC_NORMAL; + break; + + case LSM6DSO_LC_CLEAR: + *val = LSM6DSO_LC_CLEAR; + break; + + case LSM6DSO_LC_CLEAR_DONE: + *val = LSM6DSO_LC_CLEAR_DONE; + break; + + default: + *val = LSM6DSO_LC_NORMAL; + break; + } + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FSM output registers[get] + * + * @param ctx read / write interface definitions + * @param val struct of registers from FSM_OUTS1 to FSM_OUTS16 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_out_get(stmdev_ctx_t *ctx, lsm6dso_fsm_out_t *val) +{ + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_OUTS1, (uint8_t *)val, 16); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Finite State Machine ODR configuration.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fsm_odr in reg EMB_FUNC_ODR_CFG_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_fsm_odr_t val) +{ + lsm6dso_emb_func_odr_cfg_b_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.not_used_01 = 3; /* set default values */ + reg.not_used_02 = 2; /* set default values */ + reg.fsm_odr = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Finite State Machine ODR configuration.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fsm_odr in reg EMB_FUNC_ODR_CFG_B + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_fsm_odr_t *val) +{ + lsm6dso_emb_func_odr_cfg_b_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B, + (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.fsm_odr) + { + case LSM6DSO_ODR_FSM_12Hz5: + *val = LSM6DSO_ODR_FSM_12Hz5; + break; + + case LSM6DSO_ODR_FSM_26Hz: + *val = LSM6DSO_ODR_FSM_26Hz; + break; + + case LSM6DSO_ODR_FSM_52Hz: + *val = LSM6DSO_ODR_FSM_52Hz; + break; + + case LSM6DSO_ODR_FSM_104Hz: + *val = LSM6DSO_ODR_FSM_104Hz; + break; + + default: + *val = LSM6DSO_ODR_FSM_12Hz5; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FSM initialization request.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fsm_init in reg FSM_INIT + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_init_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_emb_func_init_b_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.fsm_init = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FSM initialization request.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fsm_init in reg FSM_INIT + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_init_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_emb_func_init_b_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.fsm_init; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief FSM long counter timeout register (r/w). The long counter + * timeout value is an unsigned integer value (16-bit format). + * When the long counter value reached this value, + * the FSM generates an interrupt.[set] + * + * @param ctx read / write interface definitions + * @param val the value of long counter + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_cnt_int_value_set(stmdev_ctx_t *ctx, + uint16_t val) +{ + uint8_t buff[2]; + int32_t ret; + + buff[1] = (uint8_t)(val / 256U); + buff[0] = (uint8_t)(val - (buff[1] * 256U)); + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_H, + &buff[1]); + } + + return ret; +} + +/** + * @brief FSM long counter timeout register (r/w). The long counter + * timeout value is an unsigned integer value (16-bit format). + * When the long counter value reached this value, + * the FSM generates an interrupt.[get] + * + * @param ctx read / write interface definitions + * @param val buffer that stores the value of long counter + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_long_cnt_int_value_get(stmdev_ctx_t *ctx, + uint16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_LC_TIMEOUT_H, + &buff[1]); + *val = buff[1]; + *val = (*val * 256U) + buff[0]; + } + + return ret; +} + +/** + * @brief FSM number of programs register.[set] + * + * @param ctx read / write interface definitions + * @param val value to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_number_of_programs_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + int32_t ret; + + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_PROGRAMS, &val); + + return ret; +} + +/** + * @brief FSM number of programs register.[get] + * + * @param ctx read / write interface definitions + * @param val buffer that stores data read. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_number_of_programs_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_PROGRAMS, val); + + return ret; +} + +/** + * @brief FSM start address register (r/w). + * First available address is 0x033C.[set] + * + * @param ctx read / write interface definitions + * @param val the value of start address + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_start_address_set(stmdev_ctx_t *ctx, uint16_t val) +{ + uint8_t buff[2]; + int32_t ret; + + buff[1] = (uint8_t)(val / 256U); + buff[0] = (uint8_t)(val - (buff[1] * 256U)); + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_START_ADD_L, + &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_write_byte(ctx, LSM6DSO_FSM_START_ADD_H, + &buff[1]); + } + + return ret; +} + +/** + * @brief FSM start address register (r/w). + * First available address is 0x033C.[get] + * + * @param ctx read / write interface definitions + * @param val buffer the value of start address. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_fsm_start_address_get(stmdev_ctx_t *ctx, + uint16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_START_ADD_L, &buff[0]); + + if (ret == 0) + { + ret = lsm6dso_ln_pg_read_byte(ctx, LSM6DSO_FSM_START_ADD_H, &buff[1]); + *val = buff[1]; + *val = (*val * 256U) + buff[0]; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LSM6DSO_Sensor_hub + * @brief This section groups all the functions that manage the + * sensor hub. + * @{ + * + */ + +/** + * @brief Sensor hub output registers.[get] + * + * @param ctx read / write interface definitions + * @param val values read from registers SENSOR_HUB_1 to SENSOR_HUB_18 + * @param len number of consecutive register to read (max 18) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_read_data_raw_get(stmdev_ctx_t *ctx, uint8_t *val, + uint8_t len) +{ + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SENSOR_HUB_1, (uint8_t *) val, + len); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Number of external sensors to be read by the sensor hub.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of aux_sens_on in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_slave_connected_set(stmdev_ctx_t *ctx, + lsm6dso_aux_sens_on_t val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.aux_sens_on = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Number of external sensors to be read by the sensor hub.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of aux_sens_on in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_slave_connected_get(stmdev_ctx_t *ctx, + lsm6dso_aux_sens_on_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.aux_sens_on) + { + case LSM6DSO_SLV_0: + *val = LSM6DSO_SLV_0; + break; + + case LSM6DSO_SLV_0_1: + *val = LSM6DSO_SLV_0_1; + break; + + case LSM6DSO_SLV_0_1_2: + *val = LSM6DSO_SLV_0_1_2; + break; + + case LSM6DSO_SLV_0_1_2_3: + *val = LSM6DSO_SLV_0_1_2_3; + break; + + default: + *val = LSM6DSO_SLV_0; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Sensor hub I2C master enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of master_on in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_master_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.master_on = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Sensor hub I2C master enable.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of master_on in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_master_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.master_on; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Master I2C pull-up enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of shub_pu_en in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_pin_mode_set(stmdev_ctx_t *ctx, + lsm6dso_shub_pu_en_t val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.shub_pu_en = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Master I2C pull-up enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of shub_pu_en in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_pin_mode_get(stmdev_ctx_t *ctx, + lsm6dso_shub_pu_en_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.shub_pu_en) + { + case LSM6DSO_EXT_PULL_UP: + *val = LSM6DSO_EXT_PULL_UP; + break; + + case LSM6DSO_INTERNAL_PULL_UP: + *val = LSM6DSO_INTERNAL_PULL_UP; + break; + + default: + *val = LSM6DSO_EXT_PULL_UP; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief I2C interface pass-through.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of pass_through_mode in + * reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_pass_through_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.pass_through_mode = val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief I2C interface pass-through.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of pass_through_mode in + * reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_pass_through_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.pass_through_mode; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Sensor hub trigger signal selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of start_config in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_syncro_mode_set(stmdev_ctx_t *ctx, + lsm6dso_start_config_t val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.start_config = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Sensor hub trigger signal selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of start_config in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_syncro_mode_get(stmdev_ctx_t *ctx, + lsm6dso_start_config_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.start_config) + { + case LSM6DSO_EXT_ON_INT2_PIN: + *val = LSM6DSO_EXT_ON_INT2_PIN; + break; + + case LSM6DSO_XL_GY_DRDY: + *val = LSM6DSO_XL_GY_DRDY; + break; + + default: + *val = LSM6DSO_EXT_ON_INT2_PIN; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Slave 0 write operation is performed only at the first + * sensor hub cycle.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of write_once in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_write_mode_set(stmdev_ctx_t *ctx, + lsm6dso_write_once_t val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.write_once = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Slave 0 write operation is performed only at the first sensor + * hub cycle.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of write_once in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_write_mode_get(stmdev_ctx_t *ctx, + lsm6dso_write_once_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.write_once) + { + case LSM6DSO_EACH_SH_CYCLE: + *val = LSM6DSO_EACH_SH_CYCLE; + break; + + case LSM6DSO_ONLY_FIRST_CYCLE: + *val = LSM6DSO_ONLY_FIRST_CYCLE; + break; + + default: + *val = LSM6DSO_EACH_SH_CYCLE; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Reset Master logic and output registers.[set] + * + * @param ctx read / write interface definitions + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_reset_set(stmdev_ctx_t *ctx) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.rst_master_regs = PROPERTY_ENABLE; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.rst_master_regs = PROPERTY_DISABLE; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Reset Master logic and output registers.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of rst_master_regs in reg MASTER_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_reset_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lsm6dso_master_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MASTER_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + *val = reg.rst_master_regs; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Rate at which the master communicates.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of shub_odr in reg slv1_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_shub_odr_t val) +{ + lsm6dso_slv0_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + reg.shub_odr = (uint8_t)val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Rate at which the master communicates.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of shub_odr in reg slv1_CONFIG + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_shub_odr_t *val) +{ + lsm6dso_slv0_config_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, (uint8_t *)®, 1); + } + + if (ret == 0) + { + switch (reg.shub_odr) + { + case LSM6DSO_SH_ODR_104Hz: + *val = LSM6DSO_SH_ODR_104Hz; + break; + + case LSM6DSO_SH_ODR_52Hz: + *val = LSM6DSO_SH_ODR_52Hz; + break; + + case LSM6DSO_SH_ODR_26Hz: + *val = LSM6DSO_SH_ODR_26Hz; + break; + + case LSM6DSO_SH_ODR_13Hz: + *val = LSM6DSO_SH_ODR_13Hz; + break; + + default: + *val = LSM6DSO_SH_ODR_104Hz; + break; + } + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a write.[set] + * + * @param ctx read / write interface definitions + * @param val a structure that contain + * - uint8_t slv1_add; 8 bit i2c device address + * - uint8_t slv1_subadd; 8 bit register device address + * - uint8_t slv1_data; 8 bit data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_cfg_write(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_write_t *val) +{ + lsm6dso_slv0_add_t reg; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + reg.slave0 = val->slv0_add; + reg.rw_0 = 0; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_ADD, (uint8_t *)®, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_SUBADD, + &(val->slv0_subadd), 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_DATAWRITE_SLV0, + &(val->slv0_data), 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a read.[set] + * + * @param ctx read / write interface definitions + * @param val Structure that contain + * - uint8_t slv1_add; 8 bit i2c device address + * - uint8_t slv1_subadd; 8 bit register device address + * - uint8_t slv1_len; num of bit to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_slv0_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val) +{ + lsm6dso_slv0_add_t slv0_add; + lsm6dso_slv0_config_t slv0_config; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + slv0_add.slave0 = val->slv_add; + slv0_add.rw_0 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_ADD, (uint8_t *)&slv0_add, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_SUBADD, + &(val->slv_subadd), 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV0_CONFIG, + (uint8_t *)&slv0_config, 1); + } + + if (ret == 0) + { + slv0_config.slave0_numop = val->slv_len; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV0_CONFIG, + (uint8_t *)&slv0_config, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a write/read.[set] + * + * @param ctx read / write interface definitions + * @param val Structure that contain + * - uint8_t slv1_add; 8 bit i2c device address + * - uint8_t slv1_subadd; 8 bit register device address + * - uint8_t slv1_len; num of bit to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_slv1_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val) +{ + lsm6dso_slv1_add_t slv1_add; + lsm6dso_slv1_config_t slv1_config; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + slv1_add.slave1_add = val->slv_add; + slv1_add.r_1 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_ADD, (uint8_t *)&slv1_add, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_SUBADD, + &(val->slv_subadd), 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV1_CONFIG, + (uint8_t *)&slv1_config, 1); + } + + if (ret == 0) + { + slv1_config.slave1_numop = val->slv_len; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV1_CONFIG, + (uint8_t *)&slv1_config, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a write/read.[set] + * + * @param ctx read / write interface definitions + * @param val Structure that contain + * - uint8_t slv2_add; 8 bit i2c device address + * - uint8_t slv2_subadd; 8 bit register device address + * - uint8_t slv2_len; num of bit to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_slv2_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val) +{ + lsm6dso_slv2_add_t slv2_add; + lsm6dso_slv2_config_t slv2_config; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + slv2_add.slave2_add = val->slv_add; + slv2_add.r_2 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_ADD, (uint8_t *)&slv2_add, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_SUBADD, + &(val->slv_subadd), 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV2_CONFIG, + (uint8_t *)&slv2_config, 1); + } + + if (ret == 0) + { + slv2_config.slave2_numop = val->slv_len; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV2_CONFIG, + (uint8_t *)&slv2_config, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Configure slave 0 for perform a write/read.[set] + * + * @param ctx read / write interface definitions + * @param val Structure that contain + * - uint8_t slv3_add; 8 bit i2c device address + * - uint8_t slv3_subadd; 8 bit register device address + * - uint8_t slv3_len; num of bit to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_slv3_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val) +{ + lsm6dso_slv3_add_t slv3_add; + lsm6dso_slv3_config_t slv3_config; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + slv3_add.slave3_add = val->slv_add; + slv3_add.r_3 = 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_ADD, (uint8_t *)&slv3_add, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_SUBADD, + &(val->slv_subadd), 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_SLV3_CONFIG, + (uint8_t *)&slv3_config, 1); + } + + if (ret == 0) + { + slv3_config.slave3_numop = val->slv_len; + ret = lsm6dso_write_reg(ctx, LSM6DSO_SLV3_CONFIG, + (uint8_t *)&slv3_config, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Sensor hub source register.[get] + * + * @param ctx read / write interface definitions + * @param val union of registers from STATUS_MASTER to + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_sh_status_get(stmdev_ctx_t *ctx, + lsm6dso_status_master_t *val) +{ + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_SENSOR_HUB_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_MASTER, (uint8_t *) val, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup Basic configuration + * @brief This section groups all the functions concerning + * device basic configuration. + * @{ + * + */ + +/** + * @brief Device "Who am I".[get] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val ID values read from the two interfaces. ID values + * will be the same.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_id_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_id_t *val) +{ + int32_t ret = 0; + + if (ctx != NULL) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_WHO_AM_I, + (uint8_t *) & (val->ui), 1); + } + + if (aux_ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_WHO_AM_I, + (uint8_t *) & (val->aux), 1); + } + } + + return ret; +} + +/** + * @brief Re-initialize the device.[set] + * + * @param ctx communication interface handler.(ptr) + * @param val re-initialization mode. Refer to datasheet + * and application note for more information + * about differencies between boot and sw_reset + * procedure. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_init_set(stmdev_ctx_t *ctx, lsm6dso_init_t val) +{ + lsm6dso_emb_func_init_a_t emb_func_init_a; + lsm6dso_emb_func_init_b_t emb_func_init_b; + lsm6dso_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, + (uint8_t *)&emb_func_init_b, 1); + } + + if (ret == 0) + { + emb_func_init_b.fifo_compr_init = (uint8_t)val + & ((uint8_t)LSM6DSO_FIFO_COMP >> 2); + emb_func_init_b.fsm_init = (uint8_t)val + & ((uint8_t)LSM6DSO_FSM >> 3); + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INIT_B, + (uint8_t *)&emb_func_init_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INIT_A, + (uint8_t *)&emb_func_init_a, 1); + } + + if (ret == 0) + { + emb_func_init_a.step_det_init = ((uint8_t)val + & (uint8_t)LSM6DSO_PEDO) >> 5; + emb_func_init_a.tilt_init = ((uint8_t)val + & (uint8_t)LSM6DSO_TILT) >> 6; + emb_func_init_a.sig_mot_init = ((uint8_t)val + & (uint8_t)LSM6DSO_SMOTION) >> 7; + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INIT_A, + (uint8_t *)&emb_func_init_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + if (((val == LSM6DSO_BOOT) || (val == LSM6DSO_RESET)) && + (ret == 0)) + { + ctrl3_c.boot = (uint8_t)val & (uint8_t)LSM6DSO_BOOT; + ctrl3_c.sw_reset = ((uint8_t)val & (uint8_t)LSM6DSO_RESET) >> 1; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + if ((val == LSM6DSO_DRV_RDY) + && ((ctrl3_c.bdu == PROPERTY_DISABLE) + || (ctrl3_c.if_inc == PROPERTY_DISABLE)) && (ret == 0)) + { + ctrl3_c.bdu = PROPERTY_ENABLE; + ctrl3_c.if_inc = PROPERTY_ENABLE; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + return ret; +} + +/** + * @brief Configures the bus operating mode.[set] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val configures the bus operating mode for both the + * main and the auxiliary interface. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_bus_mode_set(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_bus_mode_t val) +{ + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + lsm6dso_ctrl9_xl_t ctrl9_xl; + lsm6dso_ctrl3_c_t ctrl3_c; + lsm6dso_ctrl4_c_t ctrl4_c; + uint8_t bit_val; + int32_t ret; + + ret = 0; + + if (aux_ctx != NULL) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_CTRL1_OIS, + (uint8_t *)&ctrl1_ois, 1); + bit_val = ((uint8_t)val.aux_bus_md & 0x04U) >> 2; + + if ((ret == 0) && (ctrl1_ois.sim_ois != bit_val)) + { + ctrl1_ois.sim_ois = bit_val; + ret = lsm6dso_write_reg(aux_ctx, LSM6DSO_CTRL1_OIS, + (uint8_t *)&ctrl1_ois, 1); + } + } + + if (ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + bit_val = ((uint8_t)val.ui_bus_md & 0x04U) >> 2; + + if ((ret == 0) && (ctrl9_xl.i3c_disable != bit_val)) + { + ctrl9_xl.i3c_disable = bit_val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + bit_val = ((uint8_t)val.ui_bus_md & 0x30U) >> 4; + + if ((ret == 0) && (i3c_bus_avb.i3c_bus_avb_sel != bit_val)) + { + i3c_bus_avb.i3c_bus_avb_sel = bit_val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + bit_val = ((uint8_t)val.ui_bus_md & 0x02U) >> 1; + + if ((ret == 0) && (ctrl4_c.i2c_disable != bit_val)) + { + ctrl4_c.i2c_disable = bit_val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + + bit_val = (uint8_t)val.ui_bus_md & 0x01U; + + if ((ret == 0) && (ctrl3_c.sim != bit_val)) + { + ctrl3_c.sim = bit_val; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + } + } + + return ret; +} + +/** + * @brief Get the bus operating mode.[get] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val retrieves the bus operating mode for both the main + * and the auxiliary interface.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_bus_mode_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_bus_mode_t *val) +{ + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + lsm6dso_ctrl9_xl_t ctrl9_xl; + lsm6dso_ctrl3_c_t ctrl3_c; + lsm6dso_ctrl4_c_t ctrl4_c; + int32_t ret = 0; + + if (aux_ctx != NULL) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_CTRL1_OIS, + (uint8_t *)&ctrl1_ois, 1); + + switch (ctrl1_ois.sim_ois) + { + case LSM6DSO_SPI_4W_AUX: + val->aux_bus_md = LSM6DSO_SPI_4W_AUX; + break; + + case LSM6DSO_SPI_3W_AUX: + val->aux_bus_md = LSM6DSO_SPI_3W_AUX; + break; + + default: + val->aux_bus_md = LSM6DSO_SPI_4W_AUX; + break; + } + } + + if (ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL9_XL, + (uint8_t *)&ctrl9_xl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, + (uint8_t *)&ctrl4_c, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, + (uint8_t *)&ctrl3_c, 1); + + switch ((i3c_bus_avb.i3c_bus_avb_sel << 4) & + (ctrl9_xl.i3c_disable << 2) & + (ctrl4_c.i2c_disable << 1) & ctrl3_c.sim) + { + case LSM6DSO_SEL_BY_HW: + val->ui_bus_md = LSM6DSO_SEL_BY_HW; + break; + + case LSM6DSO_SPI_4W: + val->ui_bus_md = LSM6DSO_SPI_4W; + break; + + case LSM6DSO_SPI_3W: + val->ui_bus_md = LSM6DSO_SPI_3W; + break; + + case LSM6DSO_I2C: + val->ui_bus_md = LSM6DSO_I2C; + break; + + case LSM6DSO_I3C_T_50us: + val->ui_bus_md = LSM6DSO_I3C_T_50us; + break; + + case LSM6DSO_I3C_T_2us: + val->ui_bus_md = LSM6DSO_I3C_T_2us; + break; + + case LSM6DSO_I3C_T_1ms: + val->ui_bus_md = LSM6DSO_I3C_T_1ms; + break; + + case LSM6DSO_I3C_T_25ms: + val->ui_bus_md = LSM6DSO_I3C_T_25ms; + break; + + default: + val->ui_bus_md = LSM6DSO_SEL_BY_HW; + break; + } + } + } + + return ret; +} + +/** + * @brief Get the status of the device.[get] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val the status of the device.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_status_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_status_t *val) +{ + lsm6dso_status_spiaux_t status_spiaux; + lsm6dso_status_reg_t status_reg; + lsm6dso_ctrl3_c_t ctrl3_c; + int32_t ret; + ret = 0; + + if (aux_ctx != NULL) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_STATUS_SPIAUX, + (uint8_t *)&status_spiaux, 1); + val->ois_drdy_xl = status_spiaux.xlda; + val->ois_drdy_g = status_spiaux.gda; + val->ois_gyro_settling = status_spiaux.gyro_settling; + } + + if (ctx != NULL) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + val->sw_reset = ctrl3_c.sw_reset; + val->boot = ctrl3_c.boot; + + if ((ret == 0) && (ctrl3_c.sw_reset == PROPERTY_DISABLE) && + (ctrl3_c.boot == PROPERTY_DISABLE)) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_REG, + (uint8_t *)&status_reg, 1); + val->drdy_xl = status_reg.xlda; + val->drdy_g = status_reg.gda; + val->drdy_temp = status_reg.tda; + } + } + + return ret; +} + +/** + * @brief Electrical pin configuration.[set] + * + * @param ctx communication interface handler.(ptr) + * @param val the electrical settings for the configurable + * pins. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_conf_set(stmdev_ctx_t *ctx, + lsm6dso_pin_conf_t val) +{ + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + lsm6dso_pin_ctrl_t pin_ctrl; + lsm6dso_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)&pin_ctrl, 1); + + if (ret == 0) + { + pin_ctrl.ois_pu_dis = ~val.aux_sdo_ocs_pull_up; + pin_ctrl.sdo_pu_en = val.sdo_sa0_pull_up; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)&pin_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + if (ret == 0) + { + ctrl3_c.pp_od = ~val.int1_int2_push_pull; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + if (ret == 0) + { + i3c_bus_avb.pd_dis_int1 = ~val.int1_pull_down; + ret = lsm6dso_write_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + return ret; +} + +/** + * @brief Electrical pin configuration.[get] + * + * @param ctx communication interface handler.(ptr) + * @param val the electrical settings for the configurable + * pins.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_conf_get(stmdev_ctx_t *ctx, + lsm6dso_pin_conf_t *val) +{ + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + lsm6dso_pin_ctrl_t pin_ctrl; + lsm6dso_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_PIN_CTRL, (uint8_t *)&pin_ctrl, 1); + + if (ret == 0) + { + val->aux_sdo_ocs_pull_up = ~pin_ctrl.ois_pu_dis; + val->aux_sdo_ocs_pull_up = pin_ctrl.sdo_pu_en; + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + if (ret == 0) + { + val->int1_int2_push_pull = ~ctrl3_c.pp_od; + ret = lsm6dso_read_reg(ctx, LSM6DSO_I3C_BUS_AVB, + (uint8_t *)&i3c_bus_avb, 1); + } + + if (ret == 0) + { + val->int1_pull_down = ~i3c_bus_avb.pd_dis_int1; + } + + return ret; +} + +/** + * @brief Interrupt pins hardware signal configuration.[set] + * + * @param ctx communication interface handler.(ptr) + * @param val the pins hardware signal settings. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_interrupt_mode_set(stmdev_ctx_t *ctx, + lsm6dso_int_mode_t val) +{ + lsm6dso_tap_cfg0_t tap_cfg0; + lsm6dso_page_rw_t page_rw; + lsm6dso_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.h_lactive = val.active_low; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *) &tap_cfg0, 1); + } + + if (ret == 0) + { + tap_cfg0.lir = val.base_latched; + tap_cfg0.int_clr_on_read = val.base_latched | val.emb_latched; + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *) &tap_cfg0, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.emb_func_lir = val.emb_latched; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Interrupt pins hardware signal configuration.[get] + * + * @param ctx communication interface handler.(ptr) + * @param val the pins hardware signal settings.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_interrupt_mode_get(stmdev_ctx_t *ctx, + lsm6dso_int_mode_t *val) +{ + lsm6dso_tap_cfg0_t tap_cfg0; + lsm6dso_page_rw_t page_rw; + lsm6dso_ctrl3_c_t ctrl3_c; + int32_t ret; + + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL3_C, (uint8_t *)&ctrl3_c, 1); + + if (ret == 0) + { + ctrl3_c.h_lactive = val->active_low; + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG0, (uint8_t *) &tap_cfg0, 1); + } + + if (ret == 0) + { + tap_cfg0.lir = val->base_latched; + tap_cfg0.int_clr_on_read = val->base_latched | val->emb_latched; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + page_rw.emb_func_lir = val->emb_latched; + ret = lsm6dso_write_reg(ctx, LSM6DSO_PAGE_RW, (uint8_t *) &page_rw, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Route interrupt signals on int1 pin.[set] + * + * @param ctx communication interface handler.(ptr) + * @param val the signals to route on int1 pin. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_int1_route_set(stmdev_ctx_t *ctx, + lsm6dso_pin_int1_route_t val) +{ + lsm6dso_pin_int2_route_t pin_int2_route; + lsm6dso_emb_func_int1_t emb_func_int1; + lsm6dso_fsm_int1_a_t fsm_int1_a; + lsm6dso_fsm_int1_b_t fsm_int1_b; + lsm6dso_int1_ctrl_t int1_ctrl; + lsm6dso_int2_ctrl_t int2_ctrl; + lsm6dso_tap_cfg2_t tap_cfg2; + lsm6dso_md2_cfg_t md2_cfg; + lsm6dso_md1_cfg_t md1_cfg; + lsm6dso_ctrl4_c_t ctrl4_c; + int32_t ret; + int1_ctrl.int1_drdy_xl = val.drdy_xl; + int1_ctrl.int1_drdy_g = val.drdy_g; + int1_ctrl.int1_boot = val.boot; + int1_ctrl.int1_fifo_th = val.fifo_th; + int1_ctrl.int1_fifo_ovr = val.fifo_ovr; + int1_ctrl.int1_fifo_full = val.fifo_full; + int1_ctrl.int1_cnt_bdr = val.fifo_bdr; + int1_ctrl.den_drdy_flag = val.den_flag; + md1_cfg.int1_shub = val.sh_endop; + md1_cfg.int1_6d = val.six_d; + md1_cfg.int1_double_tap = val.double_tap; + md1_cfg.int1_ff = val.free_fall; + md1_cfg.int1_wu = val.wake_up; + md1_cfg.int1_single_tap = val.single_tap; + md1_cfg.int1_sleep_change = val.sleep_change; + emb_func_int1.not_used_01 = 0; + emb_func_int1.int1_step_detector = val.step_detector; + emb_func_int1.int1_tilt = val.tilt; + emb_func_int1.int1_sig_mot = val.sig_mot; + emb_func_int1.not_used_02 = 0; + emb_func_int1.int1_fsm_lc = val.fsm_lc; + fsm_int1_a.int1_fsm1 = val.fsm1; + fsm_int1_a.int1_fsm2 = val.fsm2; + fsm_int1_a.int1_fsm3 = val.fsm3; + fsm_int1_a.int1_fsm4 = val.fsm4; + fsm_int1_a.int1_fsm5 = val.fsm5; + fsm_int1_a.int1_fsm6 = val.fsm6; + fsm_int1_a.int1_fsm7 = val.fsm7; + fsm_int1_a.int1_fsm8 = val.fsm8; + fsm_int1_b.int1_fsm9 = val.fsm9 ; + fsm_int1_b.int1_fsm10 = val.fsm10; + fsm_int1_b.int1_fsm11 = val.fsm11; + fsm_int1_b.int1_fsm12 = val.fsm12; + fsm_int1_b.int1_fsm13 = val.fsm13; + fsm_int1_b.int1_fsm14 = val.fsm14; + fsm_int1_b.int1_fsm15 = val.fsm15; + fsm_int1_b.int1_fsm16 = val.fsm16; + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + if ((val.drdy_temp | val.timestamp) != PROPERTY_DISABLE) + { + ctrl4_c.int2_on_int1 = PROPERTY_ENABLE; + } + + else + { + ctrl4_c.int2_on_int1 = PROPERTY_DISABLE; + } + + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)&ctrl4_c, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INT1, + (uint8_t *)&emb_func_int1, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT1_A, + (uint8_t *)&fsm_int1_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT1_B, + (uint8_t *)&fsm_int1_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + if (ret == 0) + { + if ((emb_func_int1.int1_fsm_lc + | emb_func_int1.int1_sig_mot + | emb_func_int1.int1_step_detector + | emb_func_int1.int1_tilt + | fsm_int1_a.int1_fsm1 + | fsm_int1_a.int1_fsm2 + | fsm_int1_a.int1_fsm3 + | fsm_int1_a.int1_fsm4 + | fsm_int1_a.int1_fsm5 + | fsm_int1_a.int1_fsm6 + | fsm_int1_a.int1_fsm7 + | fsm_int1_a.int1_fsm8 + | fsm_int1_b.int1_fsm9 + | fsm_int1_b.int1_fsm10 + | fsm_int1_b.int1_fsm11 + | fsm_int1_b.int1_fsm12 + | fsm_int1_b.int1_fsm13 + | fsm_int1_b.int1_fsm14 + | fsm_int1_b.int1_fsm15 + | fsm_int1_b.int1_fsm16) != PROPERTY_DISABLE) + { + md1_cfg.int1_emb_func = PROPERTY_ENABLE; + } + + else + { + md1_cfg.int1_emb_func = PROPERTY_DISABLE; + } + + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT1_CTRL, + (uint8_t *)&int1_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_MD1_CFG, (uint8_t *)&md1_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT2_CTRL, (uint8_t *)&int2_ctrl, 1); + } + + if (ret == 0) + { + int2_ctrl.int2_drdy_temp = val.drdy_temp; + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT2_CTRL, (uint8_t *)&int2_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + md2_cfg.int2_timestamp = val.timestamp; + ret = lsm6dso_write_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *) &tap_cfg2, 1); + } + + if (ret == 0) + { + ret = lsm6dso_pin_int2_route_get(ctx, NULL, &pin_int2_route); + } + + if (ret == 0) + { + if ((pin_int2_route.fifo_bdr + | pin_int2_route.drdy_g + | pin_int2_route.drdy_temp + | pin_int2_route.drdy_xl + | pin_int2_route.fifo_full + | pin_int2_route.fifo_ovr + | pin_int2_route.fifo_th + | pin_int2_route.six_d + | pin_int2_route.double_tap + | pin_int2_route.free_fall + | pin_int2_route.wake_up + | pin_int2_route.single_tap + | pin_int2_route.sleep_change + | int1_ctrl.den_drdy_flag + | int1_ctrl.int1_boot + | int1_ctrl.int1_cnt_bdr + | int1_ctrl.int1_drdy_g + | int1_ctrl.int1_drdy_xl + | int1_ctrl.int1_fifo_full + | int1_ctrl.int1_fifo_ovr + | int1_ctrl.int1_fifo_th + | md1_cfg.int1_shub + | md1_cfg.int1_6d + | md1_cfg.int1_double_tap + | md1_cfg.int1_ff + | md1_cfg.int1_wu + | md1_cfg.int1_single_tap + | md1_cfg.int1_sleep_change) != PROPERTY_DISABLE) + { + tap_cfg2.interrupts_enable = PROPERTY_ENABLE; + } + + else + { + tap_cfg2.interrupts_enable = PROPERTY_DISABLE; + } + + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *) &tap_cfg2, 1); + } + + return ret; +} + +/** + * @brief Route interrupt signals on int1 pin.[get] + * + * @param ctx communication interface handler.(ptr) + * @param val the signals that are routed on int1 pin.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_int1_route_get(stmdev_ctx_t *ctx, + lsm6dso_pin_int1_route_t *val) +{ + lsm6dso_emb_func_int1_t emb_func_int1; + lsm6dso_fsm_int1_a_t fsm_int1_a; + lsm6dso_fsm_int1_b_t fsm_int1_b; + lsm6dso_int1_ctrl_t int1_ctrl; + lsm6dso_int2_ctrl_t int2_ctrl; + lsm6dso_md2_cfg_t md2_cfg; + lsm6dso_md1_cfg_t md1_cfg; + lsm6dso_ctrl4_c_t ctrl4_c; + int32_t ret; + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INT1, + (uint8_t *)&emb_func_int1, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT1_A, + (uint8_t *)&fsm_int1_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT1_B, + (uint8_t *)&fsm_int1_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT1_CTRL, + (uint8_t *)&int1_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MD1_CFG, (uint8_t *)&md1_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)&ctrl4_c, 1); + } + + if (ctrl4_c.int2_on_int1 == PROPERTY_ENABLE) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT2_CTRL, (uint8_t *)&int2_ctrl, 1); + val->drdy_temp = int2_ctrl.int2_drdy_temp; + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1); + val->timestamp = md2_cfg.int2_timestamp; + } + } + + else + { + val->drdy_temp = PROPERTY_DISABLE; + val->timestamp = PROPERTY_DISABLE; + } + + val->drdy_xl = int1_ctrl.int1_drdy_xl; + val->drdy_g = int1_ctrl.int1_drdy_g; + val->boot = int1_ctrl.int1_boot; + val->fifo_th = int1_ctrl.int1_fifo_th; + val->fifo_ovr = int1_ctrl.int1_fifo_ovr; + val->fifo_full = int1_ctrl.int1_fifo_full; + val->fifo_bdr = int1_ctrl.int1_cnt_bdr; + val->den_flag = int1_ctrl.den_drdy_flag; + val->sh_endop = md1_cfg.int1_shub; + val->six_d = md1_cfg.int1_6d; + val->double_tap = md1_cfg.int1_double_tap; + val->free_fall = md1_cfg.int1_ff; + val->wake_up = md1_cfg.int1_wu; + val->single_tap = md1_cfg.int1_single_tap; + val->sleep_change = md1_cfg.int1_sleep_change; + val->step_detector = emb_func_int1.int1_step_detector; + val->tilt = emb_func_int1.int1_tilt; + val->sig_mot = emb_func_int1.int1_sig_mot; + val->fsm_lc = emb_func_int1.int1_fsm_lc; + val->fsm1 = fsm_int1_a.int1_fsm1; + val->fsm2 = fsm_int1_a.int1_fsm2; + val->fsm3 = fsm_int1_a.int1_fsm3; + val->fsm4 = fsm_int1_a.int1_fsm4; + val->fsm5 = fsm_int1_a.int1_fsm5; + val->fsm6 = fsm_int1_a.int1_fsm6; + val->fsm7 = fsm_int1_a.int1_fsm7; + val->fsm8 = fsm_int1_a.int1_fsm8; + val->fsm9 = fsm_int1_b.int1_fsm9; + val->fsm10 = fsm_int1_b.int1_fsm10; + val->fsm11 = fsm_int1_b.int1_fsm11; + val->fsm12 = fsm_int1_b.int1_fsm12; + val->fsm13 = fsm_int1_b.int1_fsm13; + val->fsm14 = fsm_int1_b.int1_fsm14; + val->fsm15 = fsm_int1_b.int1_fsm15; + val->fsm16 = fsm_int1_b.int1_fsm16; + + return ret; +} + +/** + * @brief Route interrupt signals on int2 pin.[set] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val the signals to route on int2 pin. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_int2_route_set(stmdev_ctx_t *ctx, + stmdev_ctx_t *aux_ctx, + lsm6dso_pin_int2_route_t val) +{ + lsm6dso_pin_int1_route_t pin_int1_route; + lsm6dso_emb_func_int2_t emb_func_int2; + lsm6dso_fsm_int2_a_t fsm_int2_a; + lsm6dso_fsm_int2_b_t fsm_int2_b; + lsm6dso_int2_ctrl_t int2_ctrl; + lsm6dso_tap_cfg2_t tap_cfg2; + lsm6dso_md2_cfg_t md2_cfg; + lsm6dso_ctrl4_c_t ctrl4_c; + lsm6dso_int_ois_t int_ois; + int32_t ret; + ret = 0; + + if (aux_ctx != NULL) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_INT_OIS, + (uint8_t *)&int_ois, 1); + + if (ret == 0) + { + int_ois.int2_drdy_ois = val.drdy_ois; + ret = lsm6dso_write_reg(aux_ctx, LSM6DSO_INT_OIS, + (uint8_t *)&int_ois, 1); + } + } + + if (ctx != NULL) + { + int2_ctrl.int2_drdy_xl = val.drdy_xl; + int2_ctrl.int2_drdy_g = val.drdy_g; + int2_ctrl.int2_drdy_temp = val.drdy_temp; + int2_ctrl.int2_fifo_th = val.fifo_th; + int2_ctrl.int2_fifo_ovr = val.fifo_ovr; + int2_ctrl.int2_fifo_full = val.fifo_full; + int2_ctrl.int2_cnt_bdr = val.fifo_bdr; + int2_ctrl.not_used_01 = 0; + md2_cfg.int2_timestamp = val.timestamp; + md2_cfg.int2_6d = val.six_d; + md2_cfg.int2_double_tap = val.double_tap; + md2_cfg.int2_ff = val.free_fall; + md2_cfg.int2_wu = val.wake_up; + md2_cfg.int2_single_tap = val.single_tap; + md2_cfg.int2_sleep_change = val.sleep_change; + emb_func_int2.not_used_01 = 0; + emb_func_int2. int2_step_detector = val.step_detector; + emb_func_int2.int2_tilt = val.tilt; + emb_func_int2.int2_sig_mot = val.sig_mot; + emb_func_int2.not_used_02 = 0; + emb_func_int2.int2_fsm_lc = val.fsm_lc; + fsm_int2_a.int2_fsm1 = val.fsm1; + fsm_int2_a.int2_fsm2 = val.fsm2; + fsm_int2_a.int2_fsm3 = val.fsm3; + fsm_int2_a.int2_fsm4 = val.fsm4; + fsm_int2_a.int2_fsm5 = val.fsm5; + fsm_int2_a.int2_fsm6 = val.fsm6; + fsm_int2_a.int2_fsm7 = val.fsm7; + fsm_int2_a.int2_fsm8 = val.fsm8; + fsm_int2_b.int2_fsm9 = val.fsm9 ; + fsm_int2_b.int2_fsm10 = val.fsm10; + fsm_int2_b.int2_fsm11 = val.fsm11; + fsm_int2_b.int2_fsm12 = val.fsm12; + fsm_int2_b.int2_fsm13 = val.fsm13; + fsm_int2_b.int2_fsm14 = val.fsm14; + fsm_int2_b.int2_fsm15 = val.fsm15; + fsm_int2_b.int2_fsm16 = val.fsm16; + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)&ctrl4_c, 1); + + if (ret == 0) + { + if ((val.drdy_temp | val.timestamp) != PROPERTY_DISABLE) + { + ctrl4_c.int2_on_int1 = PROPERTY_DISABLE; + } + + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)&ctrl4_c, 1); + } + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_INT2, + (uint8_t *)&emb_func_int2, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT2_A, + (uint8_t *)&fsm_int2_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FSM_INT2_B, + (uint8_t *)&fsm_int2_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + if (ret == 0) + { + if ((emb_func_int2.int2_fsm_lc + | emb_func_int2.int2_sig_mot + | emb_func_int2.int2_step_detector + | emb_func_int2.int2_tilt + | fsm_int2_a.int2_fsm1 + | fsm_int2_a.int2_fsm2 + | fsm_int2_a.int2_fsm3 + | fsm_int2_a.int2_fsm4 + | fsm_int2_a.int2_fsm5 + | fsm_int2_a.int2_fsm6 + | fsm_int2_a.int2_fsm7 + | fsm_int2_a.int2_fsm8 + | fsm_int2_b.int2_fsm9 + | fsm_int2_b.int2_fsm10 + | fsm_int2_b.int2_fsm11 + | fsm_int2_b.int2_fsm12 + | fsm_int2_b.int2_fsm13 + | fsm_int2_b.int2_fsm14 + | fsm_int2_b.int2_fsm15 + | fsm_int2_b.int2_fsm16) != PROPERTY_DISABLE) + { + md2_cfg.int2_emb_func = PROPERTY_ENABLE; + } + + else + { + md2_cfg.int2_emb_func = PROPERTY_DISABLE; + } + + ret = lsm6dso_write_reg(ctx, LSM6DSO_INT2_CTRL, + (uint8_t *)&int2_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *) &tap_cfg2, 1); + } + + if (ret == 0) + { + ret = lsm6dso_pin_int1_route_get(ctx, &pin_int1_route); + } + + if (ret == 0) + { + if ((val.fifo_bdr + | val.drdy_g + | val.drdy_temp + | val.drdy_xl + | val.fifo_full + | val.fifo_ovr + | val.fifo_th + | val.six_d + | val.double_tap + | val.free_fall + | val.wake_up + | val.single_tap + | val.sleep_change + | pin_int1_route.den_flag + | pin_int1_route.boot + | pin_int1_route.fifo_bdr + | pin_int1_route.drdy_g + | pin_int1_route.drdy_xl + | pin_int1_route.fifo_full + | pin_int1_route.fifo_ovr + | pin_int1_route.fifo_th + | pin_int1_route.six_d + | pin_int1_route.double_tap + | pin_int1_route.free_fall + | pin_int1_route.wake_up + | pin_int1_route.single_tap + | pin_int1_route.sleep_change) != PROPERTY_DISABLE) + { + tap_cfg2.interrupts_enable = PROPERTY_ENABLE; + } + + else + { + tap_cfg2.interrupts_enable = PROPERTY_DISABLE; + } + + ret = lsm6dso_write_reg(ctx, LSM6DSO_TAP_CFG2, (uint8_t *) &tap_cfg2, 1); + } + } + + return ret; +} + +/** + * @brief Route interrupt signals on int2 pin.[get] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val the signals that are routed on int2 pin.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_pin_int2_route_get(stmdev_ctx_t *ctx, + stmdev_ctx_t *aux_ctx, + lsm6dso_pin_int2_route_t *val) +{ + lsm6dso_emb_func_int2_t emb_func_int2; + lsm6dso_fsm_int2_a_t fsm_int2_a; + lsm6dso_fsm_int2_b_t fsm_int2_b; + lsm6dso_int2_ctrl_t int2_ctrl; + lsm6dso_md2_cfg_t md2_cfg; + lsm6dso_ctrl4_c_t ctrl4_c; + lsm6dso_int_ois_t int_ois; + int32_t ret; + ret = 0; + + if (aux_ctx != NULL) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_INT_OIS, + (uint8_t *)&int_ois, 1); + val->drdy_ois = int_ois.int2_drdy_ois; + } + + if (ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_INT2, + (uint8_t *)&emb_func_int2, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT2_A, + (uint8_t *)&fsm_int2_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_INT2_B, + (uint8_t *)&fsm_int2_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT2_CTRL, + (uint8_t *)&int2_ctrl, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MD2_CFG, + (uint8_t *)&md2_cfg, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL4_C, (uint8_t *)&ctrl4_c, 1); + } + + if (ctrl4_c.int2_on_int1 == PROPERTY_DISABLE) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_INT2_CTRL, + (uint8_t *)&int2_ctrl, 1); + val->drdy_temp = int2_ctrl.int2_drdy_temp; + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1); + val->timestamp = md2_cfg.int2_timestamp; + } + } + + else + { + val->drdy_temp = PROPERTY_DISABLE; + val->timestamp = PROPERTY_DISABLE; + } + + val->drdy_xl = int2_ctrl.int2_drdy_xl; + val->drdy_g = int2_ctrl.int2_drdy_g; + val->drdy_temp = int2_ctrl.int2_drdy_temp; + val->fifo_th = int2_ctrl.int2_fifo_th; + val->fifo_ovr = int2_ctrl.int2_fifo_ovr; + val->fifo_full = int2_ctrl.int2_fifo_full; + val->fifo_bdr = int2_ctrl.int2_cnt_bdr; + val->timestamp = md2_cfg.int2_timestamp; + val->six_d = md2_cfg.int2_6d; + val->double_tap = md2_cfg.int2_double_tap; + val->free_fall = md2_cfg.int2_ff; + val->wake_up = md2_cfg.int2_wu; + val->single_tap = md2_cfg.int2_single_tap; + val->sleep_change = md2_cfg.int2_sleep_change; + val->step_detector = emb_func_int2. int2_step_detector; + val->tilt = emb_func_int2.int2_tilt; + val->fsm_lc = emb_func_int2.int2_fsm_lc; + val->fsm1 = fsm_int2_a.int2_fsm1; + val->fsm2 = fsm_int2_a.int2_fsm2; + val->fsm3 = fsm_int2_a.int2_fsm3; + val->fsm4 = fsm_int2_a.int2_fsm4; + val->fsm5 = fsm_int2_a.int2_fsm5; + val->fsm6 = fsm_int2_a.int2_fsm6; + val->fsm7 = fsm_int2_a.int2_fsm7; + val->fsm8 = fsm_int2_a.int2_fsm8; + val->fsm9 = fsm_int2_b.int2_fsm9; + val->fsm10 = fsm_int2_b.int2_fsm10; + val->fsm11 = fsm_int2_b.int2_fsm11; + val->fsm12 = fsm_int2_b.int2_fsm12; + val->fsm13 = fsm_int2_b.int2_fsm13; + val->fsm14 = fsm_int2_b.int2_fsm14; + val->fsm15 = fsm_int2_b.int2_fsm15; + val->fsm16 = fsm_int2_b.int2_fsm16; + } + + return ret; +} + +/** + * @brief Get the status of all the interrupt sources.[get] + * + * @param ctx communication interface handler.(ptr) + * @param val the status of all the interrupt sources.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_all_sources_get(stmdev_ctx_t *ctx, + lsm6dso_all_sources_t *val) +{ + lsm6dso_emb_func_status_mainpage_t emb_func_status_mainpage; + lsm6dso_status_master_mainpage_t status_master_mainpage; + lsm6dso_fsm_status_a_mainpage_t fsm_status_a_mainpage; + lsm6dso_fsm_status_b_mainpage_t fsm_status_b_mainpage; + lsm6dso_fifo_status1_t fifo_status1; + lsm6dso_fifo_status2_t fifo_status2; + lsm6dso_all_int_src_t all_int_src; + lsm6dso_wake_up_src_t wake_up_src; + lsm6dso_status_reg_t status_reg; + lsm6dso_tap_src_t tap_src; + lsm6dso_d6d_src_t d6d_src; + uint8_t reg[5]; + int32_t ret; + ret = lsm6dso_read_reg(ctx, LSM6DSO_ALL_INT_SRC, reg, 5); + + if (ret == 0) + { + bytecpy((uint8_t *)&all_int_src, ®[0]); + bytecpy((uint8_t *)&wake_up_src, ®[1]); + bytecpy((uint8_t *)&tap_src, ®[2]); + bytecpy((uint8_t *)&d6d_src, ®[3]); + bytecpy((uint8_t *)&status_reg, ®[4]); + val->timestamp = all_int_src.timestamp_endcount; + val->wake_up_z = wake_up_src.z_wu; + val->wake_up_y = wake_up_src.y_wu; + val->wake_up_x = wake_up_src.x_wu; + val->wake_up = wake_up_src.wu_ia; + val->sleep_state = wake_up_src.sleep_state; + val->free_fall = wake_up_src.ff_ia; + val->sleep_change = wake_up_src.sleep_change_ia; + val->tap_x = tap_src.x_tap; + val->tap_y = tap_src.y_tap; + val->tap_z = tap_src.z_tap; + val->tap_sign = tap_src.tap_sign; + val->double_tap = tap_src.double_tap; + val->single_tap = tap_src.single_tap; + val->six_d_xl = d6d_src.xl; + val->six_d_xh = d6d_src.xh; + val->six_d_yl = d6d_src.yl; + val->six_d_yh = d6d_src.yh; + val->six_d_zl = d6d_src.zl; + val->six_d_zh = d6d_src.zh; + val->six_d = d6d_src.d6d_ia; + val->den_flag = d6d_src.den_drdy; + val->drdy_xl = status_reg.xlda; + val->drdy_g = status_reg.gda; + val->drdy_temp = status_reg.tda; + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_STATUS_MAINPAGE, reg, 3); + } + + if (ret == 0) + { + bytecpy((uint8_t *)&emb_func_status_mainpage, ®[0]); + bytecpy((uint8_t *)&fsm_status_a_mainpage, ®[1]); + bytecpy((uint8_t *)&fsm_status_b_mainpage, ®[2]); + val->step_detector = emb_func_status_mainpage.is_step_det; + val->tilt = emb_func_status_mainpage.is_tilt; + val->sig_mot = emb_func_status_mainpage.is_sigmot; + val->fsm_lc = emb_func_status_mainpage.is_fsm_lc; + val->fsm1 = fsm_status_a_mainpage.is_fsm1; + val->fsm2 = fsm_status_a_mainpage.is_fsm2; + val->fsm3 = fsm_status_a_mainpage.is_fsm3; + val->fsm4 = fsm_status_a_mainpage.is_fsm4; + val->fsm5 = fsm_status_a_mainpage.is_fsm5; + val->fsm6 = fsm_status_a_mainpage.is_fsm6; + val->fsm7 = fsm_status_a_mainpage.is_fsm7; + val->fsm8 = fsm_status_a_mainpage.is_fsm8; + val->fsm9 = fsm_status_b_mainpage.is_fsm9; + val->fsm10 = fsm_status_b_mainpage.is_fsm10; + val->fsm11 = fsm_status_b_mainpage.is_fsm11; + val->fsm12 = fsm_status_b_mainpage.is_fsm12; + val->fsm13 = fsm_status_b_mainpage.is_fsm13; + val->fsm14 = fsm_status_b_mainpage.is_fsm14; + val->fsm15 = fsm_status_b_mainpage.is_fsm15; + val->fsm16 = fsm_status_b_mainpage.is_fsm16; + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_STATUS_MASTER_MAINPAGE, reg, 3); + } + + if (ret == 0) + { + bytecpy((uint8_t *)&status_master_mainpage, ®[0]); + bytecpy((uint8_t *)&fifo_status1, ®[1]); + bytecpy((uint8_t *)&fifo_status2, ®[2]); + val->sh_endop = status_master_mainpage.sens_hub_endop; + val->sh_slave0_nack = status_master_mainpage.slave0_nack; + val->sh_slave1_nack = status_master_mainpage.slave1_nack; + val->sh_slave2_nack = status_master_mainpage.slave2_nack; + val->sh_slave3_nack = status_master_mainpage.slave3_nack; + val->sh_wr_once = status_master_mainpage.wr_once_done; + val->fifo_diff = (256U * fifo_status2.diff_fifo) + + fifo_status1.diff_fifo; + val->fifo_ovr_latched = fifo_status2.over_run_latched; + val->fifo_bdr = fifo_status2.counter_bdr_ia; + val->fifo_full = fifo_status2.fifo_full_ia; + val->fifo_ovr = fifo_status2.fifo_ovr_ia; + val->fifo_th = fifo_status2.fifo_wtm_ia; + } + + return ret; +} + +/** + * @brief Sensor conversion parameters selection.[set] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val set the sensor conversion parameters by checking + * the constraints of the device.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mode_set(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_md_t *val) +{ + lsm6dso_func_cfg_access_t func_cfg_access; + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_ctrl2_ois_t ctrl2_ois; + lsm6dso_ctrl3_ois_t ctrl3_ois; + lsm6dso_ctrl1_xl_t ctrl1_xl; + lsm6dso_ctrl8_xl_t ctrl8_xl; + lsm6dso_ctrl2_g_t ctrl2_g; + lsm6dso_ctrl3_c_t ctrl3_c; + lsm6dso_ctrl4_c_t ctrl4_c; + lsm6dso_ctrl5_c_t ctrl5_c; + lsm6dso_ctrl6_c_t ctrl6_c; + lsm6dso_ctrl7_g_t ctrl7_g; + uint8_t xl_hm_mode; + uint8_t g_hm_mode; + uint8_t xl_ulp_en; + uint8_t odr_gy; + uint8_t odr_xl; + uint8_t reg[8]; + int32_t ret; + + ret = 0; + /* FIXME: Remove warnings with STM32CubeIDE */ + ctrl3_c.not_used_01 = 0; + ctrl4_c.not_used_01 = 0; + ctrl5_c.xl_ulp_en = 0; + /* reading input configuration */ + xl_hm_mode = ((uint8_t)val->ui.xl.odr & 0x10U) >> 4; + xl_ulp_en = ((uint8_t)val->ui.xl.odr & 0x20U) >> 5; + odr_xl = (uint8_t)val->ui.xl.odr & 0x0FU; + + /* if enable xl ultra low power mode disable gy and OIS chain */ + if (xl_ulp_en == PROPERTY_ENABLE) + { + val->ois.xl.odr = LSM6DSO_XL_OIS_OFF; + val->ois.gy.odr = LSM6DSO_GY_OIS_OFF; + val->ui.gy.odr = LSM6DSO_GY_UI_OFF; + } + + /* if OIS xl is enabled also gyro OIS is enabled */ + if (val->ois.xl.odr == LSM6DSO_XL_OIS_6667Hz_HP) + { + val->ois.gy.odr = LSM6DSO_GY_OIS_6667Hz_HP; + } + + g_hm_mode = ((uint8_t)val->ui.gy.odr & 0x10U) >> 4; + odr_gy = (uint8_t)val->ui.gy.odr & 0x0FU; + + /* reading registers to be configured */ + if (ctx != NULL) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, reg, 8); + bytecpy((uint8_t *)&ctrl1_xl, ®[0]); + bytecpy((uint8_t *)&ctrl2_g, ®[1]); + bytecpy((uint8_t *)&ctrl3_c, ®[2]); + bytecpy((uint8_t *)&ctrl4_c, ®[3]); + bytecpy((uint8_t *)&ctrl5_c, ®[4]); + bytecpy((uint8_t *)&ctrl6_c, ®[5]); + bytecpy((uint8_t *)&ctrl7_g, ®[6]); + bytecpy((uint8_t *)&ctrl8_xl, ®[7]); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, + (uint8_t *)&func_cfg_access, 1); + } + + /* if toggle xl ultra low power mode, turn off xl before reconfigure */ + if (ctrl5_c.xl_ulp_en != xl_ulp_en) + { + ctrl1_xl.odr_xl = (uint8_t) 0x00U; + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, + (uint8_t *)&ctrl1_xl, 1); + } + } + + /* reading OIS registers to be configured */ + if (aux_ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_CTRL1_OIS, reg, 3); + } + + bytecpy((uint8_t *)&ctrl1_ois, ®[0]); + bytecpy((uint8_t *)&ctrl2_ois, ®[1]); + bytecpy((uint8_t *)&ctrl3_ois, ®[2]); + } + + else + { + if (ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, reg, 3); + } + + bytecpy((uint8_t *)&ctrl1_ois, ®[0]); + bytecpy((uint8_t *)&ctrl2_ois, ®[1]); + bytecpy((uint8_t *)&ctrl3_ois, ®[2]); + } + } + + /* Check the Finite State Machine data rate constraints */ + if (val->fsm.sens != LSM6DSO_FSM_DISABLE) + { + switch (val->fsm.odr) + { + case LSM6DSO_FSM_12Hz5: + if ((val->fsm.sens != LSM6DSO_FSM_GY) && (odr_xl == 0x00U)) + { + odr_xl = 0x01U; + } + + if ((val->fsm.sens != LSM6DSO_FSM_XL) && (odr_gy == 0x00U)) + { + xl_ulp_en = PROPERTY_DISABLE; + odr_gy = 0x01U; + } + + break; + + case LSM6DSO_FSM_26Hz: + if ((val->fsm.sens != LSM6DSO_FSM_GY) && (odr_xl < 0x02U)) + { + odr_xl = 0x02U; + } + + if ((val->fsm.sens != LSM6DSO_FSM_XL) && (odr_gy < 0x02U)) + { + xl_ulp_en = PROPERTY_DISABLE; + odr_gy = 0x02U; + } + + break; + + case LSM6DSO_FSM_52Hz: + if ((val->fsm.sens != LSM6DSO_FSM_GY) && (odr_xl < 0x03U)) + { + odr_xl = 0x03U; + } + + if ((val->fsm.sens != LSM6DSO_FSM_XL) && (odr_gy < 0x03U)) + { + xl_ulp_en = PROPERTY_DISABLE; + odr_gy = 0x03U; + } + + break; + + case LSM6DSO_FSM_104Hz: + if ((val->fsm.sens != LSM6DSO_FSM_GY) && (odr_xl < 0x04U)) + { + odr_xl = 0x04U; + } + + if ((val->fsm.sens != LSM6DSO_FSM_XL) && (odr_gy < 0x04U)) + { + xl_ulp_en = PROPERTY_DISABLE; + odr_gy = 0x04U; + } + + break; + + default: + odr_xl = 0x00U; + odr_gy = 0x00U; + break; + } + } + + /* Updating the accelerometer data rate configuration */ + switch ((ctrl5_c.xl_ulp_en << 5) | (ctrl6_c.xl_hm_mode << 4) | + ctrl1_xl.odr_xl) + { + case LSM6DSO_XL_UI_OFF: + val->ui.xl.odr = LSM6DSO_XL_UI_OFF; + break; + + case LSM6DSO_XL_UI_12Hz5_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_12Hz5_HP; + break; + + case LSM6DSO_XL_UI_26Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_26Hz_HP; + break; + + case LSM6DSO_XL_UI_52Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_52Hz_HP; + break; + + case LSM6DSO_XL_UI_104Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_104Hz_HP; + break; + + case LSM6DSO_XL_UI_208Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_208Hz_HP; + break; + + case LSM6DSO_XL_UI_416Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_416Hz_HP; + break; + + case LSM6DSO_XL_UI_833Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_833Hz_HP; + break; + + case LSM6DSO_XL_UI_1667Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_1667Hz_HP; + break; + + case LSM6DSO_XL_UI_3333Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_3333Hz_HP; + break; + + case LSM6DSO_XL_UI_6667Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_6667Hz_HP; + break; + + case LSM6DSO_XL_UI_1Hz6_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_1Hz6_LP; + break; + + case LSM6DSO_XL_UI_12Hz5_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_12Hz5_LP; + break; + + case LSM6DSO_XL_UI_26Hz_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_26Hz_LP; + break; + + case LSM6DSO_XL_UI_52Hz_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_52Hz_LP; + break; + + case LSM6DSO_XL_UI_104Hz_NM: + val->ui.xl.odr = LSM6DSO_XL_UI_104Hz_NM; + break; + + case LSM6DSO_XL_UI_208Hz_NM: + val->ui.xl.odr = LSM6DSO_XL_UI_208Hz_NM; + break; + + case LSM6DSO_XL_UI_1Hz6_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_1Hz6_ULP; + break; + + case LSM6DSO_XL_UI_12Hz5_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_12Hz5_ULP; + break; + + case LSM6DSO_XL_UI_26Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_26Hz_ULP; + break; + + case LSM6DSO_XL_UI_52Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_52Hz_ULP; + break; + + case LSM6DSO_XL_UI_104Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_104Hz_ULP; + break; + + case LSM6DSO_XL_UI_208Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_208Hz_ULP; + break; + + default: + val->ui.xl.odr = LSM6DSO_XL_UI_OFF; + break; + } + + /* Updating the accelerometer data rate configuration */ + switch ((ctrl7_g.g_hm_mode << 4) | ctrl2_g.odr_g) + { + case LSM6DSO_GY_UI_OFF: + val->ui.gy.odr = LSM6DSO_GY_UI_OFF; + break; + + case LSM6DSO_GY_UI_12Hz5_LP: + val->ui.gy.odr = LSM6DSO_GY_UI_12Hz5_LP; + break; + + case LSM6DSO_GY_UI_12Hz5_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_12Hz5_HP; + break; + + case LSM6DSO_GY_UI_26Hz_LP: + val->ui.gy.odr = LSM6DSO_GY_UI_26Hz_LP; + break; + + case LSM6DSO_GY_UI_26Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_26Hz_HP; + break; + + case LSM6DSO_GY_UI_52Hz_LP: + val->ui.gy.odr = LSM6DSO_GY_UI_52Hz_LP; + break; + + case LSM6DSO_GY_UI_52Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_52Hz_HP; + break; + + case LSM6DSO_GY_UI_104Hz_NM: + val->ui.gy.odr = LSM6DSO_GY_UI_104Hz_NM; + break; + + case LSM6DSO_GY_UI_104Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_104Hz_HP; + break; + + case LSM6DSO_GY_UI_208Hz_NM: + val->ui.gy.odr = LSM6DSO_GY_UI_208Hz_NM; + break; + + case LSM6DSO_GY_UI_208Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_208Hz_HP; + break; + + case LSM6DSO_GY_UI_416Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_416Hz_HP; + break; + + case LSM6DSO_GY_UI_833Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_833Hz_HP; + break; + + case LSM6DSO_GY_UI_1667Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_1667Hz_HP; + break; + + case LSM6DSO_GY_UI_3333Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_3333Hz_HP; + break; + + case LSM6DSO_GY_UI_6667Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_6667Hz_HP; + break; + + default: + val->ui.gy.odr = LSM6DSO_GY_UI_OFF; + break; + } + + /* Check accelerometer full scale constraints */ + /* Full scale of 16g must be the same for UI and OIS */ + if ((val->ui.xl.fs == LSM6DSO_XL_UI_16g) || + (val->ois.xl.fs == LSM6DSO_XL_OIS_16g)) + { + val->ui.xl.fs = LSM6DSO_XL_UI_16g; + val->ois.xl.fs = LSM6DSO_XL_OIS_16g; + } + + /* prapare new configuration */ + + /* Full scale of 16g must be the same for UI and OIS */ + if (val->ui.xl.fs == LSM6DSO_XL_UI_16g) + { + ctrl8_xl.xl_fs_mode = PROPERTY_DISABLE; + } + + else + { + ctrl8_xl.xl_fs_mode = PROPERTY_ENABLE; + } + + /* OIS new configuration */ + ctrl7_g.ois_on_en = val->ois.ctrl_md & 0x01U; + + switch (val->ois.ctrl_md) + { + case LSM6DSO_OIS_ONLY_AUX: + ctrl1_ois.fs_g_ois = (uint8_t)val->ois.gy.fs; + ctrl1_ois.ois_en_spi2 = (uint8_t)val->ois.gy.odr | + (uint8_t)val->ois.xl.odr; + ctrl1_ois.mode4_en = (uint8_t) val->ois.xl.odr; + ctrl3_ois.fs_xl_ois = (uint8_t)val->ois.xl.fs; + break; + + case LSM6DSO_OIS_MIXED: + ctrl1_ois.fs_g_ois = (uint8_t)val->ois.gy.fs; + ctrl7_g.ois_on = (uint8_t)val->ois.gy.odr | (uint8_t)val->ois.xl.odr; + ctrl1_ois.mode4_en = (uint8_t) val->ois.xl.odr; + ctrl3_ois.fs_xl_ois = (uint8_t)val->ois.xl.fs; + break; + + default: + ctrl1_ois.fs_g_ois = (uint8_t)val->ois.gy.fs; + ctrl1_ois.ois_en_spi2 = (uint8_t)val->ois.gy.odr | + (uint8_t)val->ois.xl.odr; + ctrl1_ois.mode4_en = (uint8_t) val->ois.xl.odr; + ctrl3_ois.fs_xl_ois = (uint8_t)val->ois.xl.fs; + break; + } + + /* UI new configuration */ + ctrl1_xl.odr_xl = odr_xl; + ctrl1_xl.fs_xl = (uint8_t)val->ui.xl.fs; + ctrl5_c.xl_ulp_en = xl_ulp_en; + ctrl6_c.xl_hm_mode = xl_hm_mode; + ctrl7_g.g_hm_mode = g_hm_mode; + ctrl2_g.odr_g = odr_gy; + ctrl2_g.fs_g = (uint8_t) val->ui.gy.fs; + + /* writing checked configuration */ + if (ctx != NULL) + { + bytecpy(®[0], (uint8_t *)&ctrl1_xl); + bytecpy(®[1], (uint8_t *)&ctrl2_g); + bytecpy(®[2], (uint8_t *)&ctrl3_c); + bytecpy(®[3], (uint8_t *)&ctrl4_c); + bytecpy(®[4], (uint8_t *)&ctrl5_c); + bytecpy(®[5], (uint8_t *)&ctrl6_c); + bytecpy(®[6], (uint8_t *)&ctrl7_g); + bytecpy(®[7], (uint8_t *)&ctrl8_xl); + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_CTRL1_XL, (uint8_t *)®, 8); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, + (uint8_t *)&func_cfg_access, 1); + } + } + + /* writing OIS checked configuration */ + if (aux_ctx != NULL) + { + bytecpy(®[0], (uint8_t *)&ctrl1_ois); + bytecpy(®[1], (uint8_t *)&ctrl2_ois); + bytecpy(®[2], (uint8_t *)&ctrl3_ois); + + if (ret == 0) + { + ret = lsm6dso_write_reg(aux_ctx, LSM6DSO_CTRL1_OIS, reg, 3); + } + } + + return ret; +} + +/** + * @brief Sensor conversion parameters selection.[get] + * + * @param ctx communication interface handler. Use NULL to ignore + * this interface.(ptr) + * @param aux_ctx auxiliary communication interface handler. Use NULL + * to ignore this interface.(ptr) + * @param val get the sensor conversion parameters.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_mode_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_md_t *val) +{ + lsm6dso_emb_func_odr_cfg_b_t emb_func_odr_cfg_b; + lsm6dso_func_cfg_access_t func_cfg_access; + lsm6dso_emb_func_en_b_t emb_func_en_b; + lsm6dso_fsm_enable_a_t fsm_enable_a; + lsm6dso_fsm_enable_b_t fsm_enable_b; + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_ctrl2_ois_t ctrl2_ois; + lsm6dso_ctrl3_ois_t ctrl3_ois; + lsm6dso_ctrl1_xl_t ctrl1_xl; + lsm6dso_ctrl2_g_t ctrl2_g; + lsm6dso_ctrl3_c_t ctrl3_c; + lsm6dso_ctrl4_c_t ctrl4_c; + lsm6dso_ctrl5_c_t ctrl5_c; + lsm6dso_ctrl6_c_t ctrl6_c; + lsm6dso_ctrl7_g_t ctrl7_g; + uint8_t reg[8]; + int32_t ret; + + ret = 0; + + /* reading the registers of the device */ + if (ctx != NULL) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_XL, reg, 7); + bytecpy((uint8_t *)&ctrl1_xl, ®[0]); + bytecpy((uint8_t *)&ctrl2_g, ®[1]); + bytecpy((uint8_t *)&ctrl3_c, ®[2]); + bytecpy((uint8_t *)&ctrl4_c, ®[3]); + bytecpy((uint8_t *)&ctrl5_c, ®[4]); + bytecpy((uint8_t *)&ctrl6_c, ®[5]); + bytecpy((uint8_t *)&ctrl7_g, ®[6]); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FUNC_CFG_ACCESS, + (uint8_t *)&func_cfg_access, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_ODR_CFG_B, reg, 1); + bytecpy((uint8_t *)&emb_func_odr_cfg_b, ®[0]); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, + (uint8_t *)&emb_func_en_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_FSM_ENABLE_A, reg, 2); + bytecpy((uint8_t *)&fsm_enable_a, ®[0]); + bytecpy((uint8_t *)&fsm_enable_b, ®[1]); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + } + + if (aux_ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_CTRL1_OIS, reg, 3); + } + + bytecpy((uint8_t *)&ctrl1_ois, ®[0]); + bytecpy((uint8_t *)&ctrl2_ois, ®[1]); + bytecpy((uint8_t *)&ctrl3_ois, ®[2]); + } + + else + { + if (ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_CTRL1_OIS, reg, 3); + } + + bytecpy((uint8_t *)&ctrl1_ois, ®[0]); + bytecpy((uint8_t *)&ctrl2_ois, ®[1]); + bytecpy((uint8_t *)&ctrl3_ois, ®[2]); + } + } + + /* fill the input structure */ + + /* get accelerometer configuration */ + switch ((ctrl5_c.xl_ulp_en << 5) | (ctrl6_c.xl_hm_mode << 4) | + ctrl1_xl.odr_xl) + { + case LSM6DSO_XL_UI_OFF: + val->ui.xl.odr = LSM6DSO_XL_UI_OFF; + break; + + case LSM6DSO_XL_UI_12Hz5_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_12Hz5_HP; + break; + + case LSM6DSO_XL_UI_26Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_26Hz_HP; + break; + + case LSM6DSO_XL_UI_52Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_52Hz_HP; + break; + + case LSM6DSO_XL_UI_104Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_104Hz_HP; + break; + + case LSM6DSO_XL_UI_208Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_208Hz_HP; + break; + + case LSM6DSO_XL_UI_416Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_416Hz_HP; + break; + + case LSM6DSO_XL_UI_833Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_833Hz_HP; + break; + + case LSM6DSO_XL_UI_1667Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_1667Hz_HP; + break; + + case LSM6DSO_XL_UI_3333Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_3333Hz_HP; + break; + + case LSM6DSO_XL_UI_6667Hz_HP: + val->ui.xl.odr = LSM6DSO_XL_UI_6667Hz_HP; + break; + + case LSM6DSO_XL_UI_1Hz6_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_1Hz6_LP; + break; + + case LSM6DSO_XL_UI_12Hz5_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_12Hz5_LP; + break; + + case LSM6DSO_XL_UI_26Hz_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_26Hz_LP; + break; + + case LSM6DSO_XL_UI_52Hz_LP: + val->ui.xl.odr = LSM6DSO_XL_UI_52Hz_LP; + break; + + case LSM6DSO_XL_UI_104Hz_NM: + val->ui.xl.odr = LSM6DSO_XL_UI_104Hz_NM; + break; + + case LSM6DSO_XL_UI_208Hz_NM: + val->ui.xl.odr = LSM6DSO_XL_UI_208Hz_NM; + break; + + case LSM6DSO_XL_UI_1Hz6_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_1Hz6_ULP; + break; + + case LSM6DSO_XL_UI_12Hz5_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_12Hz5_ULP; + break; + + case LSM6DSO_XL_UI_26Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_26Hz_ULP; + break; + + case LSM6DSO_XL_UI_52Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_52Hz_ULP; + break; + + case LSM6DSO_XL_UI_104Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_104Hz_ULP; + break; + + case LSM6DSO_XL_UI_208Hz_ULP: + val->ui.xl.odr = LSM6DSO_XL_UI_208Hz_ULP; + break; + + default: + val->ui.xl.odr = LSM6DSO_XL_UI_OFF; + break; + } + + switch (ctrl1_xl.fs_xl) + { + case LSM6DSO_XL_UI_2g: + val->ui.xl.fs = LSM6DSO_XL_UI_2g; + break; + + case LSM6DSO_XL_UI_4g: + val->ui.xl.fs = LSM6DSO_XL_UI_4g; + break; + + case LSM6DSO_XL_UI_8g: + val->ui.xl.fs = LSM6DSO_XL_UI_8g; + break; + + case LSM6DSO_XL_UI_16g: + val->ui.xl.fs = LSM6DSO_XL_UI_16g; + break; + + default: + val->ui.xl.fs = LSM6DSO_XL_UI_2g; + break; + } + + /* get gyroscope configuration */ + switch ((ctrl7_g.g_hm_mode << 4) | ctrl2_g.odr_g) + { + case LSM6DSO_GY_UI_OFF: + val->ui.gy.odr = LSM6DSO_GY_UI_OFF; + break; + + case LSM6DSO_GY_UI_12Hz5_LP: + val->ui.gy.odr = LSM6DSO_GY_UI_12Hz5_LP; + break; + + case LSM6DSO_GY_UI_12Hz5_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_12Hz5_HP; + break; + + case LSM6DSO_GY_UI_26Hz_LP: + val->ui.gy.odr = LSM6DSO_GY_UI_26Hz_LP; + break; + + case LSM6DSO_GY_UI_26Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_26Hz_HP; + break; + + case LSM6DSO_GY_UI_52Hz_LP: + val->ui.gy.odr = LSM6DSO_GY_UI_52Hz_LP; + break; + + case LSM6DSO_GY_UI_52Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_52Hz_HP; + break; + + case LSM6DSO_GY_UI_104Hz_NM: + val->ui.gy.odr = LSM6DSO_GY_UI_104Hz_NM; + break; + + case LSM6DSO_GY_UI_104Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_104Hz_HP; + break; + + case LSM6DSO_GY_UI_208Hz_NM: + val->ui.gy.odr = LSM6DSO_GY_UI_208Hz_NM; + break; + + case LSM6DSO_GY_UI_208Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_208Hz_HP; + break; + + case LSM6DSO_GY_UI_416Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_416Hz_HP; + break; + + case LSM6DSO_GY_UI_833Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_833Hz_HP; + break; + + case LSM6DSO_GY_UI_1667Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_1667Hz_HP; + break; + + case LSM6DSO_GY_UI_3333Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_3333Hz_HP; + break; + + case LSM6DSO_GY_UI_6667Hz_HP: + val->ui.gy.odr = LSM6DSO_GY_UI_6667Hz_HP; + break; + + default: + val->ui.gy.odr = LSM6DSO_GY_UI_OFF; + break; + } + + switch (ctrl2_g.fs_g) + { + case LSM6DSO_GY_UI_125dps: + val->ui.gy.fs = LSM6DSO_GY_UI_125dps; + break; + + case LSM6DSO_GY_UI_250dps: + val->ui.gy.fs = LSM6DSO_GY_UI_250dps; + break; + + case LSM6DSO_GY_UI_500dps: + val->ui.gy.fs = LSM6DSO_GY_UI_500dps; + break; + + case LSM6DSO_GY_UI_1000dps: + val->ui.gy.fs = LSM6DSO_GY_UI_1000dps; + break; + + case LSM6DSO_GY_UI_2000dps: + val->ui.gy.fs = LSM6DSO_GY_UI_2000dps; + break; + + default: + val->ui.gy.fs = LSM6DSO_GY_UI_125dps; + break; + } + + /* get finite state machine configuration */ + if ((fsm_enable_a.fsm1_en | fsm_enable_a.fsm2_en | + fsm_enable_a.fsm3_en | + fsm_enable_a.fsm4_en | fsm_enable_a.fsm5_en | fsm_enable_a.fsm6_en | + fsm_enable_a.fsm7_en | fsm_enable_a.fsm8_en | fsm_enable_b.fsm9_en | + fsm_enable_b.fsm10_en | fsm_enable_b.fsm11_en | + fsm_enable_b.fsm12_en | fsm_enable_b.fsm13_en | + fsm_enable_b.fsm14_en | fsm_enable_b.fsm15_en | + fsm_enable_b.fsm16_en) == PROPERTY_ENABLE) + { + switch (emb_func_odr_cfg_b.fsm_odr) + { + case LSM6DSO_FSM_12Hz5: + val->fsm.odr = LSM6DSO_FSM_12Hz5; + break; + + case LSM6DSO_FSM_26Hz: + val->fsm.odr = LSM6DSO_FSM_26Hz; + break; + + case LSM6DSO_FSM_52Hz: + val->fsm.odr = LSM6DSO_FSM_52Hz; + break; + + case LSM6DSO_FSM_104Hz: + val->fsm.odr = LSM6DSO_FSM_104Hz; + break; + + default: + val->fsm.odr = LSM6DSO_FSM_12Hz5; + break; + } + + val->fsm.sens = LSM6DSO_FSM_XL_GY; + + if (val->ui.gy.odr == LSM6DSO_GY_UI_OFF) + { + val->fsm.sens = LSM6DSO_FSM_XL; + } + + if (val->ui.xl.odr == LSM6DSO_XL_UI_OFF) + { + val->fsm.sens = LSM6DSO_FSM_GY; + } + } + + else + { + val->fsm.sens = LSM6DSO_FSM_DISABLE; + } + + /* get ois configuration */ + + /* OIS configuration mode */ + switch (ctrl7_g.ois_on_en) + { + case LSM6DSO_OIS_ONLY_AUX: + switch (ctrl3_ois.fs_xl_ois) + { + case LSM6DSO_XL_OIS_2g: + val->ois.xl.fs = LSM6DSO_XL_OIS_2g; + break; + + case LSM6DSO_XL_OIS_4g: + val->ois.xl.fs = LSM6DSO_XL_OIS_4g; + break; + + case LSM6DSO_XL_OIS_8g: + val->ois.xl.fs = LSM6DSO_XL_OIS_8g; + break; + + case LSM6DSO_XL_OIS_16g: + val->ois.xl.fs = LSM6DSO_XL_OIS_16g; + break; + + default: + val->ois.xl.fs = LSM6DSO_XL_OIS_2g; + break; + } + + switch (ctrl1_ois.mode4_en) + { + case LSM6DSO_XL_OIS_OFF: + val->ois.xl.odr = LSM6DSO_XL_OIS_OFF; + break; + + case LSM6DSO_XL_OIS_6667Hz_HP: + val->ois.xl.odr = LSM6DSO_XL_OIS_6667Hz_HP; + break; + + default: + val->ois.xl.odr = LSM6DSO_XL_OIS_OFF; + break; + } + + switch (ctrl1_ois.fs_g_ois) + { + case LSM6DSO_GY_OIS_250dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_250dps; + break; + + case LSM6DSO_GY_OIS_500dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_500dps; + break; + + case LSM6DSO_GY_OIS_1000dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_1000dps; + break; + + case LSM6DSO_GY_OIS_2000dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_2000dps; + break; + + default: + val->ois.gy.fs = LSM6DSO_GY_OIS_250dps; + break; + } + + switch (ctrl1_ois.ois_en_spi2) + { + case LSM6DSO_GY_OIS_OFF: + val->ois.gy.odr = LSM6DSO_GY_OIS_OFF; + break; + + case LSM6DSO_GY_OIS_6667Hz_HP: + val->ois.gy.odr = LSM6DSO_GY_OIS_6667Hz_HP; + break; + + default: + val->ois.gy.odr = LSM6DSO_GY_OIS_OFF; + break; + } + + val->ois.ctrl_md = LSM6DSO_OIS_ONLY_AUX; + break; + + case LSM6DSO_OIS_MIXED: + switch (ctrl3_ois.fs_xl_ois) + { + case LSM6DSO_XL_OIS_2g: + val->ois.xl.fs = LSM6DSO_XL_OIS_2g; + break; + + case LSM6DSO_XL_OIS_4g: + val->ois.xl.fs = LSM6DSO_XL_OIS_4g; + break; + + case LSM6DSO_XL_OIS_8g: + val->ois.xl.fs = LSM6DSO_XL_OIS_8g; + break; + + case LSM6DSO_XL_OIS_16g: + val->ois.xl.fs = LSM6DSO_XL_OIS_16g; + break; + + default: + val->ois.xl.fs = LSM6DSO_XL_OIS_2g; + break; + } + + switch (ctrl1_ois.mode4_en) + { + case LSM6DSO_XL_OIS_OFF: + val->ois.xl.odr = LSM6DSO_XL_OIS_OFF; + break; + + case LSM6DSO_XL_OIS_6667Hz_HP: + val->ois.xl.odr = LSM6DSO_XL_OIS_6667Hz_HP; + break; + + default: + val->ois.xl.odr = LSM6DSO_XL_OIS_OFF; + break; + } + + switch (ctrl1_ois.fs_g_ois) + { + case LSM6DSO_GY_OIS_250dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_250dps; + break; + + case LSM6DSO_GY_OIS_500dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_500dps; + break; + + case LSM6DSO_GY_OIS_1000dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_1000dps; + break; + + case LSM6DSO_GY_OIS_2000dps: + val->ois.gy.fs = LSM6DSO_GY_OIS_2000dps; + break; + + default: + val->ois.gy.fs = LSM6DSO_GY_OIS_250dps; + break; + } + + switch (ctrl1_ois.ois_en_spi2) + { + case LSM6DSO_GY_OIS_OFF: + val->ois.gy.odr = LSM6DSO_GY_OIS_OFF; + break; + + case LSM6DSO_GY_OIS_6667Hz_HP: + val->ois.gy.odr = LSM6DSO_GY_OIS_6667Hz_HP; + break; + + default: + val->ois.gy.odr = LSM6DSO_GY_OIS_OFF; + break; + } + + val->ois.ctrl_md = LSM6DSO_OIS_MIXED; + break; + + default: + ctrl1_ois.fs_g_ois = (uint8_t)val->ois.gy.fs; + ctrl1_ois.ois_en_spi2 = (uint8_t)val->ois.gy.odr | + (uint8_t)val->ois.xl.odr; + ctrl1_ois.mode4_en = (uint8_t) val->ois.xl.odr; + ctrl3_ois.fs_xl_ois = (uint8_t)val->ois.xl.fs; + val->ois.ctrl_md = LSM6DSO_OIS_ONLY_AUX; + break; + } + + return ret; +} + +/** + * @brief Read data in engineering unit.[get] + * + * @param ctx communication interface handler.(ptr) + * @param md the sensor conversion parameters.(ptr) + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_data_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_md_t *md, lsm6dso_data_t *data) +{ + uint8_t buff[14]; + int32_t ret; + + uint8_t i; + uint8_t j; + ret = 0; + + /* read data */ + if (ctx != NULL) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_OUT_TEMP_L, buff, 14); + } + + j = 0; + /* temperature conversion */ + data->ui.heat.raw = (int16_t)buff[j + 1U]; + data->ui.heat.raw = (((int16_t)data->ui.heat.raw * (int16_t)256) + + (int16_t)buff[j]); + j += 2U; + data->ui.heat.deg_c = lsm6dso_from_lsb_to_celsius(( + int16_t)data->ui.heat.raw); + + /* angular rate conversion */ + for (i = 0U; i < 3U; i++) + { + data->ui.gy.raw[i] = (int16_t)buff[j + 1U]; + data->ui.gy.raw[i] = (data->ui.gy.raw[i] * 256) + (int16_t) buff[j]; + j += 2U; + + switch (md->ui.gy.fs) + { + case LSM6DSO_GY_UI_250dps: + data->ui.gy.mdps[i] = lsm6dso_from_fs250_to_mdps(data->ui.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_125dps: + data->ui.gy.mdps[i] = lsm6dso_from_fs125_to_mdps(data->ui.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_500dps: + data->ui.gy.mdps[i] = lsm6dso_from_fs500_to_mdps(data->ui.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_1000dps: + data->ui.gy.mdps[i] = lsm6dso_from_fs1000_to_mdps(data->ui.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_2000dps: + data->ui.gy.mdps[i] = lsm6dso_from_fs2000_to_mdps(data->ui.gy.raw[i]); + break; + + default: + data->ui.gy.mdps[i] = 0.0f; + break; + } + } + + /* acceleration conversion */ + for (i = 0U; i < 3U; i++) + { + data->ui.xl.raw[i] = (int16_t)buff[j + 1U]; + data->ui.xl.raw[i] = (data->ui.xl.raw[i] * 256) + (int16_t) buff[j]; + j += 2U; + + switch (md->ui.xl.fs) + { + case LSM6DSO_XL_UI_2g: + data->ui.xl.mg[i] = lsm6dso_from_fs2_to_mg(data->ui.xl.raw[i]); + break; + + case LSM6DSO_XL_UI_4g: + data->ui.xl.mg[i] = lsm6dso_from_fs4_to_mg(data->ui.xl.raw[i]); + break; + + case LSM6DSO_XL_UI_8g: + data->ui.xl.mg[i] = lsm6dso_from_fs8_to_mg(data->ui.xl.raw[i]); + break; + + case LSM6DSO_XL_UI_16g: + data->ui.xl.mg[i] = lsm6dso_from_fs16_to_mg(data->ui.xl.raw[i]); + break; + + default: + data->ui.xl.mg[i] = 0.0f; + break; + } + } + + /* read data from ois chain */ + if (aux_ctx != NULL) + { + if (ret == 0) + { + ret = lsm6dso_read_reg(aux_ctx, LSM6DSO_OUTX_L_G, buff, 12); + } + } + + j = 0; + + /* ois angular rate conversion */ + for (i = 0U; i < 3U; i++) + { + data->ois.gy.raw[i] = (int16_t) buff[j + 1U]; + data->ois.gy.raw[i] = (data->ois.gy.raw[i] * 256) + (int16_t) buff[j]; + j += 2U; + + switch (md->ois.gy.fs) + { + case LSM6DSO_GY_UI_250dps: + data->ois.gy.mdps[i] = lsm6dso_from_fs250_to_mdps( + data->ois.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_125dps: + data->ois.gy.mdps[i] = lsm6dso_from_fs125_to_mdps( + data->ois.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_500dps: + data->ois.gy.mdps[i] = lsm6dso_from_fs500_to_mdps( + data->ois.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_1000dps: + data->ois.gy.mdps[i] = lsm6dso_from_fs1000_to_mdps( + data->ois.gy.raw[i]); + break; + + case LSM6DSO_GY_UI_2000dps: + data->ois.gy.mdps[i] = lsm6dso_from_fs2000_to_mdps( + data->ois.gy.raw[i]); + break; + + default: + data->ois.gy.mdps[i] = 0.0f; + break; + } + } + + /* ois acceleration conversion */ + for (i = 0U; i < 3U; i++) + { + data->ois.xl.raw[i] = (int16_t) buff[j + 1U]; + data->ois.xl.raw[i] = (data->ois.xl.raw[i] * 256) + (int16_t) buff[j]; + j += 2U; + + switch (md->ois.xl.fs) + { + case LSM6DSO_XL_UI_2g: + data->ois.xl.mg[i] = lsm6dso_from_fs2_to_mg(data->ois.xl.raw[i]); + break; + + case LSM6DSO_XL_UI_4g: + data->ois.xl.mg[i] = lsm6dso_from_fs4_to_mg(data->ois.xl.raw[i]); + break; + + case LSM6DSO_XL_UI_8g: + data->ois.xl.mg[i] = lsm6dso_from_fs8_to_mg(data->ois.xl.raw[i]); + break; + + case LSM6DSO_XL_UI_16g: + data->ois.xl.mg[i] = lsm6dso_from_fs16_to_mg(data->ois.xl.raw[i]); + break; + + default: + data->ois.xl.mg[i] = 0.0f; + break; + } + } + + return ret; +} + +/** + * @brief Embedded functions.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of registers + * EMB_FUNC_EN_A e EMB_FUNC_EN_B. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_embedded_sens_set(stmdev_ctx_t *ctx, + lsm6dso_emb_sens_t *val) +{ + lsm6dso_emb_func_en_a_t emb_func_en_a; + lsm6dso_emb_func_en_b_t emb_func_en_b; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, + (uint8_t *)&emb_func_en_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, + (uint8_t *)&emb_func_en_b, 1); + emb_func_en_b.fsm_en = val->fsm; + emb_func_en_a.tilt_en = val->tilt; + emb_func_en_a.pedo_en = val->step; + emb_func_en_b.pedo_adv_en = val->step_adv; + emb_func_en_a.sign_motion_en = val->sig_mot; + emb_func_en_b.fifo_compr_en = val->fifo_compr; + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, + (uint8_t *)&emb_func_en_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, + (uint8_t *)&emb_func_en_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief Embedded functions.[get] + * + * @param ctx read / write interface definitions + * @param val get the values of registers + * EMB_FUNC_EN_A e EMB_FUNC_EN_B. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_embedded_sens_get(stmdev_ctx_t *ctx, + lsm6dso_emb_sens_t *emb_sens) +{ + lsm6dso_emb_func_en_a_t emb_func_en_a; + lsm6dso_emb_func_en_b_t emb_func_en_b; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, + (uint8_t *)&emb_func_en_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, + (uint8_t *)&emb_func_en_b, 1); + emb_sens->fsm = emb_func_en_b.fsm_en; + emb_sens->tilt = emb_func_en_a.tilt_en; + emb_sens->step = emb_func_en_a.pedo_en; + emb_sens->step_adv = emb_func_en_b.pedo_adv_en; + emb_sens->sig_mot = emb_func_en_a.sign_motion_en; + emb_sens->fifo_compr = emb_func_en_b.fifo_compr_en; + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @brief turn off all embedded functions.[get] + * + * @param ctx read / write interface definitions + * @param val get the values of registers + * EMB_FUNC_EN_A e EMB_FUNC_EN_B. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lsm6dso_embedded_sens_off(stmdev_ctx_t *ctx) +{ + lsm6dso_emb_func_en_a_t emb_func_en_a; + lsm6dso_emb_func_en_b_t emb_func_en_b; + int32_t ret; + + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_EMBEDDED_FUNC_BANK); + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, + (uint8_t *)&emb_func_en_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_read_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, + (uint8_t *)&emb_func_en_b, 1); + emb_func_en_b.fsm_en = PROPERTY_DISABLE; + emb_func_en_a.tilt_en = PROPERTY_DISABLE; + emb_func_en_a.pedo_en = PROPERTY_DISABLE; + emb_func_en_b.pedo_adv_en = PROPERTY_DISABLE; + emb_func_en_a.sign_motion_en = PROPERTY_DISABLE; + emb_func_en_b.fifo_compr_en = PROPERTY_DISABLE; + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_A, + (uint8_t *)&emb_func_en_a, 1); + } + + if (ret == 0) + { + ret = lsm6dso_write_reg(ctx, LSM6DSO_EMB_FUNC_EN_B, + (uint8_t *)&emb_func_en_b, 1); + } + + if (ret == 0) + { + ret = lsm6dso_mem_bank_set(ctx, LSM6DSO_USER_BANK); + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @} + * + */ diff --git a/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.h b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.h new file mode 100644 index 00000000000..b72f6232748 --- /dev/null +++ b/non_catalog_apps/airmouse/lib/lsm6dso-api/lsm6dso_reg.h @@ -0,0 +1,4486 @@ +/** + ****************************************************************************** + * @file lsm6dso_reg.h + * @author Sensors Software Solution Team + * @brief This file contains all the functions prototypes for the + * lsm6dso_reg.c driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef LSM6DSO_REGS_H +#define LSM6DSO_REGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include + +/** @addtogroup LSM6DSO + * @{ + * + */ + +/** @defgroup Endianness definitions + * @{ + * + */ + +#ifndef DRV_BYTE_ORDER +#ifndef __BYTE_ORDER__ + +#define DRV_LITTLE_ENDIAN 1234 +#define DRV_BIG_ENDIAN 4321 + +/** if _BYTE_ORDER is not defined, choose the endianness of your architecture + * by uncommenting the define which fits your platform endianness + */ +//#define DRV_BYTE_ORDER DRV_BIG_ENDIAN +#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN + +#else /* defined __BYTE_ORDER__ */ + +#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#define DRV_BYTE_ORDER __BYTE_ORDER__ + +#endif /* __BYTE_ORDER__*/ +#endif /* DRV_BYTE_ORDER */ + +/** + * @} + * + */ + +/** @defgroup STMicroelectronics sensors common types + * @{ + * + */ + +#ifndef MEMS_SHARED_TYPES +#define MEMS_SHARED_TYPES + +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} bitwise_t; + +#define PROPERTY_DISABLE (0U) +#define PROPERTY_ENABLE (1U) + +/** @addtogroup Interfaces_Functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +typedef int32_t (*stmdev_write_ptr)(void *, uint8_t, uint8_t *, uint16_t); +typedef int32_t (*stmdev_read_ptr)(void *, uint8_t, uint8_t *, uint16_t); +typedef void (*stmdev_mdelay_ptr)(uint32_t millisec); + +typedef struct +{ + /** Component mandatory fields **/ + stmdev_write_ptr write_reg; + stmdev_read_ptr read_reg; + /** Component optional fields **/ + stmdev_mdelay_ptr mdelay; + /** Customizable optional pointer **/ + void *handle; +} stmdev_ctx_t; + +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ + +/* + * These are the basic platform dependent I/O routines to read + * and write device registers connected on a standard bus. + * The driver keeps offering a default implementation based on function + * pointers to read/write routines for backward compatibility. + * The __weak directive allows the final application to overwrite + * them with a custom implementation. + */ +int32_t lsm6dso_read_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len); +int32_t lsm6dso_write_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len); + +/** + * @} + * + */ + +#endif /* MEMS_SHARED_TYPES */ + +#ifndef MEMS_UCF_SHARED_TYPES +#define MEMS_UCF_SHARED_TYPES + +/** @defgroup Generic address-data structure definition + * @brief This structure is useful to load a predefined configuration + * of a sensor. + * You can create a sensor configuration by your own or using + * Unico / Unicleo tools available on STMicroelectronics + * web site. + * + * @{ + * + */ + +typedef struct +{ + uint8_t address; + uint8_t data; +} ucf_line_t; + +/** + * @} + * + */ + +#endif /* MEMS_UCF_SHARED_TYPES */ + +/** + * @} + * + */ + +/** @defgroup LSM6DSO_Infos + * @{ + * + */ + +/** I2C Device Address 8 bit format if SA0=0 -> D5 if SA0=1 -> D7 **/ +#define LSM6DSO_I2C_ADD_L 0xD5 +#define LSM6DSO_I2C_ADD_H 0xD7 + +/** Device Identification (Who am I) **/ +#define LSM6DSO_ID 0x6C + +/** + * @} + * + */ + +#define LSM6DSO_FUNC_CFG_ACCESS 0x01U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 6; +uint8_t reg_access : + 2; /* shub_reg_access + func_cfg_access */ +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN +uint8_t reg_access : + 2; /* shub_reg_access + func_cfg_access */ + uint8_t not_used_01 : 6; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_func_cfg_access_t; + +#define LSM6DSO_PIN_CTRL 0x02U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 6; + uint8_t sdo_pu_en : 1; + uint8_t ois_pu_dis : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ois_pu_dis : 1; + uint8_t sdo_pu_en : 1; + uint8_t not_used_01 : 6; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_pin_ctrl_t; + +#define LSM6DSO_FIFO_CTRL1 0x07U +typedef struct +{ + uint8_t wtm : 8; +} lsm6dso_fifo_ctrl1_t; + +#define LSM6DSO_FIFO_CTRL2 0x08U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wtm : 1; + uint8_t uncoptr_rate : 2; + uint8_t not_used_01 : 1; + uint8_t odrchg_en : 1; + uint8_t not_used_02 : 1; + uint8_t fifo_compr_rt_en : 1; + uint8_t stop_on_wtm : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t stop_on_wtm : 1; + uint8_t fifo_compr_rt_en : 1; + uint8_t not_used_02 : 1; + uint8_t odrchg_en : 1; + uint8_t not_used_01 : 1; + uint8_t uncoptr_rate : 2; + uint8_t wtm : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fifo_ctrl2_t; + +#define LSM6DSO_FIFO_CTRL3 0x09U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bdr_xl : 4; + uint8_t bdr_gy : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bdr_gy : 4; + uint8_t bdr_xl : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fifo_ctrl3_t; + +#define LSM6DSO_FIFO_CTRL4 0x0AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fifo_mode : 3; + uint8_t not_used_01 : 1; + uint8_t odr_t_batch : 2; + uint8_t odr_ts_batch : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_ts_batch : 2; + uint8_t odr_t_batch : 2; + uint8_t not_used_01 : 1; + uint8_t fifo_mode : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fifo_ctrl4_t; + +#define LSM6DSO_COUNTER_BDR_REG1 0x0BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t cnt_bdr_th : 3; + uint8_t not_used_01 : 2; + uint8_t trig_counter_bdr : 1; + uint8_t rst_counter_bdr : 1; + uint8_t dataready_pulsed : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t dataready_pulsed : 1; + uint8_t rst_counter_bdr : 1; + uint8_t trig_counter_bdr : 1; + uint8_t not_used_01 : 2; + uint8_t cnt_bdr_th : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_counter_bdr_reg1_t; + +#define LSM6DSO_COUNTER_BDR_REG2 0x0CU +typedef struct +{ + uint8_t cnt_bdr_th : 8; +} lsm6dso_counter_bdr_reg2_t; + +#define LSM6DSO_INT1_CTRL 0x0D +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_drdy_xl : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_boot : 1; + uint8_t int1_fifo_th : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_fifo_full : 1; + uint8_t int1_cnt_bdr : 1; + uint8_t den_drdy_flag : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_drdy_flag : 1; + uint8_t int1_cnt_bdr : 1; + uint8_t int1_fifo_full : 1; + uint8_t int1_fifo_ovr : 1; + uint8_t int1_fifo_th : 1; + uint8_t int1_boot : 1; + uint8_t int1_drdy_g : 1; + uint8_t int1_drdy_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_int1_ctrl_t; + +#define LSM6DSO_INT2_CTRL 0x0EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_drdy_xl : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_fifo_th : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_fifo_full : 1; + uint8_t int2_cnt_bdr : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t int2_cnt_bdr : 1; + uint8_t int2_fifo_full : 1; + uint8_t int2_fifo_ovr : 1; + uint8_t int2_fifo_th : 1; + uint8_t int2_drdy_temp : 1; + uint8_t int2_drdy_g : 1; + uint8_t int2_drdy_xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_int2_ctrl_t; + +#define LSM6DSO_WHO_AM_I 0x0FU +#define LSM6DSO_CTRL1_XL 0x10U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t lpf2_xl_en : 1; + uint8_t fs_xl : 2; + uint8_t odr_xl : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_xl : 4; + uint8_t fs_xl : 2; + uint8_t lpf2_xl_en : 1; + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl1_xl_t; + +#define LSM6DSO_CTRL2_G 0x11U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t fs_g : 3; /* fs_125 + fs_g */ + uint8_t odr_g : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr_g : 4; + uint8_t fs_g : 3; /* fs_125 + fs_g */ + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl2_g_t; + +#define LSM6DSO_CTRL3_C 0x12U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sw_reset : 1; + uint8_t not_used_01 : 1; + uint8_t if_inc : 1; + uint8_t sim : 1; + uint8_t pp_od : 1; + uint8_t h_lactive : 1; + uint8_t bdu : 1; + uint8_t boot : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t boot : 1; + uint8_t bdu : 1; + uint8_t h_lactive : 1; + uint8_t pp_od : 1; + uint8_t sim : 1; + uint8_t if_inc : 1; + uint8_t not_used_01 : 1; + uint8_t sw_reset : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl3_c_t; + +#define LSM6DSO_CTRL4_C 0x13U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t lpf1_sel_g : 1; + uint8_t i2c_disable : 1; + uint8_t drdy_mask : 1; + uint8_t not_used_02 : 1; + uint8_t int2_on_int1 : 1; + uint8_t sleep_g : 1; + uint8_t not_used_03 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_03 : 1; + uint8_t sleep_g : 1; + uint8_t int2_on_int1 : 1; + uint8_t not_used_02 : 1; + uint8_t drdy_mask : 1; + uint8_t i2c_disable : 1; + uint8_t lpf1_sel_g : 1; + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl4_c_t; + +#define LSM6DSO_CTRL5_C 0x14U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t st_xl : 2; + uint8_t st_g : 2; + uint8_t not_used_01 : 1; + uint8_t rounding : 2; + uint8_t xl_ulp_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t xl_ulp_en : 1; + uint8_t rounding : 2; + uint8_t not_used_01 : 1; + uint8_t st_g : 2; + uint8_t st_xl : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl5_c_t; + +#define LSM6DSO_CTRL6_C 0x15U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ftype : 3; + uint8_t usr_off_w : 1; + uint8_t xl_hm_mode : 1; +uint8_t den_mode : + 3; /* trig_en + lvl1_en + lvl2_en */ +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN +uint8_t den_mode : + 3; /* trig_en + lvl1_en + lvl2_en */ + uint8_t xl_hm_mode : 1; + uint8_t usr_off_w : 1; + uint8_t ftype : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl6_c_t; + +#define LSM6DSO_CTRL7_G 0x16U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ois_on : 1; + uint8_t usr_off_on_out : 1; + uint8_t ois_on_en : 1; + uint8_t not_used_01 : 1; + uint8_t hpm_g : 2; + uint8_t hp_en_g : 1; + uint8_t g_hm_mode : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t g_hm_mode : 1; + uint8_t hp_en_g : 1; + uint8_t hpm_g : 2; + uint8_t not_used_01 : 1; + uint8_t ois_on_en : 1; + uint8_t usr_off_on_out : 1; + uint8_t ois_on : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl7_g_t; + +#define LSM6DSO_CTRL8_XL 0x17U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t low_pass_on_6d : 1; + uint8_t xl_fs_mode : 1; + uint8_t hp_slope_xl_en : 1; + uint8_t fastsettl_mode_xl : 1; + uint8_t hp_ref_mode_xl : 1; + uint8_t hpcf_xl : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t hpcf_xl : 3; + uint8_t hp_ref_mode_xl : 1; + uint8_t fastsettl_mode_xl : 1; + uint8_t hp_slope_xl_en : 1; + uint8_t xl_fs_mode : 1; + uint8_t low_pass_on_6d : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl8_xl_t; + +#define LSM6DSO_CTRL9_XL 0x18U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 1; + uint8_t i3c_disable : 1; + uint8_t den_lh : 1; + uint8_t den_xl_g : 2; /* den_xl_en + den_xl_g */ + uint8_t den_z : 1; + uint8_t den_y : 1; + uint8_t den_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_x : 1; + uint8_t den_y : 1; + uint8_t den_z : 1; + uint8_t den_xl_g : 2; /* den_xl_en + den_xl_g */ + uint8_t den_lh : 1; + uint8_t i3c_disable : 1; + uint8_t not_used_01 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl9_xl_t; + +#define LSM6DSO_CTRL10_C 0x19U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 5; + uint8_t timestamp_en : 1; + uint8_t not_used_02 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 2; + uint8_t timestamp_en : 1; + uint8_t not_used_01 : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl10_c_t; + +#define LSM6DSO_ALL_INT_SRC 0x1AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ff_ia : 1; + uint8_t wu_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t d6d_ia : 1; + uint8_t sleep_change_ia : 1; + uint8_t not_used_01 : 1; + uint8_t timestamp_endcount : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t timestamp_endcount : 1; + uint8_t not_used_01 : 1; + uint8_t sleep_change_ia : 1; + uint8_t d6d_ia : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t wu_ia : 1; + uint8_t ff_ia : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_all_int_src_t; + +#define LSM6DSO_WAKE_UP_SRC 0x1BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_wu : 1; + uint8_t y_wu : 1; + uint8_t x_wu : 1; + uint8_t wu_ia : 1; + uint8_t sleep_state : 1; + uint8_t ff_ia : 1; + uint8_t sleep_change_ia : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t sleep_change_ia : 1; + uint8_t ff_ia : 1; + uint8_t sleep_state : 1; + uint8_t wu_ia : 1; + uint8_t x_wu : 1; + uint8_t y_wu : 1; + uint8_t z_wu : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_wake_up_src_t; + +#define LSM6DSO_TAP_SRC 0x1CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_tap : 1; + uint8_t y_tap : 1; + uint8_t x_tap : 1; + uint8_t tap_sign : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t tap_ia : 1; + uint8_t not_used_02 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 1; + uint8_t tap_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t tap_sign : 1; + uint8_t x_tap : 1; + uint8_t y_tap : 1; + uint8_t z_tap : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_tap_src_t; + +#define LSM6DSO_D6D_SRC 0x1DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xl : 1; + uint8_t xh : 1; + uint8_t yl : 1; + uint8_t yh : 1; + uint8_t zl : 1; + uint8_t zh : 1; + uint8_t d6d_ia : 1; + uint8_t den_drdy : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t den_drdy : 1; + uint8_t d6d_ia : 1; + uint8_t zh : 1; + uint8_t zl : 1; + uint8_t yh : 1; + uint8_t yl : 1; + uint8_t xh : 1; + uint8_t xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_d6d_src_t; + +#define LSM6DSO_STATUS_REG 0x1EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xlda : 1; + uint8_t gda : 1; + uint8_t tda : 1; + uint8_t not_used_01 : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 5; + uint8_t tda : 1; + uint8_t gda : 1; + uint8_t xlda : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_status_reg_t; + +#define LSM6DSO_STATUS_SPIAUX 0x1EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xlda : 1; + uint8_t gda : 1; + uint8_t gyro_settling : 1; + uint8_t not_used_01 : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 5; + uint8_t gyro_settling : 1; + uint8_t gda : 1; + uint8_t xlda : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_status_spiaux_t; + +#define LSM6DSO_OUT_TEMP_L 0x20U +#define LSM6DSO_OUT_TEMP_H 0x21U +#define LSM6DSO_OUTX_L_G 0x22U +#define LSM6DSO_OUTX_H_G 0x23U +#define LSM6DSO_OUTY_L_G 0x24U +#define LSM6DSO_OUTY_H_G 0x25U +#define LSM6DSO_OUTZ_L_G 0x26U +#define LSM6DSO_OUTZ_H_G 0x27U +#define LSM6DSO_OUTX_L_A 0x28U +#define LSM6DSO_OUTX_H_A 0x29U +#define LSM6DSO_OUTY_L_A 0x2AU +#define LSM6DSO_OUTY_H_A 0x2BU +#define LSM6DSO_OUTZ_L_A 0x2CU +#define LSM6DSO_OUTZ_H_A 0x2DU +#define LSM6DSO_EMB_FUNC_STATUS_MAINPAGE 0x35U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t is_step_det : 1; + uint8_t is_tilt : 1; + uint8_t is_sigmot : 1; + uint8_t not_used_02 : 1; + uint8_t is_fsm_lc : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t is_fsm_lc : 1; + uint8_t not_used_02 : 1; + uint8_t is_sigmot : 1; + uint8_t is_tilt : 1; + uint8_t is_step_det : 1; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_status_mainpage_t; + +#define LSM6DSO_FSM_STATUS_A_MAINPAGE 0x36U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t is_fsm1 : 1; + uint8_t is_fsm2 : 1; + uint8_t is_fsm3 : 1; + uint8_t is_fsm4 : 1; + uint8_t is_fsm5 : 1; + uint8_t is_fsm6 : 1; + uint8_t is_fsm7 : 1; + uint8_t is_fsm8 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t is_fsm8 : 1; + uint8_t is_fsm7 : 1; + uint8_t is_fsm6 : 1; + uint8_t is_fsm5 : 1; + uint8_t is_fsm4 : 1; + uint8_t is_fsm3 : 1; + uint8_t is_fsm2 : 1; + uint8_t is_fsm1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_status_a_mainpage_t; + +#define LSM6DSO_FSM_STATUS_B_MAINPAGE 0x37U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t is_fsm9 : 1; + uint8_t is_fsm10 : 1; + uint8_t is_fsm11 : 1; + uint8_t is_fsm12 : 1; + uint8_t is_fsm13 : 1; + uint8_t is_fsm14 : 1; + uint8_t is_fsm15 : 1; + uint8_t is_fsm16 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t is_fsm16 : 1; + uint8_t is_fsm15 : 1; + uint8_t is_fsm14 : 1; + uint8_t is_fsm13 : 1; + uint8_t is_fsm12 : 1; + uint8_t is_fsm11 : 1; + uint8_t is_fsm10 : 1; + uint8_t is_fsm9 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_status_b_mainpage_t; + +#define LSM6DSO_STATUS_MASTER_MAINPAGE 0x39U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sens_hub_endop : 1; + uint8_t not_used_01 : 2; + uint8_t slave0_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave3_nack : 1; + uint8_t wr_once_done : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wr_once_done : 1; + uint8_t slave3_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave0_nack : 1; + uint8_t not_used_01 : 2; + uint8_t sens_hub_endop : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_status_master_mainpage_t; + +#define LSM6DSO_FIFO_STATUS1 0x3AU +typedef struct +{ + uint8_t diff_fifo : 8; +} lsm6dso_fifo_status1_t; + +#define LSM6DSO_FIFO_STATUS2 0x3B +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t diff_fifo : 2; + uint8_t not_used_01 : 1; + uint8_t over_run_latched : 1; + uint8_t counter_bdr_ia : 1; + uint8_t fifo_full_ia : 1; + uint8_t fifo_ovr_ia : 1; + uint8_t fifo_wtm_ia : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fifo_wtm_ia : 1; + uint8_t fifo_ovr_ia : 1; + uint8_t fifo_full_ia : 1; + uint8_t counter_bdr_ia : 1; + uint8_t over_run_latched : 1; + uint8_t not_used_01 : 1; + uint8_t diff_fifo : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fifo_status2_t; + +#define LSM6DSO_TIMESTAMP0 0x40U +#define LSM6DSO_TIMESTAMP1 0x41U +#define LSM6DSO_TIMESTAMP2 0x42U +#define LSM6DSO_TIMESTAMP3 0x43U +#define LSM6DSO_TAP_CFG0 0x56U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t lir : 1; + uint8_t tap_z_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_x_en : 1; + uint8_t slope_fds : 1; + uint8_t sleep_status_on_int : 1; + uint8_t int_clr_on_read : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t int_clr_on_read : 1; + uint8_t sleep_status_on_int : 1; + uint8_t slope_fds : 1; + uint8_t tap_x_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_z_en : 1; + uint8_t lir : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_tap_cfg0_t; + +#define LSM6DSO_TAP_CFG1 0x57U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_ths_x : 5; + uint8_t tap_priority : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t tap_priority : 3; + uint8_t tap_ths_x : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_tap_cfg1_t; + +#define LSM6DSO_TAP_CFG2 0x58U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_ths_y : 5; + uint8_t inact_en : 2; + uint8_t interrupts_enable : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t interrupts_enable : 1; + uint8_t inact_en : 2; + uint8_t tap_ths_y : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_tap_cfg2_t; + +#define LSM6DSO_TAP_THS_6D 0x59U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_ths_z : 5; + uint8_t sixd_ths : 2; + uint8_t d4d_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t d4d_en : 1; + uint8_t sixd_ths : 2; + uint8_t tap_ths_z : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_tap_ths_6d_t; + +#define LSM6DSO_INT_DUR2 0x5AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t shock : 2; + uint8_t quiet : 2; + uint8_t dur : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t dur : 4; + uint8_t quiet : 2; + uint8_t shock : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_int_dur2_t; + +#define LSM6DSO_WAKE_UP_THS 0x5BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wk_ths : 6; + uint8_t usr_off_on_wu : 1; + uint8_t single_double_tap : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t single_double_tap : 1; + uint8_t usr_off_on_wu : 1; + uint8_t wk_ths : 6; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_wake_up_ths_t; + +#define LSM6DSO_WAKE_UP_DUR 0x5CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sleep_dur : 4; + uint8_t wake_ths_w : 1; + uint8_t wake_dur : 2; + uint8_t ff_dur : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 1; + uint8_t wake_dur : 2; + uint8_t wake_ths_w : 1; + uint8_t sleep_dur : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_wake_up_dur_t; + +#define LSM6DSO_FREE_FALL 0x5DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ff_ths : 3; + uint8_t ff_dur : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 5; + uint8_t ff_ths : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_free_fall_t; + +#define LSM6DSO_MD1_CFG 0x5EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_shub : 1; + uint8_t int1_emb_func : 1; + uint8_t int1_6d : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_ff : 1; + uint8_t int1_wu : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_sleep_change : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_sleep_change : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_wu : 1; + uint8_t int1_ff : 1; + uint8_t int1_double_tap : 1; + uint8_t int1_6d : 1; + uint8_t int1_emb_func : 1; + uint8_t int1_shub : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_md1_cfg_t; + +#define LSM6DSO_MD2_CFG 0x5FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_timestamp : 1; + uint8_t int2_emb_func : 1; + uint8_t int2_6d : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_ff : 1; + uint8_t int2_wu : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_sleep_change : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_sleep_change : 1; + uint8_t int2_single_tap : 1; + uint8_t int2_wu : 1; + uint8_t int2_ff : 1; + uint8_t int2_double_tap : 1; + uint8_t int2_6d : 1; + uint8_t int2_emb_func : 1; + uint8_t int2_timestamp : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_md2_cfg_t; + +#define LSM6DSO_I3C_BUS_AVB 0x62U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t pd_dis_int1 : 1; + uint8_t not_used_01 : 2; + uint8_t i3c_bus_avb_sel : 2; + uint8_t not_used_02 : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 3; + uint8_t i3c_bus_avb_sel : 2; + uint8_t not_used_01 : 2; + uint8_t pd_dis_int1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_i3c_bus_avb_t; + +#define LSM6DSO_INTERNAL_FREQ_FINE 0x63U +typedef struct +{ + uint8_t freq_fine : 8; +} lsm6dso_internal_freq_fine_t; + +#define LSM6DSO_INT_OIS 0x6FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t st_xl_ois : 2; + uint8_t not_used_01 : 3; + uint8_t den_lh_ois : 1; + uint8_t lvl2_ois : 1; + uint8_t int2_drdy_ois : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_drdy_ois : 1; + uint8_t lvl2_ois : 1; + uint8_t den_lh_ois : 1; + uint8_t not_used_01 : 3; + uint8_t st_xl_ois : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_int_ois_t; + +#define LSM6DSO_CTRL1_OIS 0x70U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ois_en_spi2 : 1; + uint8_t fs_g_ois : 3; /* fs_125_ois + fs[1:0]_g_ois */ + uint8_t mode4_en : 1; + uint8_t sim_ois : 1; + uint8_t lvl1_ois : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t lvl1_ois : 1; + uint8_t sim_ois : 1; + uint8_t mode4_en : 1; + uint8_t fs_g_ois : 3; /* fs_125_ois + fs[1:0]_g_ois */ + uint8_t ois_en_spi2 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl1_ois_t; + +#define LSM6DSO_CTRL2_OIS 0x71U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t hp_en_ois : 1; + uint8_t ftype_ois : 2; + uint8_t not_used_01 : 1; + uint8_t hpm_ois : 2; + uint8_t not_used_02 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 2; + uint8_t hpm_ois : 2; + uint8_t not_used_01 : 1; + uint8_t ftype_ois : 2; + uint8_t hp_en_ois : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl2_ois_t; + +#define LSM6DSO_CTRL3_OIS 0x72U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t st_ois_clampdis : 1; + uint8_t st_ois : 2; + uint8_t filter_xl_conf_ois : 3; + uint8_t fs_xl_ois : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fs_xl_ois : 2; + uint8_t filter_xl_conf_ois : 3; + uint8_t st_ois : 2; + uint8_t st_ois_clampdis : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_ctrl3_ois_t; + +#define LSM6DSO_X_OFS_USR 0x73U +#define LSM6DSO_Y_OFS_USR 0x74U +#define LSM6DSO_Z_OFS_USR 0x75U +#define LSM6DSO_FIFO_DATA_OUT_TAG 0x78U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tag_parity : 1; + uint8_t tag_cnt : 2; + uint8_t tag_sensor : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t tag_sensor : 5; + uint8_t tag_cnt : 2; + uint8_t tag_parity : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fifo_data_out_tag_t; + +#define LSM6DSO_FIFO_DATA_OUT_X_L 0x79U +#define LSM6DSO_FIFO_DATA_OUT_X_H 0x7AU +#define LSM6DSO_FIFO_DATA_OUT_Y_L 0x7BU +#define LSM6DSO_FIFO_DATA_OUT_Y_H 0x7CU +#define LSM6DSO_FIFO_DATA_OUT_Z_L 0x7DU +#define LSM6DSO_FIFO_DATA_OUT_Z_H 0x7EU +#define LSM6DSO_PAGE_SEL 0x02U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 4; + uint8_t page_sel : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t page_sel : 4; + uint8_t not_used_01 : 4; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_page_sel_t; + +#define LSM6DSO_EMB_FUNC_EN_A 0x04U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t pedo_en : 1; + uint8_t tilt_en : 1; + uint8_t sign_motion_en : 1; + uint8_t not_used_02 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 2; + uint8_t sign_motion_en : 1; + uint8_t tilt_en : 1; + uint8_t pedo_en : 1; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_en_a_t; + +#define LSM6DSO_EMB_FUNC_EN_B 0x05U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fsm_en : 1; + uint8_t not_used_01 : 2; + uint8_t fifo_compr_en : 1; + uint8_t pedo_adv_en : 1; + uint8_t not_used_02 : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 3; + uint8_t pedo_adv_en : 1; + uint8_t fifo_compr_en : 1; + uint8_t not_used_01 : 2; + uint8_t fsm_en : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_en_b_t; + +#define LSM6DSO_PAGE_ADDRESS 0x08U +typedef struct +{ + uint8_t page_addr : 8; +} lsm6dso_page_address_t; + +#define LSM6DSO_PAGE_VALUE 0x09U +typedef struct +{ + uint8_t page_value : 8; +} lsm6dso_page_value_t; + +#define LSM6DSO_EMB_FUNC_INT1 0x0AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t int1_step_detector : 1; + uint8_t int1_tilt : 1; + uint8_t int1_sig_mot : 1; + uint8_t not_used_02 : 1; + uint8_t int1_fsm_lc : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_fsm_lc : 1; + uint8_t not_used_02 : 1; + uint8_t int1_sig_mot : 1; + uint8_t int1_tilt : 1; + uint8_t int1_step_detector : 1; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_int1_t; + +#define LSM6DSO_FSM_INT1_A 0x0BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_fsm1 : 1; + uint8_t int1_fsm2 : 1; + uint8_t int1_fsm3 : 1; + uint8_t int1_fsm4 : 1; + uint8_t int1_fsm5 : 1; + uint8_t int1_fsm6 : 1; + uint8_t int1_fsm7 : 1; + uint8_t int1_fsm8 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_fsm8 : 1; + uint8_t int1_fsm7 : 1; + uint8_t int1_fsm6 : 1; + uint8_t int1_fsm5 : 1; + uint8_t int1_fsm4 : 1; + uint8_t int1_fsm3 : 1; + uint8_t int1_fsm2 : 1; + uint8_t int1_fsm1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_int1_a_t; + +#define LSM6DSO_FSM_INT1_B 0x0CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_fsm9 : 1; + uint8_t int1_fsm10 : 1; + uint8_t int1_fsm11 : 1; + uint8_t int1_fsm12 : 1; + uint8_t int1_fsm13 : 1; + uint8_t int1_fsm14 : 1; + uint8_t int1_fsm15 : 1; + uint8_t int1_fsm16 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_fsm16 : 1; + uint8_t int1_fsm15 : 1; + uint8_t int1_fsm14 : 1; + uint8_t int1_fsm13 : 1; + uint8_t int1_fsm12 : 1; + uint8_t int1_fsm11 : 1; + uint8_t int1_fsm10 : 1; + uint8_t int1_fsm9 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_int1_b_t; + +#define LSM6DSO_EMB_FUNC_INT2 0x0EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t int2_step_detector : 1; + uint8_t int2_tilt : 1; + uint8_t int2_sig_mot : 1; + uint8_t not_used_02 : 1; + uint8_t int2_fsm_lc : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_fsm_lc : 1; + uint8_t not_used_02 : 1; + uint8_t int2_sig_mot : 1; + uint8_t int2_tilt : 1; + uint8_t int2_step_detector : 1; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_int2_t; + +#define LSM6DSO_FSM_INT2_A 0x0FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_fsm1 : 1; + uint8_t int2_fsm2 : 1; + uint8_t int2_fsm3 : 1; + uint8_t int2_fsm4 : 1; + uint8_t int2_fsm5 : 1; + uint8_t int2_fsm6 : 1; + uint8_t int2_fsm7 : 1; + uint8_t int2_fsm8 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_fsm8 : 1; + uint8_t int2_fsm7 : 1; + uint8_t int2_fsm6 : 1; + uint8_t int2_fsm5 : 1; + uint8_t int2_fsm4 : 1; + uint8_t int2_fsm3 : 1; + uint8_t int2_fsm2 : 1; + uint8_t int2_fsm1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_int2_a_t; + +#define LSM6DSO_FSM_INT2_B 0x10U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_fsm9 : 1; + uint8_t int2_fsm10 : 1; + uint8_t int2_fsm11 : 1; + uint8_t int2_fsm12 : 1; + uint8_t int2_fsm13 : 1; + uint8_t int2_fsm14 : 1; + uint8_t int2_fsm15 : 1; + uint8_t int2_fsm16 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_fsm16 : 1; + uint8_t int2_fsm15 : 1; + uint8_t int2_fsm14 : 1; + uint8_t int2_fsm13 : 1; + uint8_t int2_fsm12 : 1; + uint8_t int2_fsm11 : 1; + uint8_t int2_fsm10 : 1; + uint8_t int2_fsm9 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_int2_b_t; + +#define LSM6DSO_EMB_FUNC_STATUS 0x12U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t is_step_det : 1; + uint8_t is_tilt : 1; + uint8_t is_sigmot : 1; + uint8_t not_used_02 : 1; + uint8_t is_fsm_lc : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t is_fsm_lc : 1; + uint8_t not_used_02 : 1; + uint8_t is_sigmot : 1; + uint8_t is_tilt : 1; + uint8_t is_step_det : 1; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_status_t; + +#define LSM6DSO_FSM_STATUS_A 0x13U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t is_fsm1 : 1; + uint8_t is_fsm2 : 1; + uint8_t is_fsm3 : 1; + uint8_t is_fsm4 : 1; + uint8_t is_fsm5 : 1; + uint8_t is_fsm6 : 1; + uint8_t is_fsm7 : 1; + uint8_t is_fsm8 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t is_fsm8 : 1; + uint8_t is_fsm7 : 1; + uint8_t is_fsm6 : 1; + uint8_t is_fsm5 : 1; + uint8_t is_fsm4 : 1; + uint8_t is_fsm3 : 1; + uint8_t is_fsm2 : 1; + uint8_t is_fsm1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_status_a_t; + +#define LSM6DSO_FSM_STATUS_B 0x14U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t is_fsm9 : 1; + uint8_t is_fsm10 : 1; + uint8_t is_fsm11 : 1; + uint8_t is_fsm12 : 1; + uint8_t is_fsm13 : 1; + uint8_t is_fsm14 : 1; + uint8_t is_fsm15 : 1; + uint8_t is_fsm16 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t is_fsm16 : 1; + uint8_t is_fsm15 : 1; + uint8_t is_fsm14 : 1; + uint8_t is_fsm13 : 1; + uint8_t is_fsm12 : 1; + uint8_t is_fsm11 : 1; + uint8_t is_fsm10 : 1; + uint8_t is_fsm9 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_status_b_t; + +#define LSM6DSO_PAGE_RW 0x17U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 5; + uint8_t page_rw : 2; /* page_write + page_read */ + uint8_t emb_func_lir : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t emb_func_lir : 1; + uint8_t page_rw : 2; /* page_write + page_read */ + uint8_t not_used_01 : 5; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_page_rw_t; + +#define LSM6DSO_EMB_FUNC_FIFO_CFG 0x44U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_00 : 6; + uint8_t pedo_fifo_en : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t pedo_fifo_en : 1; + uint8_t not_used_00 : 6; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_fifo_cfg_t; + +#define LSM6DSO_FSM_ENABLE_A 0x46U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fsm1_en : 1; + uint8_t fsm2_en : 1; + uint8_t fsm3_en : 1; + uint8_t fsm4_en : 1; + uint8_t fsm5_en : 1; + uint8_t fsm6_en : 1; + uint8_t fsm7_en : 1; + uint8_t fsm8_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fsm8_en : 1; + uint8_t fsm7_en : 1; + uint8_t fsm6_en : 1; + uint8_t fsm5_en : 1; + uint8_t fsm4_en : 1; + uint8_t fsm3_en : 1; + uint8_t fsm2_en : 1; + uint8_t fsm1_en : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_enable_a_t; + +#define LSM6DSO_FSM_ENABLE_B 0x47U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fsm9_en : 1; + uint8_t fsm10_en : 1; + uint8_t fsm11_en : 1; + uint8_t fsm12_en : 1; + uint8_t fsm13_en : 1; + uint8_t fsm14_en : 1; + uint8_t fsm15_en : 1; + uint8_t fsm16_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fsm16_en : 1; + uint8_t fsm15_en : 1; + uint8_t fsm14_en : 1; + uint8_t fsm13_en : 1; + uint8_t fsm12_en : 1; + uint8_t fsm11_en : 1; + uint8_t fsm10_en : 1; + uint8_t fsm9_en : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_enable_b_t; + +#define LSM6DSO_FSM_LONG_COUNTER_L 0x48U +#define LSM6DSO_FSM_LONG_COUNTER_H 0x49U +#define LSM6DSO_FSM_LONG_COUNTER_CLEAR 0x4AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN +uint8_t fsm_lc_clr : + 2; /* fsm_lc_cleared + fsm_lc_clear */ + uint8_t not_used_01 : 6; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 6; +uint8_t fsm_lc_clr : + 2; /* fsm_lc_cleared + fsm_lc_clear */ +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_long_counter_clear_t; + +#define LSM6DSO_FSM_OUTS1 0x4CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs1_t; + +#define LSM6DSO_FSM_OUTS2 0x4DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs2_t; + +#define LSM6DSO_FSM_OUTS3 0x4EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs3_t; + +#define LSM6DSO_FSM_OUTS4 0x4FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs4_t; + +#define LSM6DSO_FSM_OUTS5 0x50U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs5_t; + +#define LSM6DSO_FSM_OUTS6 0x51U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs6_t; + +#define LSM6DSO_FSM_OUTS7 0x52U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs7_t; + +#define LSM6DSO_FSM_OUTS8 0x53U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs8_t; + +#define LSM6DSO_FSM_OUTS9 0x54U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs9_t; + +#define LSM6DSO_FSM_OUTS10 0x55U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs10_t; + +#define LSM6DSO_FSM_OUTS11 0x56U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs11_t; + +#define LSM6DSO_FSM_OUTS12 0x57U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs12_t; + +#define LSM6DSO_FSM_OUTS13 0x58U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs13_t; + +#define LSM6DSO_FSM_OUTS14 0x59U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs14_t; + +#define LSM6DSO_FSM_OUTS15 0x5AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs15_t; + +#define LSM6DSO_FSM_OUTS16 0x5BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t n_v : 1; + uint8_t p_v : 1; + uint8_t n_z : 1; + uint8_t p_z : 1; + uint8_t n_y : 1; + uint8_t p_y : 1; + uint8_t n_x : 1; + uint8_t p_x : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t p_x : 1; + uint8_t n_x : 1; + uint8_t p_y : 1; + uint8_t n_y : 1; + uint8_t p_z : 1; + uint8_t n_z : 1; + uint8_t p_v : 1; + uint8_t n_v : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_fsm_outs16_t; + +#define LSM6DSO_EMB_FUNC_ODR_CFG_B 0x5FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t fsm_odr : 2; + uint8_t not_used_02 : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 3; + uint8_t fsm_odr : 2; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_odr_cfg_b_t; + +#define LSM6DSO_STEP_COUNTER_L 0x62U +#define LSM6DSO_STEP_COUNTER_H 0x63U +#define LSM6DSO_EMB_FUNC_SRC 0x64U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t stepcounter_bit_set : 1; + uint8_t step_overflow : 1; + uint8_t step_count_delta_ia : 1; + uint8_t step_detected : 1; + uint8_t not_used_02 : 1; + uint8_t pedo_rst_step : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t pedo_rst_step : 1; + uint8_t not_used_02 : 1; + uint8_t step_detected : 1; + uint8_t step_count_delta_ia : 1; + uint8_t step_overflow : 1; + uint8_t stepcounter_bit_set : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_src_t; + +#define LSM6DSO_EMB_FUNC_INIT_A 0x66U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 3; + uint8_t step_det_init : 1; + uint8_t tilt_init : 1; + uint8_t sig_mot_init : 1; + uint8_t not_used_02 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 2; + uint8_t sig_mot_init : 1; + uint8_t tilt_init : 1; + uint8_t step_det_init : 1; + uint8_t not_used_01 : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_init_a_t; + +#define LSM6DSO_EMB_FUNC_INIT_B 0x67U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fsm_init : 1; + uint8_t not_used_01 : 2; + uint8_t fifo_compr_init : 1; + uint8_t not_used_02 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 4; + uint8_t fifo_compr_init : 1; + uint8_t not_used_01 : 2; + uint8_t fsm_init : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_emb_func_init_b_t; + +#define LSM6DSO_MAG_SENSITIVITY_L 0xBAU +#define LSM6DSO_MAG_SENSITIVITY_H 0xBBU +#define LSM6DSO_MAG_OFFX_L 0xC0U +#define LSM6DSO_MAG_OFFX_H 0xC1U +#define LSM6DSO_MAG_OFFY_L 0xC2U +#define LSM6DSO_MAG_OFFY_H 0xC3U +#define LSM6DSO_MAG_OFFZ_L 0xC4U +#define LSM6DSO_MAG_OFFZ_H 0xC5U +#define LSM6DSO_MAG_SI_XX_L 0xC6U +#define LSM6DSO_MAG_SI_XX_H 0xC7U +#define LSM6DSO_MAG_SI_XY_L 0xC8U +#define LSM6DSO_MAG_SI_XY_H 0xC9U +#define LSM6DSO_MAG_SI_XZ_L 0xCAU +#define LSM6DSO_MAG_SI_XZ_H 0xCBU +#define LSM6DSO_MAG_SI_YY_L 0xCCU +#define LSM6DSO_MAG_SI_YY_H 0xCDU +#define LSM6DSO_MAG_SI_YZ_L 0xCEU +#define LSM6DSO_MAG_SI_YZ_H 0xCFU +#define LSM6DSO_MAG_SI_ZZ_L 0xD0U +#define LSM6DSO_MAG_SI_ZZ_H 0xD1U +#define LSM6DSO_MAG_CFG_A 0xD4U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t mag_z_axis : 3; + uint8_t not_used_01 : 1; + uint8_t mag_y_axis : 3; + uint8_t not_used_02 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 1; + uint8_t mag_y_axis : 3; + uint8_t not_used_01 : 1; + uint8_t mag_z_axis : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_mag_cfg_a_t; + +#define LSM6DSO_MAG_CFG_B 0xD5U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t mag_x_axis : 3; + uint8_t not_used_01 : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 5; + uint8_t mag_x_axis : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_mag_cfg_b_t; + +#define LSM6DSO_FSM_LC_TIMEOUT_L 0x17AU +#define LSM6DSO_FSM_LC_TIMEOUT_H 0x17BU +#define LSM6DSO_FSM_PROGRAMS 0x17CU +#define LSM6DSO_FSM_START_ADD_L 0x17EU +#define LSM6DSO_FSM_START_ADD_H 0x17FU +#define LSM6DSO_PEDO_CMD_REG 0x183U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ad_det_en : 1; + uint8_t not_used_01 : 1; + uint8_t fp_rejection_en : 1; + uint8_t carry_count_en : 1; + uint8_t not_used_02 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_02 : 4; + uint8_t carry_count_en : 1; + uint8_t fp_rejection_en : 1; + uint8_t not_used_01 : 1; + uint8_t ad_det_en : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_pedo_cmd_reg_t; + +#define LSM6DSO_PEDO_DEB_STEPS_CONF 0x184U +#define LSM6DSO_PEDO_SC_DELTAT_L 0x1D0U +#define LSM6DSO_PEDO_SC_DELTAT_H 0x1D1U +#define LSM6DSO_SENSOR_HUB_1 0x02U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_1_t; + +#define LSM6DSO_SENSOR_HUB_2 0x03U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_2_t; + +#define LSM6DSO_SENSOR_HUB_3 0x04U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_3_t; + +#define LSM6DSO_SENSOR_HUB_4 0x05U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_4_t; + +#define LSM6DSO_SENSOR_HUB_5 0x06U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_5_t; + +#define LSM6DSO_SENSOR_HUB_6 0x07U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_6_t; + +#define LSM6DSO_SENSOR_HUB_7 0x08U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_7_t; + +#define LSM6DSO_SENSOR_HUB_8 0x09U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_8_t; + +#define LSM6DSO_SENSOR_HUB_9 0x0AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_9_t; + +#define LSM6DSO_SENSOR_HUB_10 0x0BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_10_t; + +#define LSM6DSO_SENSOR_HUB_11 0x0CU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_11_t; + +#define LSM6DSO_SENSOR_HUB_12 0x0DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_12_t; + +#define LSM6DSO_SENSOR_HUB_13 0x0EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_13_t; + +#define LSM6DSO_SENSOR_HUB_14 0x0FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_14_t; + +#define LSM6DSO_SENSOR_HUB_15 0x10U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_15_t; + +#define LSM6DSO_SENSOR_HUB_16 0x11U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_16_t; + +#define LSM6DSO_SENSOR_HUB_17 0x12U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_17_t; + +#define LSM6DSO_SENSOR_HUB_18 0x13U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_sensor_hub_18_t; + +#define LSM6DSO_MASTER_CONFIG 0x14U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t aux_sens_on : 2; + uint8_t master_on : 1; + uint8_t shub_pu_en : 1; + uint8_t pass_through_mode : 1; + uint8_t start_config : 1; + uint8_t write_once : 1; + uint8_t rst_master_regs : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t rst_master_regs : 1; + uint8_t write_once : 1; + uint8_t start_config : 1; + uint8_t pass_through_mode : 1; + uint8_t shub_pu_en : 1; + uint8_t master_on : 1; + uint8_t aux_sens_on : 2; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_master_config_t; + +#define LSM6DSO_SLV0_ADD 0x15U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t rw_0 : 1; + uint8_t slave0 : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave0 : 7; + uint8_t rw_0 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv0_add_t; + +#define LSM6DSO_SLV0_SUBADD 0x16U +typedef struct +{ + uint8_t slave0_reg : 8; +} lsm6dso_slv0_subadd_t; + +#define LSM6DSO_SLV0_CONFIG 0x17U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave0_numop : 3; + uint8_t batch_ext_sens_0_en : 1; + uint8_t not_used_01 : 2; + uint8_t shub_odr : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t shub_odr : 2; + uint8_t not_used_01 : 2; + uint8_t batch_ext_sens_0_en : 1; + uint8_t slave0_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv0_config_t; + +#define LSM6DSO_SLV1_ADD 0x18U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_1 : 1; + uint8_t slave1_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave1_add : 7; + uint8_t r_1 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv1_add_t; + +#define LSM6DSO_SLV1_SUBADD 0x19U +typedef struct +{ + uint8_t slave1_reg : 8; +} lsm6dso_slv1_subadd_t; + +#define LSM6DSO_SLV1_CONFIG 0x1AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave1_numop : 3; + uint8_t batch_ext_sens_1_en : 1; + uint8_t not_used_01 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 4; + uint8_t batch_ext_sens_1_en : 1; + uint8_t slave1_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv1_config_t; + +#define LSM6DSO_SLV2_ADD 0x1BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_2 : 1; + uint8_t slave2_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave2_add : 7; + uint8_t r_2 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv2_add_t; + +#define LSM6DSO_SLV2_SUBADD 0x1CU +typedef struct +{ + uint8_t slave2_reg : 8; +} lsm6dso_slv2_subadd_t; + +#define LSM6DSO_SLV2_CONFIG 0x1DU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave2_numop : 3; + uint8_t batch_ext_sens_2_en : 1; + uint8_t not_used_01 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 4; + uint8_t batch_ext_sens_2_en : 1; + uint8_t slave2_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv2_config_t; + +#define LSM6DSO_SLV3_ADD 0x1EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t r_3 : 1; + uint8_t slave3_add : 7; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t slave3_add : 7; + uint8_t r_3 : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv3_add_t; + +#define LSM6DSO_SLV3_SUBADD 0x1FU +typedef struct +{ + uint8_t slave3_reg : 8; +} lsm6dso_slv3_subadd_t; + +#define LSM6DSO_SLV3_CONFIG 0x20U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t slave3_numop : 3; + uint8_t batch_ext_sens_3_en : 1; + uint8_t not_used_01 : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 4; + uint8_t batch_ext_sens_3_en : 1; + uint8_t slave3_numop : 3; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_slv3_config_t; + +#define LSM6DSO_DATAWRITE_SLV0 0x21U +typedef struct +{ + uint8_t slave0_dataw : 8; +} lsm6dso_datawrite_src_mode_sub_slv0_t; + +#define LSM6DSO_STATUS_MASTER 0x22U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sens_hub_endop : 1; + uint8_t not_used_01 : 2; + uint8_t slave0_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave3_nack : 1; + uint8_t wr_once_done : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t wr_once_done : 1; + uint8_t slave3_nack : 1; + uint8_t slave2_nack : 1; + uint8_t slave1_nack : 1; + uint8_t slave0_nack : 1; + uint8_t not_used_01 : 2; + uint8_t sens_hub_endop : 1; +#endif /* DRV_BYTE_ORDER */ +} lsm6dso_status_master_t; + +#define LSM6DSO_START_FSM_ADD 0x0400U + +/** + * @defgroup LSM6DSO_Register_Union + * @brief This union group all the registers having a bit-field + * description. + * This union is useful but it's not needed by the driver. + * + * REMOVING this union you are compliant with: + * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " + * + * @{ + * + */ +typedef union +{ + lsm6dso_func_cfg_access_t func_cfg_access; + lsm6dso_pin_ctrl_t pin_ctrl; + lsm6dso_fifo_ctrl1_t fifo_ctrl1; + lsm6dso_fifo_ctrl2_t fifo_ctrl2; + lsm6dso_fifo_ctrl3_t fifo_ctrl3; + lsm6dso_fifo_ctrl4_t fifo_ctrl4; + lsm6dso_counter_bdr_reg1_t counter_bdr_reg1; + lsm6dso_counter_bdr_reg2_t counter_bdr_reg2; + lsm6dso_int1_ctrl_t int1_ctrl; + lsm6dso_int2_ctrl_t int2_ctrl; + lsm6dso_ctrl1_xl_t ctrl1_xl; + lsm6dso_ctrl2_g_t ctrl2_g; + lsm6dso_ctrl3_c_t ctrl3_c; + lsm6dso_ctrl4_c_t ctrl4_c; + lsm6dso_ctrl5_c_t ctrl5_c; + lsm6dso_ctrl6_c_t ctrl6_c; + lsm6dso_ctrl7_g_t ctrl7_g; + lsm6dso_ctrl8_xl_t ctrl8_xl; + lsm6dso_ctrl9_xl_t ctrl9_xl; + lsm6dso_ctrl10_c_t ctrl10_c; + lsm6dso_all_int_src_t all_int_src; + lsm6dso_wake_up_src_t wake_up_src; + lsm6dso_tap_src_t tap_src; + lsm6dso_d6d_src_t d6d_src; + lsm6dso_status_reg_t status_reg; + lsm6dso_status_spiaux_t status_spiaux; + lsm6dso_fifo_status1_t fifo_status1; + lsm6dso_fifo_status2_t fifo_status2; + lsm6dso_tap_cfg0_t tap_cfg0; + lsm6dso_tap_cfg1_t tap_cfg1; + lsm6dso_tap_cfg2_t tap_cfg2; + lsm6dso_tap_ths_6d_t tap_ths_6d; + lsm6dso_int_dur2_t int_dur2; + lsm6dso_wake_up_ths_t wake_up_ths; + lsm6dso_wake_up_dur_t wake_up_dur; + lsm6dso_free_fall_t free_fall; + lsm6dso_md1_cfg_t md1_cfg; + lsm6dso_md2_cfg_t md2_cfg; + lsm6dso_i3c_bus_avb_t i3c_bus_avb; + lsm6dso_internal_freq_fine_t internal_freq_fine; + lsm6dso_int_ois_t int_ois; + lsm6dso_ctrl1_ois_t ctrl1_ois; + lsm6dso_ctrl2_ois_t ctrl2_ois; + lsm6dso_ctrl3_ois_t ctrl3_ois; + lsm6dso_fifo_data_out_tag_t fifo_data_out_tag; + lsm6dso_page_sel_t page_sel; + lsm6dso_emb_func_en_a_t emb_func_en_a; + lsm6dso_emb_func_en_b_t emb_func_en_b; + lsm6dso_page_address_t page_address; + lsm6dso_page_value_t page_value; + lsm6dso_emb_func_int1_t emb_func_int1; + lsm6dso_fsm_int1_a_t fsm_int1_a; + lsm6dso_fsm_int1_b_t fsm_int1_b; + lsm6dso_emb_func_int2_t emb_func_int2; + lsm6dso_fsm_int2_a_t fsm_int2_a; + lsm6dso_fsm_int2_b_t fsm_int2_b; + lsm6dso_emb_func_status_t emb_func_status; + lsm6dso_fsm_status_a_t fsm_status_a; + lsm6dso_fsm_status_b_t fsm_status_b; + lsm6dso_page_rw_t page_rw; + lsm6dso_emb_func_fifo_cfg_t emb_func_fifo_cfg; + lsm6dso_fsm_enable_a_t fsm_enable_a; + lsm6dso_fsm_enable_b_t fsm_enable_b; + lsm6dso_fsm_long_counter_clear_t fsm_long_counter_clear; + lsm6dso_fsm_outs1_t fsm_outs1; + lsm6dso_fsm_outs2_t fsm_outs2; + lsm6dso_fsm_outs3_t fsm_outs3; + lsm6dso_fsm_outs4_t fsm_outs4; + lsm6dso_fsm_outs5_t fsm_outs5; + lsm6dso_fsm_outs6_t fsm_outs6; + lsm6dso_fsm_outs7_t fsm_outs7; + lsm6dso_fsm_outs8_t fsm_outs8; + lsm6dso_fsm_outs9_t fsm_outs9; + lsm6dso_fsm_outs10_t fsm_outs10; + lsm6dso_fsm_outs11_t fsm_outs11; + lsm6dso_fsm_outs12_t fsm_outs12; + lsm6dso_fsm_outs13_t fsm_outs13; + lsm6dso_fsm_outs14_t fsm_outs14; + lsm6dso_fsm_outs15_t fsm_outs15; + lsm6dso_fsm_outs16_t fsm_outs16; + lsm6dso_emb_func_odr_cfg_b_t emb_func_odr_cfg_b; + lsm6dso_emb_func_src_t emb_func_src; + lsm6dso_emb_func_init_a_t emb_func_init_a; + lsm6dso_emb_func_init_b_t emb_func_init_b; + lsm6dso_mag_cfg_a_t mag_cfg_a; + lsm6dso_mag_cfg_b_t mag_cfg_b; + lsm6dso_pedo_cmd_reg_t pedo_cmd_reg; + lsm6dso_sensor_hub_1_t sensor_hub_1; + lsm6dso_sensor_hub_2_t sensor_hub_2; + lsm6dso_sensor_hub_3_t sensor_hub_3; + lsm6dso_sensor_hub_4_t sensor_hub_4; + lsm6dso_sensor_hub_5_t sensor_hub_5; + lsm6dso_sensor_hub_6_t sensor_hub_6; + lsm6dso_sensor_hub_7_t sensor_hub_7; + lsm6dso_sensor_hub_8_t sensor_hub_8; + lsm6dso_sensor_hub_9_t sensor_hub_9; + lsm6dso_sensor_hub_10_t sensor_hub_10; + lsm6dso_sensor_hub_11_t sensor_hub_11; + lsm6dso_sensor_hub_12_t sensor_hub_12; + lsm6dso_sensor_hub_13_t sensor_hub_13; + lsm6dso_sensor_hub_14_t sensor_hub_14; + lsm6dso_sensor_hub_15_t sensor_hub_15; + lsm6dso_sensor_hub_16_t sensor_hub_16; + lsm6dso_sensor_hub_17_t sensor_hub_17; + lsm6dso_sensor_hub_18_t sensor_hub_18; + lsm6dso_master_config_t master_config; + lsm6dso_slv0_add_t slv0_add; + lsm6dso_slv0_subadd_t slv0_subadd; + lsm6dso_slv0_config_t slv0_config; + lsm6dso_slv1_add_t slv1_add; + lsm6dso_slv1_subadd_t slv1_subadd; + lsm6dso_slv1_config_t slv1_config; + lsm6dso_slv2_add_t slv2_add; + lsm6dso_slv2_subadd_t slv2_subadd; + lsm6dso_slv2_config_t slv2_config; + lsm6dso_slv3_add_t slv3_add; + lsm6dso_slv3_subadd_t slv3_subadd; + lsm6dso_slv3_config_t slv3_config; + lsm6dso_datawrite_src_mode_sub_slv0_t datawrite_src_mode_sub_slv0; + lsm6dso_status_master_t status_master; + bitwise_t bitwise; + uint8_t byte; +} lsm6dso_reg_t; + +/** + * @} + * + */ + +float_t lsm6dso_from_fs2_to_mg(int16_t lsb); +float_t lsm6dso_from_fs4_to_mg(int16_t lsb); +float_t lsm6dso_from_fs8_to_mg(int16_t lsb); +float_t lsm6dso_from_fs16_to_mg(int16_t lsb); + +float_t lsm6dso_from_fs125_to_mdps(int16_t lsb); +float_t lsm6dso_from_fs500_to_mdps(int16_t lsb); +float_t lsm6dso_from_fs250_to_mdps(int16_t lsb); +float_t lsm6dso_from_fs1000_to_mdps(int16_t lsb); +float_t lsm6dso_from_fs2000_to_mdps(int16_t lsb); + +float_t lsm6dso_from_lsb_to_celsius(int16_t lsb); + +float_t lsm6dso_from_lsb_to_nsec(int16_t lsb); + +typedef enum +{ + LSM6DSO_2g = 0, + LSM6DSO_16g = 1, /* if XL_FS_MODE = '1' -> LSM6DSO_2g */ + LSM6DSO_4g = 2, + LSM6DSO_8g = 3, +} lsm6dso_fs_xl_t; +int32_t lsm6dso_xl_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_t val); +int32_t lsm6dso_xl_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_t *val); + +typedef enum +{ + LSM6DSO_XL_ODR_OFF = 0, + LSM6DSO_XL_ODR_12Hz5 = 1, + LSM6DSO_XL_ODR_26Hz = 2, + LSM6DSO_XL_ODR_52Hz = 3, + LSM6DSO_XL_ODR_104Hz = 4, + LSM6DSO_XL_ODR_208Hz = 5, + LSM6DSO_XL_ODR_417Hz = 6, + LSM6DSO_XL_ODR_833Hz = 7, + LSM6DSO_XL_ODR_1667Hz = 8, + LSM6DSO_XL_ODR_3333Hz = 9, + LSM6DSO_XL_ODR_6667Hz = 10, + LSM6DSO_XL_ODR_1Hz6 = 11, /* (low power only) */ +} lsm6dso_odr_xl_t; +int32_t lsm6dso_xl_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_odr_xl_t val); +int32_t lsm6dso_xl_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_odr_xl_t *val); + +typedef enum +{ + LSM6DSO_250dps = 0, + LSM6DSO_125dps = 1, + LSM6DSO_500dps = 2, + LSM6DSO_1000dps = 4, + LSM6DSO_2000dps = 6, +} lsm6dso_fs_g_t; +int32_t lsm6dso_gy_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_g_t val); +int32_t lsm6dso_gy_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_g_t *val); + +typedef enum +{ + LSM6DSO_GY_ODR_OFF = 0, + LSM6DSO_GY_ODR_12Hz5 = 1, + LSM6DSO_GY_ODR_26Hz = 2, + LSM6DSO_GY_ODR_52Hz = 3, + LSM6DSO_GY_ODR_104Hz = 4, + LSM6DSO_GY_ODR_208Hz = 5, + LSM6DSO_GY_ODR_417Hz = 6, + LSM6DSO_GY_ODR_833Hz = 7, + LSM6DSO_GY_ODR_1667Hz = 8, + LSM6DSO_GY_ODR_3333Hz = 9, + LSM6DSO_GY_ODR_6667Hz = 10, +} lsm6dso_odr_g_t; +int32_t lsm6dso_gy_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_odr_g_t val); +int32_t lsm6dso_gy_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_odr_g_t *val); + +int32_t lsm6dso_block_data_update_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_block_data_update_get(stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DSO_LSb_1mg = 0, + LSM6DSO_LSb_16mg = 1, +} lsm6dso_usr_off_w_t; +int32_t lsm6dso_xl_offset_weight_set(stmdev_ctx_t *ctx, + lsm6dso_usr_off_w_t val); +int32_t lsm6dso_xl_offset_weight_get(stmdev_ctx_t *ctx, + lsm6dso_usr_off_w_t *val); + +typedef enum +{ + LSM6DSO_HIGH_PERFORMANCE_MD = 0, + LSM6DSO_LOW_NORMAL_POWER_MD = 1, + LSM6DSO_ULTRA_LOW_POWER_MD = 2, +} lsm6dso_xl_hm_mode_t; +int32_t lsm6dso_xl_power_mode_set(stmdev_ctx_t *ctx, + lsm6dso_xl_hm_mode_t val); +int32_t lsm6dso_xl_power_mode_get(stmdev_ctx_t *ctx, + lsm6dso_xl_hm_mode_t *val); + +typedef enum +{ + LSM6DSO_GY_HIGH_PERFORMANCE = 0, + LSM6DSO_GY_NORMAL = 1, +} lsm6dso_g_hm_mode_t; +int32_t lsm6dso_gy_power_mode_set(stmdev_ctx_t *ctx, + lsm6dso_g_hm_mode_t val); +int32_t lsm6dso_gy_power_mode_get(stmdev_ctx_t *ctx, + lsm6dso_g_hm_mode_t *val); + +int32_t lsm6dso_status_reg_get(stmdev_ctx_t *ctx, + lsm6dso_status_reg_t *val); + +int32_t lsm6dso_xl_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_gy_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_temp_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_xl_usr_offset_x_set(stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lsm6dso_xl_usr_offset_x_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lsm6dso_xl_usr_offset_y_set(stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lsm6dso_xl_usr_offset_y_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lsm6dso_xl_usr_offset_z_set(stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lsm6dso_xl_usr_offset_z_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lsm6dso_xl_usr_offset_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_xl_usr_offset_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_timestamp_rst(stmdev_ctx_t *ctx); + +int32_t lsm6dso_timestamp_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_timestamp_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_timestamp_raw_get(stmdev_ctx_t *ctx, uint32_t *val); + +typedef enum +{ + LSM6DSO_NO_ROUND = 0, + LSM6DSO_ROUND_XL = 1, + LSM6DSO_ROUND_GY = 2, + LSM6DSO_ROUND_GY_XL = 3, +} lsm6dso_rounding_t; +int32_t lsm6dso_rounding_mode_set(stmdev_ctx_t *ctx, + lsm6dso_rounding_t val); +int32_t lsm6dso_rounding_mode_get(stmdev_ctx_t *ctx, + lsm6dso_rounding_t *val); + +int32_t lsm6dso_temperature_raw_get(stmdev_ctx_t *ctx, int16_t *val); + +int32_t lsm6dso_angular_rate_raw_get(stmdev_ctx_t *ctx, + int16_t *val); + +int32_t lsm6dso_acceleration_raw_get(stmdev_ctx_t *ctx, + int16_t *val); + +int32_t lsm6dso_fifo_out_raw_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lsm6dso_number_of_steps_get(stmdev_ctx_t *ctx, uint16_t *val); + +int32_t lsm6dso_steps_reset(stmdev_ctx_t *ctx); + +int32_t lsm6dso_odr_cal_reg_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_odr_cal_reg_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_USER_BANK = 0, + LSM6DSO_SENSOR_HUB_BANK = 1, + LSM6DSO_EMBEDDED_FUNC_BANK = 2, +} lsm6dso_reg_access_t; +int32_t lsm6dso_mem_bank_set(stmdev_ctx_t *ctx, + lsm6dso_reg_access_t val); +int32_t lsm6dso_mem_bank_get(stmdev_ctx_t *ctx, + lsm6dso_reg_access_t *val); + +int32_t lsm6dso_ln_pg_write_byte(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *val); +int32_t lsm6dso_ln_pg_read_byte(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *val); +int32_t lsm6dso_ln_pg_write(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *buf, uint8_t len); +int32_t lsm6dso_ln_pg_read(stmdev_ctx_t *ctx, uint16_t address, + uint8_t *val); + +typedef enum +{ + LSM6DSO_DRDY_LATCHED = 0, + LSM6DSO_DRDY_PULSED = 1, +} lsm6dso_dataready_pulsed_t; +int32_t lsm6dso_data_ready_mode_set(stmdev_ctx_t *ctx, + lsm6dso_dataready_pulsed_t val); +int32_t lsm6dso_data_ready_mode_get(stmdev_ctx_t *ctx, + lsm6dso_dataready_pulsed_t *val); + +int32_t lsm6dso_device_id_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lsm6dso_reset_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_reset_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_auto_increment_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_auto_increment_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_boot_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_boot_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_XL_ST_DISABLE = 0, + LSM6DSO_XL_ST_POSITIVE = 1, + LSM6DSO_XL_ST_NEGATIVE = 2, +} lsm6dso_st_xl_t; +int32_t lsm6dso_xl_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_xl_t val); +int32_t lsm6dso_xl_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_xl_t *val); + +typedef enum +{ + LSM6DSO_GY_ST_DISABLE = 0, + LSM6DSO_GY_ST_POSITIVE = 1, + LSM6DSO_GY_ST_NEGATIVE = 3, +} lsm6dso_st_g_t; +int32_t lsm6dso_gy_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_g_t val); +int32_t lsm6dso_gy_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_g_t *val); + +int32_t lsm6dso_xl_filter_lp2_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_xl_filter_lp2_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_gy_filter_lp1_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_gy_filter_lp1_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_filter_settling_mask_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_filter_settling_mask_get(stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DSO_ULTRA_LIGHT = 0, + LSM6DSO_VERY_LIGHT = 1, + LSM6DSO_LIGHT = 2, + LSM6DSO_MEDIUM = 3, + LSM6DSO_STRONG = 4, /* not available for data rate > 1k670Hz */ + LSM6DSO_VERY_STRONG = 5, /* not available for data rate > 1k670Hz */ + LSM6DSO_AGGRESSIVE = 6, /* not available for data rate > 1k670Hz */ + LSM6DSO_XTREME = 7, /* not available for data rate > 1k670Hz */ +} lsm6dso_ftype_t; +int32_t lsm6dso_gy_lp1_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_ftype_t val); +int32_t lsm6dso_gy_lp1_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_ftype_t *val); + +int32_t lsm6dso_xl_lp2_on_6d_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_xl_lp2_on_6d_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_HP_PATH_DISABLE_ON_OUT = 0x00, + LSM6DSO_SLOPE_ODR_DIV_4 = 0x10, + LSM6DSO_HP_ODR_DIV_10 = 0x11, + LSM6DSO_HP_ODR_DIV_20 = 0x12, + LSM6DSO_HP_ODR_DIV_45 = 0x13, + LSM6DSO_HP_ODR_DIV_100 = 0x14, + LSM6DSO_HP_ODR_DIV_200 = 0x15, + LSM6DSO_HP_ODR_DIV_400 = 0x16, + LSM6DSO_HP_ODR_DIV_800 = 0x17, + LSM6DSO_HP_REF_MD_ODR_DIV_10 = 0x31, + LSM6DSO_HP_REF_MD_ODR_DIV_20 = 0x32, + LSM6DSO_HP_REF_MD_ODR_DIV_45 = 0x33, + LSM6DSO_HP_REF_MD_ODR_DIV_100 = 0x34, + LSM6DSO_HP_REF_MD_ODR_DIV_200 = 0x35, + LSM6DSO_HP_REF_MD_ODR_DIV_400 = 0x36, + LSM6DSO_HP_REF_MD_ODR_DIV_800 = 0x37, + LSM6DSO_LP_ODR_DIV_10 = 0x01, + LSM6DSO_LP_ODR_DIV_20 = 0x02, + LSM6DSO_LP_ODR_DIV_45 = 0x03, + LSM6DSO_LP_ODR_DIV_100 = 0x04, + LSM6DSO_LP_ODR_DIV_200 = 0x05, + LSM6DSO_LP_ODR_DIV_400 = 0x06, + LSM6DSO_LP_ODR_DIV_800 = 0x07, +} lsm6dso_hp_slope_xl_en_t; +int32_t lsm6dso_xl_hp_path_on_out_set(stmdev_ctx_t *ctx, + lsm6dso_hp_slope_xl_en_t val); +int32_t lsm6dso_xl_hp_path_on_out_get(stmdev_ctx_t *ctx, + lsm6dso_hp_slope_xl_en_t *val); + +int32_t lsm6dso_xl_fast_settling_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_xl_fast_settling_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_USE_SLOPE = 0, + LSM6DSO_USE_HPF = 1, +} lsm6dso_slope_fds_t; +int32_t lsm6dso_xl_hp_path_internal_set(stmdev_ctx_t *ctx, + lsm6dso_slope_fds_t val); +int32_t lsm6dso_xl_hp_path_internal_get(stmdev_ctx_t *ctx, + lsm6dso_slope_fds_t *val); + +typedef enum +{ + LSM6DSO_HP_FILTER_NONE = 0x00, + LSM6DSO_HP_FILTER_16mHz = 0x80, + LSM6DSO_HP_FILTER_65mHz = 0x81, + LSM6DSO_HP_FILTER_260mHz = 0x82, + LSM6DSO_HP_FILTER_1Hz04 = 0x83, +} lsm6dso_hpm_g_t; +int32_t lsm6dso_gy_hp_path_internal_set(stmdev_ctx_t *ctx, + lsm6dso_hpm_g_t val); +int32_t lsm6dso_gy_hp_path_internal_get(stmdev_ctx_t *ctx, + lsm6dso_hpm_g_t *val); + +typedef enum +{ + LSM6DSO_AUX_PULL_UP_DISC = 0, + LSM6DSO_AUX_PULL_UP_CONNECT = 1, +} lsm6dso_ois_pu_dis_t; +int32_t lsm6dso_aux_sdo_ocs_mode_set(stmdev_ctx_t *ctx, + lsm6dso_ois_pu_dis_t val); +int32_t lsm6dso_aux_sdo_ocs_mode_get(stmdev_ctx_t *ctx, + lsm6dso_ois_pu_dis_t *val); + +typedef enum +{ + LSM6DSO_AUX_ON = 1, + LSM6DSO_AUX_ON_BY_AUX_INTERFACE = 0, +} lsm6dso_ois_on_t; +int32_t lsm6dso_aux_pw_on_ctrl_set(stmdev_ctx_t *ctx, + lsm6dso_ois_on_t val); +int32_t lsm6dso_aux_pw_on_ctrl_get(stmdev_ctx_t *ctx, + lsm6dso_ois_on_t *val); + +typedef enum +{ + LSM6DSO_USE_SAME_XL_FS = 0, + LSM6DSO_USE_DIFFERENT_XL_FS = 1, +} lsm6dso_xl_fs_mode_t; +int32_t lsm6dso_aux_xl_fs_mode_set(stmdev_ctx_t *ctx, + lsm6dso_xl_fs_mode_t val); +int32_t lsm6dso_aux_xl_fs_mode_get(stmdev_ctx_t *ctx, + lsm6dso_xl_fs_mode_t *val); + +int32_t lsm6dso_aux_status_reg_get(stmdev_ctx_t *ctx, + lsm6dso_status_spiaux_t *val); + +int32_t lsm6dso_aux_xl_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_aux_gy_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_aux_gy_flag_settling_get(stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DSO_AUX_XL_DISABLE = 0, + LSM6DSO_AUX_XL_POS = 1, + LSM6DSO_AUX_XL_NEG = 2, +} lsm6dso_st_xl_ois_t; +int32_t lsm6dso_aux_xl_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_xl_ois_t val); +int32_t lsm6dso_aux_xl_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_xl_ois_t *val); + +typedef enum +{ + LSM6DSO_AUX_DEN_ACTIVE_LOW = 0, + LSM6DSO_AUX_DEN_ACTIVE_HIGH = 1, +} lsm6dso_den_lh_ois_t; +int32_t lsm6dso_aux_den_polarity_set(stmdev_ctx_t *ctx, + lsm6dso_den_lh_ois_t val); +int32_t lsm6dso_aux_den_polarity_get(stmdev_ctx_t *ctx, + lsm6dso_den_lh_ois_t *val); + +typedef enum +{ + LSM6DSO_AUX_DEN_DISABLE = 0, + LSM6DSO_AUX_DEN_LEVEL_LATCH = 3, + LSM6DSO_AUX_DEN_LEVEL_TRIG = 2, +} lsm6dso_lvl2_ois_t; +int32_t lsm6dso_aux_den_mode_set(stmdev_ctx_t *ctx, + lsm6dso_lvl2_ois_t val); +int32_t lsm6dso_aux_den_mode_get(stmdev_ctx_t *ctx, + lsm6dso_lvl2_ois_t *val); + +int32_t lsm6dso_aux_drdy_on_int2_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_aux_drdy_on_int2_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_AUX_DISABLE = 0, + LSM6DSO_MODE_3_GY = 1, + LSM6DSO_MODE_4_GY_XL = 3, +} lsm6dso_ois_en_spi2_t; +int32_t lsm6dso_aux_mode_set(stmdev_ctx_t *ctx, + lsm6dso_ois_en_spi2_t val); +int32_t lsm6dso_aux_mode_get(stmdev_ctx_t *ctx, + lsm6dso_ois_en_spi2_t *val); + +typedef enum +{ + LSM6DSO_250dps_AUX = 0, + LSM6DSO_125dps_AUX = 1, + LSM6DSO_500dps_AUX = 2, + LSM6DSO_1000dps_AUX = 4, + LSM6DSO_2000dps_AUX = 6, +} lsm6dso_fs_g_ois_t; +int32_t lsm6dso_aux_gy_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_g_ois_t val); +int32_t lsm6dso_aux_gy_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_g_ois_t *val); + +typedef enum +{ + LSM6DSO_AUX_SPI_4_WIRE = 0, + LSM6DSO_AUX_SPI_3_WIRE = 1, +} lsm6dso_sim_ois_t; +int32_t lsm6dso_aux_spi_mode_set(stmdev_ctx_t *ctx, + lsm6dso_sim_ois_t val); +int32_t lsm6dso_aux_spi_mode_get(stmdev_ctx_t *ctx, + lsm6dso_sim_ois_t *val); + +typedef enum +{ + LSM6DSO_351Hz39 = 0, + LSM6DSO_236Hz63 = 1, + LSM6DSO_172Hz70 = 2, + LSM6DSO_937Hz91 = 3, +} lsm6dso_ftype_ois_t; +int32_t lsm6dso_aux_gy_lp1_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_ftype_ois_t val); +int32_t lsm6dso_aux_gy_lp1_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_ftype_ois_t *val); + +typedef enum +{ + LSM6DSO_AUX_HP_DISABLE = 0x00, + LSM6DSO_AUX_HP_Hz016 = 0x10, + LSM6DSO_AUX_HP_Hz065 = 0x11, + LSM6DSO_AUX_HP_Hz260 = 0x12, + LSM6DSO_AUX_HP_1Hz040 = 0x13, +} lsm6dso_hpm_ois_t; +int32_t lsm6dso_aux_gy_hp_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_hpm_ois_t val); +int32_t lsm6dso_aux_gy_hp_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_hpm_ois_t *val); + +typedef enum +{ + LSM6DSO_ENABLE_CLAMP = 0, + LSM6DSO_DISABLE_CLAMP = 1, +} lsm6dso_st_ois_clampdis_t; +int32_t lsm6dso_aux_gy_clamp_set(stmdev_ctx_t *ctx, + lsm6dso_st_ois_clampdis_t val); +int32_t lsm6dso_aux_gy_clamp_get(stmdev_ctx_t *ctx, + lsm6dso_st_ois_clampdis_t *val); + +typedef enum +{ + LSM6DSO_AUX_GY_DISABLE = 0, + LSM6DSO_AUX_GY_POS = 1, + LSM6DSO_AUX_GY_NEG = 3, +} lsm6dso_st_ois_t; +int32_t lsm6dso_aux_gy_self_test_set(stmdev_ctx_t *ctx, + lsm6dso_st_ois_t val); +int32_t lsm6dso_aux_gy_self_test_get(stmdev_ctx_t *ctx, + lsm6dso_st_ois_t *val); + +typedef enum +{ + LSM6DSO_289Hz = 0, + LSM6DSO_258Hz = 1, + LSM6DSO_120Hz = 2, + LSM6DSO_65Hz2 = 3, + LSM6DSO_33Hz2 = 4, + LSM6DSO_16Hz6 = 5, + LSM6DSO_8Hz30 = 6, + LSM6DSO_4Hz15 = 7, +} lsm6dso_filter_xl_conf_ois_t; +int32_t lsm6dso_aux_xl_bandwidth_set(stmdev_ctx_t *ctx, + lsm6dso_filter_xl_conf_ois_t val); +int32_t lsm6dso_aux_xl_bandwidth_get(stmdev_ctx_t *ctx, + lsm6dso_filter_xl_conf_ois_t *val); + +typedef enum +{ + LSM6DSO_AUX_2g = 0, + LSM6DSO_AUX_16g = 1, + LSM6DSO_AUX_4g = 2, + LSM6DSO_AUX_8g = 3, +} lsm6dso_fs_xl_ois_t; +int32_t lsm6dso_aux_xl_full_scale_set(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_ois_t val); +int32_t lsm6dso_aux_xl_full_scale_get(stmdev_ctx_t *ctx, + lsm6dso_fs_xl_ois_t *val); + +typedef enum +{ + LSM6DSO_PULL_UP_DISC = 0, + LSM6DSO_PULL_UP_CONNECT = 1, +} lsm6dso_sdo_pu_en_t; +int32_t lsm6dso_sdo_sa0_mode_set(stmdev_ctx_t *ctx, + lsm6dso_sdo_pu_en_t val); +int32_t lsm6dso_sdo_sa0_mode_get(stmdev_ctx_t *ctx, + lsm6dso_sdo_pu_en_t *val); + +typedef enum +{ + LSM6DSO_SPI_4_WIRE = 0, + LSM6DSO_SPI_3_WIRE = 1, +} lsm6dso_sim_t; +int32_t lsm6dso_spi_mode_set(stmdev_ctx_t *ctx, lsm6dso_sim_t val); +int32_t lsm6dso_spi_mode_get(stmdev_ctx_t *ctx, lsm6dso_sim_t *val); + +typedef enum +{ + LSM6DSO_I2C_ENABLE = 0, + LSM6DSO_I2C_DISABLE = 1, +} lsm6dso_i2c_disable_t; +int32_t lsm6dso_i2c_interface_set(stmdev_ctx_t *ctx, + lsm6dso_i2c_disable_t val); +int32_t lsm6dso_i2c_interface_get(stmdev_ctx_t *ctx, + lsm6dso_i2c_disable_t *val); + +typedef enum +{ + LSM6DSO_I3C_DISABLE = 0x80, + LSM6DSO_I3C_ENABLE_T_50us = 0x00, + LSM6DSO_I3C_ENABLE_T_2us = 0x01, + LSM6DSO_I3C_ENABLE_T_1ms = 0x02, + LSM6DSO_I3C_ENABLE_T_25ms = 0x03, +} lsm6dso_i3c_disable_t; +int32_t lsm6dso_i3c_disable_set(stmdev_ctx_t *ctx, + lsm6dso_i3c_disable_t val); +int32_t lsm6dso_i3c_disable_get(stmdev_ctx_t *ctx, + lsm6dso_i3c_disable_t *val); + +typedef enum +{ + LSM6DSO_PULL_DOWN_DISC = 0, + LSM6DSO_PULL_DOWN_CONNECT = 1, +} lsm6dso_int1_pd_en_t; +int32_t lsm6dso_int1_mode_set(stmdev_ctx_t *ctx, + lsm6dso_int1_pd_en_t val); +int32_t lsm6dso_int1_mode_get(stmdev_ctx_t *ctx, + lsm6dso_int1_pd_en_t *val); + +typedef enum +{ + LSM6DSO_PUSH_PULL = 0, + LSM6DSO_OPEN_DRAIN = 1, +} lsm6dso_pp_od_t; +int32_t lsm6dso_pin_mode_set(stmdev_ctx_t *ctx, lsm6dso_pp_od_t val); +int32_t lsm6dso_pin_mode_get(stmdev_ctx_t *ctx, lsm6dso_pp_od_t *val); + +typedef enum +{ + LSM6DSO_ACTIVE_HIGH = 0, + LSM6DSO_ACTIVE_LOW = 1, +} lsm6dso_h_lactive_t; +int32_t lsm6dso_pin_polarity_set(stmdev_ctx_t *ctx, + lsm6dso_h_lactive_t val); +int32_t lsm6dso_pin_polarity_get(stmdev_ctx_t *ctx, + lsm6dso_h_lactive_t *val); + +int32_t lsm6dso_all_on_int1_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_all_on_int1_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_ALL_INT_PULSED = 0, + LSM6DSO_BASE_LATCHED_EMB_PULSED = 1, + LSM6DSO_BASE_PULSED_EMB_LATCHED = 2, + LSM6DSO_ALL_INT_LATCHED = 3, +} lsm6dso_lir_t; +int32_t lsm6dso_int_notification_set(stmdev_ctx_t *ctx, + lsm6dso_lir_t val); +int32_t lsm6dso_int_notification_get(stmdev_ctx_t *ctx, + lsm6dso_lir_t *val); + +typedef enum +{ + LSM6DSO_LSb_FS_DIV_64 = 0, + LSM6DSO_LSb_FS_DIV_256 = 1, +} lsm6dso_wake_ths_w_t; +int32_t lsm6dso_wkup_ths_weight_set(stmdev_ctx_t *ctx, + lsm6dso_wake_ths_w_t val); +int32_t lsm6dso_wkup_ths_weight_get(stmdev_ctx_t *ctx, + lsm6dso_wake_ths_w_t *val); + +int32_t lsm6dso_wkup_threshold_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_wkup_threshold_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_xl_usr_offset_on_wkup_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_xl_usr_offset_on_wkup_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_wkup_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_wkup_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_gy_sleep_mode_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_gy_sleep_mode_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_DRIVE_SLEEP_CHG_EVENT = 0, + LSM6DSO_DRIVE_SLEEP_STATUS = 1, +} lsm6dso_sleep_status_on_int_t; +int32_t lsm6dso_act_pin_notification_set(stmdev_ctx_t *ctx, + lsm6dso_sleep_status_on_int_t val); +int32_t lsm6dso_act_pin_notification_get(stmdev_ctx_t *ctx, + lsm6dso_sleep_status_on_int_t *val); + +typedef enum +{ + LSM6DSO_XL_AND_GY_NOT_AFFECTED = 0, + LSM6DSO_XL_12Hz5_GY_NOT_AFFECTED = 1, + LSM6DSO_XL_12Hz5_GY_SLEEP = 2, + LSM6DSO_XL_12Hz5_GY_PD = 3, +} lsm6dso_inact_en_t; +int32_t lsm6dso_act_mode_set(stmdev_ctx_t *ctx, + lsm6dso_inact_en_t val); +int32_t lsm6dso_act_mode_get(stmdev_ctx_t *ctx, + lsm6dso_inact_en_t *val); + +int32_t lsm6dso_act_sleep_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_act_sleep_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_tap_detection_on_z_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_tap_detection_on_z_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_tap_detection_on_y_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_tap_detection_on_y_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_tap_detection_on_x_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_tap_detection_on_x_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_tap_threshold_x_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_tap_threshold_x_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_XYZ = 0, + LSM6DSO_YXZ = 1, + LSM6DSO_XZY = 2, + LSM6DSO_ZYX = 3, + LSM6DSO_YZX = 5, + LSM6DSO_ZXY = 6, +} lsm6dso_tap_priority_t; +int32_t lsm6dso_tap_axis_priority_set(stmdev_ctx_t *ctx, + lsm6dso_tap_priority_t val); +int32_t lsm6dso_tap_axis_priority_get(stmdev_ctx_t *ctx, + lsm6dso_tap_priority_t *val); + +int32_t lsm6dso_tap_threshold_y_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_tap_threshold_y_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_tap_threshold_z_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_tap_threshold_z_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_tap_shock_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_tap_shock_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_tap_quiet_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_tap_quiet_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_tap_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_tap_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_ONLY_SINGLE = 0, + LSM6DSO_BOTH_SINGLE_DOUBLE = 1, +} lsm6dso_single_double_tap_t; +int32_t lsm6dso_tap_mode_set(stmdev_ctx_t *ctx, + lsm6dso_single_double_tap_t val); +int32_t lsm6dso_tap_mode_get(stmdev_ctx_t *ctx, + lsm6dso_single_double_tap_t *val); + +typedef enum +{ + LSM6DSO_DEG_80 = 0, + LSM6DSO_DEG_70 = 1, + LSM6DSO_DEG_60 = 2, + LSM6DSO_DEG_50 = 3, +} lsm6dso_sixd_ths_t; +int32_t lsm6dso_6d_threshold_set(stmdev_ctx_t *ctx, + lsm6dso_sixd_ths_t val); +int32_t lsm6dso_6d_threshold_get(stmdev_ctx_t *ctx, + lsm6dso_sixd_ths_t *val); + +int32_t lsm6dso_4d_mode_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_4d_mode_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_FF_TSH_156mg = 0, + LSM6DSO_FF_TSH_219mg = 1, + LSM6DSO_FF_TSH_250mg = 2, + LSM6DSO_FF_TSH_312mg = 3, + LSM6DSO_FF_TSH_344mg = 4, + LSM6DSO_FF_TSH_406mg = 5, + LSM6DSO_FF_TSH_469mg = 6, + LSM6DSO_FF_TSH_500mg = 7, +} lsm6dso_ff_ths_t; +int32_t lsm6dso_ff_threshold_set(stmdev_ctx_t *ctx, + lsm6dso_ff_ths_t val); +int32_t lsm6dso_ff_threshold_get(stmdev_ctx_t *ctx, + lsm6dso_ff_ths_t *val); + +int32_t lsm6dso_ff_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_ff_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_fifo_watermark_set(stmdev_ctx_t *ctx, uint16_t val); +int32_t lsm6dso_fifo_watermark_get(stmdev_ctx_t *ctx, uint16_t *val); + +int32_t lsm6dso_compression_algo_init_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_compression_algo_init_get(stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LSM6DSO_CMP_DISABLE = 0x00, + LSM6DSO_CMP_ALWAYS = 0x04, + LSM6DSO_CMP_8_TO_1 = 0x05, + LSM6DSO_CMP_16_TO_1 = 0x06, + LSM6DSO_CMP_32_TO_1 = 0x07, +} lsm6dso_uncoptr_rate_t; +int32_t lsm6dso_compression_algo_set(stmdev_ctx_t *ctx, + lsm6dso_uncoptr_rate_t val); +int32_t lsm6dso_compression_algo_get(stmdev_ctx_t *ctx, + lsm6dso_uncoptr_rate_t *val); + +int32_t lsm6dso_fifo_virtual_sens_odr_chg_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_fifo_virtual_sens_odr_chg_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_compression_algo_real_time_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_compression_algo_real_time_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_fifo_stop_on_wtm_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_fifo_stop_on_wtm_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_XL_NOT_BATCHED = 0, + LSM6DSO_XL_BATCHED_AT_12Hz5 = 1, + LSM6DSO_XL_BATCHED_AT_26Hz = 2, + LSM6DSO_XL_BATCHED_AT_52Hz = 3, + LSM6DSO_XL_BATCHED_AT_104Hz = 4, + LSM6DSO_XL_BATCHED_AT_208Hz = 5, + LSM6DSO_XL_BATCHED_AT_417Hz = 6, + LSM6DSO_XL_BATCHED_AT_833Hz = 7, + LSM6DSO_XL_BATCHED_AT_1667Hz = 8, + LSM6DSO_XL_BATCHED_AT_3333Hz = 9, + LSM6DSO_XL_BATCHED_AT_6667Hz = 10, + LSM6DSO_XL_BATCHED_AT_6Hz5 = 11, +} lsm6dso_bdr_xl_t; +int32_t lsm6dso_fifo_xl_batch_set(stmdev_ctx_t *ctx, + lsm6dso_bdr_xl_t val); +int32_t lsm6dso_fifo_xl_batch_get(stmdev_ctx_t *ctx, + lsm6dso_bdr_xl_t *val); + +typedef enum +{ + LSM6DSO_GY_NOT_BATCHED = 0, + LSM6DSO_GY_BATCHED_AT_12Hz5 = 1, + LSM6DSO_GY_BATCHED_AT_26Hz = 2, + LSM6DSO_GY_BATCHED_AT_52Hz = 3, + LSM6DSO_GY_BATCHED_AT_104Hz = 4, + LSM6DSO_GY_BATCHED_AT_208Hz = 5, + LSM6DSO_GY_BATCHED_AT_417Hz = 6, + LSM6DSO_GY_BATCHED_AT_833Hz = 7, + LSM6DSO_GY_BATCHED_AT_1667Hz = 8, + LSM6DSO_GY_BATCHED_AT_3333Hz = 9, + LSM6DSO_GY_BATCHED_AT_6667Hz = 10, + LSM6DSO_GY_BATCHED_AT_6Hz5 = 11, +} lsm6dso_bdr_gy_t; +int32_t lsm6dso_fifo_gy_batch_set(stmdev_ctx_t *ctx, + lsm6dso_bdr_gy_t val); +int32_t lsm6dso_fifo_gy_batch_get(stmdev_ctx_t *ctx, + lsm6dso_bdr_gy_t *val); + +typedef enum +{ + LSM6DSO_BYPASS_MODE = 0, + LSM6DSO_FIFO_MODE = 1, + LSM6DSO_STREAM_TO_FIFO_MODE = 3, + LSM6DSO_BYPASS_TO_STREAM_MODE = 4, + LSM6DSO_STREAM_MODE = 6, + LSM6DSO_BYPASS_TO_FIFO_MODE = 7, +} lsm6dso_fifo_mode_t; +int32_t lsm6dso_fifo_mode_set(stmdev_ctx_t *ctx, + lsm6dso_fifo_mode_t val); +int32_t lsm6dso_fifo_mode_get(stmdev_ctx_t *ctx, + lsm6dso_fifo_mode_t *val); + +typedef enum +{ + LSM6DSO_TEMP_NOT_BATCHED = 0, + LSM6DSO_TEMP_BATCHED_AT_1Hz6 = 1, + LSM6DSO_TEMP_BATCHED_AT_12Hz5 = 2, + LSM6DSO_TEMP_BATCHED_AT_52Hz = 3, +} lsm6dso_odr_t_batch_t; +int32_t lsm6dso_fifo_temp_batch_set(stmdev_ctx_t *ctx, + lsm6dso_odr_t_batch_t val); +int32_t lsm6dso_fifo_temp_batch_get(stmdev_ctx_t *ctx, + lsm6dso_odr_t_batch_t *val); + +typedef enum +{ + LSM6DSO_NO_DECIMATION = 0, + LSM6DSO_DEC_1 = 1, + LSM6DSO_DEC_8 = 2, + LSM6DSO_DEC_32 = 3, +} lsm6dso_odr_ts_batch_t; +int32_t lsm6dso_fifo_timestamp_decimation_set(stmdev_ctx_t *ctx, + lsm6dso_odr_ts_batch_t val); +int32_t lsm6dso_fifo_timestamp_decimation_get(stmdev_ctx_t *ctx, + lsm6dso_odr_ts_batch_t *val); + +typedef enum +{ + LSM6DSO_XL_BATCH_EVENT = 0, + LSM6DSO_GYRO_BATCH_EVENT = 1, +} lsm6dso_trig_counter_bdr_t; + +typedef enum +{ + LSM6DSO_GYRO_NC_TAG = 1, + LSM6DSO_XL_NC_TAG, + LSM6DSO_TEMPERATURE_TAG, + LSM6DSO_TIMESTAMP_TAG, + LSM6DSO_CFG_CHANGE_TAG, + LSM6DSO_XL_NC_T_2_TAG, + LSM6DSO_XL_NC_T_1_TAG, + LSM6DSO_XL_2XC_TAG, + LSM6DSO_XL_3XC_TAG, + LSM6DSO_GYRO_NC_T_2_TAG, + LSM6DSO_GYRO_NC_T_1_TAG, + LSM6DSO_GYRO_2XC_TAG, + LSM6DSO_GYRO_3XC_TAG, + LSM6DSO_SENSORHUB_SLAVE0_TAG, + LSM6DSO_SENSORHUB_SLAVE1_TAG, + LSM6DSO_SENSORHUB_SLAVE2_TAG, + LSM6DSO_SENSORHUB_SLAVE3_TAG, + LSM6DSO_STEP_CPUNTER_TAG, + LSM6DSO_GAME_ROTATION_TAG, + LSM6DSO_GEOMAG_ROTATION_TAG, + LSM6DSO_ROTATION_TAG, + LSM6DSO_SENSORHUB_NACK_TAG = 0x19, +} lsm6dso_fifo_tag_t; +int32_t lsm6dso_fifo_cnt_event_batch_set(stmdev_ctx_t *ctx, + lsm6dso_trig_counter_bdr_t val); +int32_t lsm6dso_fifo_cnt_event_batch_get(stmdev_ctx_t *ctx, + lsm6dso_trig_counter_bdr_t *val); + +int32_t lsm6dso_rst_batch_counter_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_rst_batch_counter_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_batch_counter_threshold_set(stmdev_ctx_t *ctx, + uint16_t val); +int32_t lsm6dso_batch_counter_threshold_get(stmdev_ctx_t *ctx, + uint16_t *val); + +int32_t lsm6dso_fifo_data_level_get(stmdev_ctx_t *ctx, uint16_t *val); + +int32_t lsm6dso_fifo_status_get(stmdev_ctx_t *ctx, + lsm6dso_fifo_status2_t *val); + +int32_t lsm6dso_fifo_full_flag_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_fifo_ovr_flag_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_fifo_wtm_flag_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_fifo_sensor_tag_get(stmdev_ctx_t *ctx, + lsm6dso_fifo_tag_t *val); + +int32_t lsm6dso_fifo_pedo_batch_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_fifo_pedo_batch_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_sh_batch_slave_0_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_sh_batch_slave_0_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_sh_batch_slave_1_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_sh_batch_slave_1_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_sh_batch_slave_2_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_sh_batch_slave_2_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_sh_batch_slave_3_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_sh_batch_slave_3_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_DEN_DISABLE = 0, + LSM6DSO_LEVEL_FIFO = 6, + LSM6DSO_LEVEL_LETCHED = 3, + LSM6DSO_LEVEL_TRIGGER = 2, + LSM6DSO_EDGE_TRIGGER = 4, +} lsm6dso_den_mode_t; +int32_t lsm6dso_den_mode_set(stmdev_ctx_t *ctx, + lsm6dso_den_mode_t val); +int32_t lsm6dso_den_mode_get(stmdev_ctx_t *ctx, + lsm6dso_den_mode_t *val); + +typedef enum +{ + LSM6DSO_DEN_ACT_LOW = 0, + LSM6DSO_DEN_ACT_HIGH = 1, +} lsm6dso_den_lh_t; +int32_t lsm6dso_den_polarity_set(stmdev_ctx_t *ctx, + lsm6dso_den_lh_t val); +int32_t lsm6dso_den_polarity_get(stmdev_ctx_t *ctx, + lsm6dso_den_lh_t *val); + +typedef enum +{ + LSM6DSO_STAMP_IN_GY_DATA = 0, + LSM6DSO_STAMP_IN_XL_DATA = 1, + LSM6DSO_STAMP_IN_GY_XL_DATA = 2, +} lsm6dso_den_xl_g_t; +int32_t lsm6dso_den_enable_set(stmdev_ctx_t *ctx, + lsm6dso_den_xl_g_t val); +int32_t lsm6dso_den_enable_get(stmdev_ctx_t *ctx, + lsm6dso_den_xl_g_t *val); + +int32_t lsm6dso_den_mark_axis_x_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_den_mark_axis_x_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_den_mark_axis_y_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_den_mark_axis_y_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_den_mark_axis_z_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_den_mark_axis_z_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_PEDO_BASE_MODE = 0x00, + LSM6DSO_FALSE_STEP_REJ = 0x10, + LSM6DSO_FALSE_STEP_REJ_ADV_MODE = 0x30, +} lsm6dso_pedo_md_t; +int32_t lsm6dso_pedo_sens_set(stmdev_ctx_t *ctx, + lsm6dso_pedo_md_t val); +int32_t lsm6dso_pedo_sens_get(stmdev_ctx_t *ctx, + lsm6dso_pedo_md_t *val); + +int32_t lsm6dso_pedo_step_detect_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_pedo_debounce_steps_set(stmdev_ctx_t *ctx, + uint8_t *buff); +int32_t lsm6dso_pedo_debounce_steps_get(stmdev_ctx_t *ctx, + uint8_t *buff); + +int32_t lsm6dso_pedo_steps_period_set(stmdev_ctx_t *ctx, + uint16_t val); +int32_t lsm6dso_pedo_steps_period_get(stmdev_ctx_t *ctx, + uint16_t *val); + +typedef enum +{ + LSM6DSO_EVERY_STEP = 0, + LSM6DSO_COUNT_OVERFLOW = 1, +} lsm6dso_carry_count_en_t; +int32_t lsm6dso_pedo_int_mode_set(stmdev_ctx_t *ctx, + lsm6dso_carry_count_en_t val); +int32_t lsm6dso_pedo_int_mode_get(stmdev_ctx_t *ctx, + lsm6dso_carry_count_en_t *val); + +int32_t lsm6dso_motion_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_tilt_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_mag_sensitivity_set(stmdev_ctx_t *ctx, uint16_t val); +int32_t lsm6dso_mag_sensitivity_get(stmdev_ctx_t *ctx, uint16_t *val); + +int32_t lsm6dso_mag_offset_set(stmdev_ctx_t *ctx, int16_t *val); +int32_t lsm6dso_mag_offset_get(stmdev_ctx_t *ctx, int16_t *val); + +int32_t lsm6dso_mag_soft_iron_set(stmdev_ctx_t *ctx, int16_t *val); +int32_t lsm6dso_mag_soft_iron_get(stmdev_ctx_t *ctx, int16_t *val); + +typedef enum +{ + LSM6DSO_Z_EQ_Y = 0, + LSM6DSO_Z_EQ_MIN_Y = 1, + LSM6DSO_Z_EQ_X = 2, + LSM6DSO_Z_EQ_MIN_X = 3, + LSM6DSO_Z_EQ_MIN_Z = 4, + LSM6DSO_Z_EQ_Z = 5, +} lsm6dso_mag_z_axis_t; +int32_t lsm6dso_mag_z_orient_set(stmdev_ctx_t *ctx, + lsm6dso_mag_z_axis_t val); +int32_t lsm6dso_mag_z_orient_get(stmdev_ctx_t *ctx, + lsm6dso_mag_z_axis_t *val); + +typedef enum +{ + LSM6DSO_Y_EQ_Y = 0, + LSM6DSO_Y_EQ_MIN_Y = 1, + LSM6DSO_Y_EQ_X = 2, + LSM6DSO_Y_EQ_MIN_X = 3, + LSM6DSO_Y_EQ_MIN_Z = 4, + LSM6DSO_Y_EQ_Z = 5, +} lsm6dso_mag_y_axis_t; +int32_t lsm6dso_mag_y_orient_set(stmdev_ctx_t *ctx, + lsm6dso_mag_y_axis_t val); +int32_t lsm6dso_mag_y_orient_get(stmdev_ctx_t *ctx, + lsm6dso_mag_y_axis_t *val); + +typedef enum +{ + LSM6DSO_X_EQ_Y = 0, + LSM6DSO_X_EQ_MIN_Y = 1, + LSM6DSO_X_EQ_X = 2, + LSM6DSO_X_EQ_MIN_X = 3, + LSM6DSO_X_EQ_MIN_Z = 4, + LSM6DSO_X_EQ_Z = 5, +} lsm6dso_mag_x_axis_t; +int32_t lsm6dso_mag_x_orient_set(stmdev_ctx_t *ctx, + lsm6dso_mag_x_axis_t val); +int32_t lsm6dso_mag_x_orient_get(stmdev_ctx_t *ctx, + lsm6dso_mag_x_axis_t *val); + +int32_t lsm6dso_long_cnt_flag_data_ready_get(stmdev_ctx_t *ctx, + uint8_t *val); + +typedef struct +{ + lsm6dso_fsm_enable_a_t fsm_enable_a; + lsm6dso_fsm_enable_b_t fsm_enable_b; +} lsm6dso_emb_fsm_enable_t; +int32_t lsm6dso_fsm_enable_set(stmdev_ctx_t *ctx, + lsm6dso_emb_fsm_enable_t *val); +int32_t lsm6dso_fsm_enable_get(stmdev_ctx_t *ctx, + lsm6dso_emb_fsm_enable_t *val); + +int32_t lsm6dso_long_cnt_set(stmdev_ctx_t *ctx, uint16_t val); +int32_t lsm6dso_long_cnt_get(stmdev_ctx_t *ctx, uint16_t *val); + +typedef enum +{ + LSM6DSO_LC_NORMAL = 0, + LSM6DSO_LC_CLEAR = 1, + LSM6DSO_LC_CLEAR_DONE = 2, +} lsm6dso_fsm_lc_clr_t; +int32_t lsm6dso_long_clr_set(stmdev_ctx_t *ctx, + lsm6dso_fsm_lc_clr_t val); +int32_t lsm6dso_long_clr_get(stmdev_ctx_t *ctx, + lsm6dso_fsm_lc_clr_t *val); + +typedef struct +{ + lsm6dso_fsm_outs1_t fsm_outs1; + lsm6dso_fsm_outs2_t fsm_outs2; + lsm6dso_fsm_outs3_t fsm_outs3; + lsm6dso_fsm_outs4_t fsm_outs4; + lsm6dso_fsm_outs5_t fsm_outs5; + lsm6dso_fsm_outs6_t fsm_outs6; + lsm6dso_fsm_outs7_t fsm_outs7; + lsm6dso_fsm_outs8_t fsm_outs8; + lsm6dso_fsm_outs9_t fsm_outs9; + lsm6dso_fsm_outs10_t fsm_outs10; + lsm6dso_fsm_outs11_t fsm_outs11; + lsm6dso_fsm_outs12_t fsm_outs12; + lsm6dso_fsm_outs13_t fsm_outs13; + lsm6dso_fsm_outs14_t fsm_outs14; + lsm6dso_fsm_outs15_t fsm_outs15; + lsm6dso_fsm_outs16_t fsm_outs16; +} lsm6dso_fsm_out_t; +int32_t lsm6dso_fsm_out_get(stmdev_ctx_t *ctx, + lsm6dso_fsm_out_t *val); + +typedef enum +{ + LSM6DSO_ODR_FSM_12Hz5 = 0, + LSM6DSO_ODR_FSM_26Hz = 1, + LSM6DSO_ODR_FSM_52Hz = 2, + LSM6DSO_ODR_FSM_104Hz = 3, +} lsm6dso_fsm_odr_t; +int32_t lsm6dso_fsm_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_fsm_odr_t val); +int32_t lsm6dso_fsm_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_fsm_odr_t *val); + +int32_t lsm6dso_fsm_init_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_fsm_init_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lsm6dso_long_cnt_int_value_set(stmdev_ctx_t *ctx, + uint16_t val); +int32_t lsm6dso_long_cnt_int_value_get(stmdev_ctx_t *ctx, + uint16_t *val); + +int32_t lsm6dso_fsm_number_of_programs_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lsm6dso_fsm_number_of_programs_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lsm6dso_fsm_start_address_set(stmdev_ctx_t *ctx, + uint16_t val); +int32_t lsm6dso_fsm_start_address_get(stmdev_ctx_t *ctx, + uint16_t *val); + +int32_t lsm6dso_sh_read_data_raw_get(stmdev_ctx_t *ctx, uint8_t *val, + uint8_t len); + +typedef enum +{ + LSM6DSO_SLV_0 = 0, + LSM6DSO_SLV_0_1 = 1, + LSM6DSO_SLV_0_1_2 = 2, + LSM6DSO_SLV_0_1_2_3 = 3, +} lsm6dso_aux_sens_on_t; +int32_t lsm6dso_sh_slave_connected_set(stmdev_ctx_t *ctx, + lsm6dso_aux_sens_on_t val); +int32_t lsm6dso_sh_slave_connected_get(stmdev_ctx_t *ctx, + lsm6dso_aux_sens_on_t *val); + +int32_t lsm6dso_sh_master_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_sh_master_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_EXT_PULL_UP = 0, + LSM6DSO_INTERNAL_PULL_UP = 1, +} lsm6dso_shub_pu_en_t; +int32_t lsm6dso_sh_pin_mode_set(stmdev_ctx_t *ctx, + lsm6dso_shub_pu_en_t val); +int32_t lsm6dso_sh_pin_mode_get(stmdev_ctx_t *ctx, + lsm6dso_shub_pu_en_t *val); + +int32_t lsm6dso_sh_pass_through_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lsm6dso_sh_pass_through_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_EXT_ON_INT2_PIN = 1, + LSM6DSO_XL_GY_DRDY = 0, +} lsm6dso_start_config_t; +int32_t lsm6dso_sh_syncro_mode_set(stmdev_ctx_t *ctx, + lsm6dso_start_config_t val); +int32_t lsm6dso_sh_syncro_mode_get(stmdev_ctx_t *ctx, + lsm6dso_start_config_t *val); + +typedef enum +{ + LSM6DSO_EACH_SH_CYCLE = 0, + LSM6DSO_ONLY_FIRST_CYCLE = 1, +} lsm6dso_write_once_t; +int32_t lsm6dso_sh_write_mode_set(stmdev_ctx_t *ctx, + lsm6dso_write_once_t val); +int32_t lsm6dso_sh_write_mode_get(stmdev_ctx_t *ctx, + lsm6dso_write_once_t *val); + +int32_t lsm6dso_sh_reset_set(stmdev_ctx_t *ctx); +int32_t lsm6dso_sh_reset_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LSM6DSO_SH_ODR_104Hz = 0, + LSM6DSO_SH_ODR_52Hz = 1, + LSM6DSO_SH_ODR_26Hz = 2, + LSM6DSO_SH_ODR_13Hz = 3, +} lsm6dso_shub_odr_t; +int32_t lsm6dso_sh_data_rate_set(stmdev_ctx_t *ctx, + lsm6dso_shub_odr_t val); +int32_t lsm6dso_sh_data_rate_get(stmdev_ctx_t *ctx, + lsm6dso_shub_odr_t *val); + +typedef struct +{ + uint8_t slv0_add; + uint8_t slv0_subadd; + uint8_t slv0_data; +} lsm6dso_sh_cfg_write_t; +int32_t lsm6dso_sh_cfg_write(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_write_t *val); + +typedef struct +{ + uint8_t slv_add; + uint8_t slv_subadd; + uint8_t slv_len; +} lsm6dso_sh_cfg_read_t; +int32_t lsm6dso_sh_slv0_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val); +int32_t lsm6dso_sh_slv1_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val); +int32_t lsm6dso_sh_slv2_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val); +int32_t lsm6dso_sh_slv3_cfg_read(stmdev_ctx_t *ctx, + lsm6dso_sh_cfg_read_t *val); + +int32_t lsm6dso_sh_status_get(stmdev_ctx_t *ctx, + lsm6dso_status_master_t *val); + + +typedef struct +{ + uint8_t ui; + uint8_t aux; +} lsm6dso_id_t; +int32_t lsm6dso_id_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_id_t *val); + +typedef enum +{ + LSM6DSO_SEL_BY_HW = 0x00, /* bus mode select by HW (SPI 3W disable) */ + LSM6DSO_SPI_4W = 0x06, /* Only SPI: SDO / SDI separated pins */ + LSM6DSO_SPI_3W = 0x07, /* Only SPI: SDO / SDI share the same pin */ + LSM6DSO_I2C = 0x04, /* Only I2C */ + LSM6DSO_I3C_T_50us = 0x02, /* I3C: available time equal to 50 us */ + LSM6DSO_I3C_T_2us = 0x12, /* I3C: available time equal to 2 us */ + LSM6DSO_I3C_T_1ms = 0x22, /* I3C: available time equal to 1 ms */ + LSM6DSO_I3C_T_25ms = 0x32, /* I3C: available time equal to 25 ms */ +} lsm6dso_ui_bus_md_t; + +typedef enum +{ + LSM6DSO_SPI_4W_AUX = 0x00, + LSM6DSO_SPI_3W_AUX = 0x01, +} lsm6dso_aux_bus_md_t; + +typedef struct +{ + lsm6dso_ui_bus_md_t ui_bus_md; + lsm6dso_aux_bus_md_t aux_bus_md; +} lsm6dso_bus_mode_t; +int32_t lsm6dso_bus_mode_set(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_bus_mode_t val); +int32_t lsm6dso_bus_mode_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_bus_mode_t *val); + +typedef enum +{ + LSM6DSO_DRV_RDY = 0x00, /* Initialize the device for driver usage */ + LSM6DSO_BOOT = 0x01, /* Restore calib. param. ( it takes 10ms ) */ + LSM6DSO_RESET = 0x02, /* Reset configuration registers */ + LSM6DSO_FIFO_COMP = 0x04, /* FIFO compression initialization request. */ + LSM6DSO_FSM = 0x08, /* Finite State Machine initialization request */ + LSM6DSO_PEDO = 0x20, /* Pedometer algo initialization request. */ + LSM6DSO_TILT = 0x40, /* Tilt algo initialization request */ + LSM6DSO_SMOTION = 0x80, /* Significant Motion initialization request */ +} lsm6dso_init_t; +int32_t lsm6dso_init_set(stmdev_ctx_t *ctx, lsm6dso_init_t val); + +typedef struct +{ +uint8_t sw_reset : + 1; /* Restoring configuration registers */ + uint8_t boot : 1; /* Restoring calibration parameters */ + uint8_t drdy_xl : 1; /* Accelerometer data ready */ + uint8_t drdy_g : 1; /* Gyroscope data ready */ + uint8_t drdy_temp : 1; /* Temperature data ready */ + uint8_t ois_drdy_xl : 1; /* Accelerometer data ready on OIS */ + uint8_t ois_drdy_g : 1; /* Gyroscope data ready on OIS */ +uint8_t ois_gyro_settling : + 1; /* Gyroscope is in the settling phase */ +} lsm6dso_status_t; +int32_t lsm6dso_status_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_status_t *val); + +typedef struct +{ + uint8_t sdo_sa0_pull_up : 1; /* 1 = pull-up on SDO/SA0 pin */ +uint8_t aux_sdo_ocs_pull_up : + 1; /* 1 = pull-up on OCS_Aux/SDO_Aux pins */ + uint8_t int1_int2_push_pull : 1; /* 1 = push-pull / 0 = open-drain*/ +uint8_t int1_pull_down : + 1; /* 1 = pull-down always disabled (0=auto) */ +} lsm6dso_pin_conf_t; +int32_t lsm6dso_pin_conf_set(stmdev_ctx_t *ctx, + lsm6dso_pin_conf_t val); +int32_t lsm6dso_pin_conf_get(stmdev_ctx_t *ctx, + lsm6dso_pin_conf_t *val); + +typedef struct +{ + uint8_t active_low : 1; /* 1 = active low / 0 = active high */ +uint8_t base_latched : + 1; /* base functions are: FF, WU, 6D, Tap, Act/Inac */ +uint8_t emb_latched : + 1; /* emb functions are: Pedo, Tilt, SMot, Timestamp */ +} lsm6dso_int_mode_t; +int32_t lsm6dso_interrupt_mode_set(stmdev_ctx_t *ctx, + lsm6dso_int_mode_t val); +int32_t lsm6dso_interrupt_mode_get(stmdev_ctx_t *ctx, + lsm6dso_int_mode_t *val); + +typedef struct +{ + uint8_t drdy_xl : 1; /* Accelerometer data ready */ + uint8_t drdy_g : 1; /* Gyroscope data ready */ +uint8_t drdy_temp : + 1; /* Temperature data ready (1 = int2 pin disable) */ + uint8_t boot : 1; /* Restoring calibration parameters */ + uint8_t fifo_th : 1; /* FIFO threshold reached */ + uint8_t fifo_ovr : 1; /* FIFO overrun */ + uint8_t fifo_full : 1; /* FIFO full */ + uint8_t fifo_bdr : 1; /* FIFO Batch counter threshold reached */ +uint8_t den_flag : + 1; /* external trigger level recognition (DEN) */ + uint8_t sh_endop : 1; /* sensor hub end operation */ +uint8_t timestamp : + 1; /* timestamp overflow (1 = int2 pin disable) */ + uint8_t six_d : 1; /* orientation change (6D/4D detection) */ + uint8_t double_tap : 1; /* double-tap event */ + uint8_t free_fall : 1; /* free fall event */ + uint8_t wake_up : 1; /* wake up event */ + uint8_t single_tap : 1; /* single-tap event */ +uint8_t sleep_change : + 1; /* Act/Inact (or Vice-versa) status changed */ + uint8_t step_detector : 1; /* Step detected */ + uint8_t tilt : 1; /* Relative tilt event detected */ + uint8_t sig_mot : 1; /* "significant motion" event detected */ +uint8_t fsm_lc : + 1; /* fsm long counter timeout interrupt event */ + uint8_t fsm1 : 1; /* fsm 1 interrupt event */ + uint8_t fsm2 : 1; /* fsm 2 interrupt event */ + uint8_t fsm3 : 1; /* fsm 3 interrupt event */ + uint8_t fsm4 : 1; /* fsm 4 interrupt event */ + uint8_t fsm5 : 1; /* fsm 5 interrupt event */ + uint8_t fsm6 : 1; /* fsm 6 interrupt event */ + uint8_t fsm7 : 1; /* fsm 7 interrupt event */ + uint8_t fsm8 : 1; /* fsm 8 interrupt event */ + uint8_t fsm9 : 1; /* fsm 9 interrupt event */ + uint8_t fsm10 : 1; /* fsm 10 interrupt event */ + uint8_t fsm11 : 1; /* fsm 11 interrupt event */ + uint8_t fsm12 : 1; /* fsm 12 interrupt event */ + uint8_t fsm13 : 1; /* fsm 13 interrupt event */ + uint8_t fsm14 : 1; /* fsm 14 interrupt event */ + uint8_t fsm15 : 1; /* fsm 15 interrupt event */ + uint8_t fsm16 : 1; /* fsm 16 interrupt event */ + uint8_t mlc1 : 1; /* mlc 1 interrupt event */ + uint8_t mlc2 : 1; /* mlc 2 interrupt event */ + uint8_t mlc3 : 1; /* mlc 3 interrupt event */ + uint8_t mlc4 : 1; /* mlc 4 interrupt event */ + uint8_t mlc5 : 1; /* mlc 5 interrupt event */ + uint8_t mlc6 : 1; /* mlc 6 interrupt event */ + uint8_t mlc7 : 1; /* mlc 7 interrupt event */ + uint8_t mlc8 : 1; /* mlc 8 interrupt event */ +} lsm6dso_pin_int1_route_t; + +int32_t lsm6dso_pin_int1_route_set(stmdev_ctx_t *ctx, + lsm6dso_pin_int1_route_t val); +int32_t lsm6dso_pin_int1_route_get(stmdev_ctx_t *ctx, + lsm6dso_pin_int1_route_t *val); + +typedef struct +{ + uint8_t drdy_ois : 1; /* OIS chain data ready */ + uint8_t drdy_xl : 1; /* Accelerometer data ready */ + uint8_t drdy_g : 1; /* Gyroscope data ready */ + uint8_t drdy_temp : 1; /* Temperature data ready */ + uint8_t fifo_th : 1; /* FIFO threshold reached */ + uint8_t fifo_ovr : 1; /* FIFO overrun */ + uint8_t fifo_full : 1; /* FIFO full */ + uint8_t fifo_bdr : 1; /* FIFO Batch counter threshold reached */ + uint8_t timestamp : 1; /* timestamp overflow */ + uint8_t six_d : 1; /* orientation change (6D/4D detection) */ + uint8_t double_tap : 1; /* double-tap event */ + uint8_t free_fall : 1; /* free fall event */ + uint8_t wake_up : 1; /* wake up event */ + uint8_t single_tap : 1; /* single-tap event */ +uint8_t sleep_change : + 1; /* Act/Inact (or Vice-versa) status changed */ + uint8_t step_detector : 1; /* Step detected */ + uint8_t tilt : 1; /* Relative tilt event detected */ + uint8_t sig_mot : 1; /* "significant motion" event detected */ +uint8_t fsm_lc : + 1; /* fsm long counter timeout interrupt event */ + uint8_t fsm1 : 1; /* fsm 1 interrupt event */ + uint8_t fsm2 : 1; /* fsm 2 interrupt event */ + uint8_t fsm3 : 1; /* fsm 3 interrupt event */ + uint8_t fsm4 : 1; /* fsm 4 interrupt event */ + uint8_t fsm5 : 1; /* fsm 5 interrupt event */ + uint8_t fsm6 : 1; /* fsm 6 interrupt event */ + uint8_t fsm7 : 1; /* fsm 7 interrupt event */ + uint8_t fsm8 : 1; /* fsm 8 interrupt event */ + uint8_t fsm9 : 1; /* fsm 9 interrupt event */ + uint8_t fsm10 : 1; /* fsm 10 interrupt event */ + uint8_t fsm11 : 1; /* fsm 11 interrupt event */ + uint8_t fsm12 : 1; /* fsm 12 interrupt event */ + uint8_t fsm13 : 1; /* fsm 13 interrupt event */ + uint8_t fsm14 : 1; /* fsm 14 interrupt event */ + uint8_t fsm15 : 1; /* fsm 15 interrupt event */ + uint8_t fsm16 : 1; /* fsm 16 interrupt event */ + uint8_t mlc1 : 1; /* mlc 1 interrupt event */ + uint8_t mlc2 : 1; /* mlc 2 interrupt event */ + uint8_t mlc3 : 1; /* mlc 3 interrupt event */ + uint8_t mlc4 : 1; /* mlc 4 interrupt event */ + uint8_t mlc5 : 1; /* mlc 5 interrupt event */ + uint8_t mlc6 : 1; /* mlc 6 interrupt event */ + uint8_t mlc7 : 1; /* mlc 7 interrupt event */ + uint8_t mlc8 : 1; /* mlc 8 interrupt event */ +} lsm6dso_pin_int2_route_t; + +int32_t lsm6dso_pin_int2_route_set(stmdev_ctx_t *ctx, + stmdev_ctx_t *aux_ctx, + lsm6dso_pin_int2_route_t val); +int32_t lsm6dso_pin_int2_route_get(stmdev_ctx_t *ctx, + stmdev_ctx_t *aux_ctx, + lsm6dso_pin_int2_route_t *val); + +typedef struct +{ + uint8_t drdy_xl : 1; /* Accelerometer data ready */ + uint8_t drdy_g : 1; /* Gyroscope data ready */ + uint8_t drdy_temp : 1; /* Temperature data ready */ +uint8_t den_flag : + 1; /* external trigger level recognition (DEN) */ +uint8_t timestamp : + 1; /* timestamp overflow (1 = int2 pin disable) */ + uint8_t free_fall : 1; /* free fall event */ + uint8_t wake_up : 1; /* wake up event */ + uint8_t wake_up_z : 1; /* wake up on Z axis event */ + uint8_t wake_up_y : 1; /* wake up on Y axis event */ + uint8_t wake_up_x : 1; /* wake up on X axis event */ + uint8_t single_tap : 1; /* single-tap event */ + uint8_t double_tap : 1; /* double-tap event */ + uint8_t tap_z : 1; /* single-tap on Z axis event */ + uint8_t tap_y : 1; /* single-tap on Y axis event */ + uint8_t tap_x : 1; /* single-tap on X axis event */ + uint8_t tap_sign : 1; /* sign of tap event (0-pos / 1-neg) */ +uint8_t six_d : + 1; /* orientation change (6D/4D detection) */ +uint8_t six_d_xl : + 1; /* X-axis low 6D/4D event (under threshold) */ +uint8_t six_d_xh : + 1; /* X-axis high 6D/4D event (over threshold) */ +uint8_t six_d_yl : + 1; /* Y-axis low 6D/4D event (under threshold) */ +uint8_t six_d_yh : + 1; /* Y-axis high 6D/4D event (over threshold) */ +uint8_t six_d_zl : + 1; /* Z-axis low 6D/4D event (under threshold) */ +uint8_t six_d_zh : + 1; /* Z-axis high 6D/4D event (over threshold) */ +uint8_t sleep_change : + 1; /* Act/Inact (or Vice-versa) status changed */ +uint8_t sleep_state : + 1; /* Act/Inact status flag (0-Act / 1-Inact) */ + uint8_t step_detector : 1; /* Step detected */ + uint8_t tilt : 1; /* Relative tilt event detected */ +uint8_t sig_mot : + 1; /* "significant motion" event detected */ +uint8_t fsm_lc : + 1; /* fsm long counter timeout interrupt event */ + uint8_t fsm1 : 1; /* fsm 1 interrupt event */ + uint8_t fsm2 : 1; /* fsm 2 interrupt event */ + uint8_t fsm3 : 1; /* fsm 3 interrupt event */ + uint8_t fsm4 : 1; /* fsm 4 interrupt event */ + uint8_t fsm5 : 1; /* fsm 5 interrupt event */ + uint8_t fsm6 : 1; /* fsm 6 interrupt event */ + uint8_t fsm7 : 1; /* fsm 7 interrupt event */ + uint8_t fsm8 : 1; /* fsm 8 interrupt event */ + uint8_t fsm9 : 1; /* fsm 9 interrupt event */ + uint8_t fsm10 : 1; /* fsm 10 interrupt event */ + uint8_t fsm11 : 1; /* fsm 11 interrupt event */ + uint8_t fsm12 : 1; /* fsm 12 interrupt event */ + uint8_t fsm13 : 1; /* fsm 13 interrupt event */ + uint8_t fsm14 : 1; /* fsm 14 interrupt event */ + uint8_t fsm15 : 1; /* fsm 15 interrupt event */ + uint8_t fsm16 : 1; /* fsm 16 interrupt event */ + uint8_t mlc1 : 1; /* mlc 1 interrupt event */ + uint8_t mlc2 : 1; /* mlc 2 interrupt event */ + uint8_t mlc3 : 1; /* mlc 3 interrupt event */ + uint8_t mlc4 : 1; /* mlc 4 interrupt event */ + uint8_t mlc5 : 1; /* mlc 5 interrupt event */ + uint8_t mlc6 : 1; /* mlc 6 interrupt event */ + uint8_t mlc7 : 1; /* mlc 7 interrupt event */ + uint8_t mlc8 : 1; /* mlc 8 interrupt event */ + uint8_t sh_endop : 1; /* sensor hub end operation */ +uint8_t sh_slave0_nack : + 1; /* Not acknowledge on sensor hub slave 0 */ +uint8_t sh_slave1_nack : + 1; /* Not acknowledge on sensor hub slave 1 */ +uint8_t sh_slave2_nack : + 1; /* Not acknowledge on sensor hub slave 2 */ +uint8_t sh_slave3_nack : + 1; /* Not acknowledge on sensor hub slave 3 */ +uint8_t sh_wr_once : + 1; /* "WRITE_ONCE" end on sensor hub slave 0 */ +uint16_t fifo_diff : + 10; /* Number of unread sensor data in FIFO*/ + uint8_t fifo_ovr_latched : 1; /* Latched FIFO overrun status */ +uint8_t fifo_bdr : + 1; /* FIFO Batch counter threshold reached */ + uint8_t fifo_full : 1; /* FIFO full */ + uint8_t fifo_ovr : 1; /* FIFO overrun */ + uint8_t fifo_th : 1; /* FIFO threshold reached */ +} lsm6dso_all_sources_t; +int32_t lsm6dso_all_sources_get(stmdev_ctx_t *ctx, + lsm6dso_all_sources_t *val); + +typedef struct +{ + uint8_t odr_fine_tune; +} dev_cal_t; +int32_t lsm6dso_calibration_get(stmdev_ctx_t *ctx, dev_cal_t *val); + +typedef enum +{ + LSM6DSO_XL_UI_OFF = 0x00, /* in power down */ + LSM6DSO_XL_UI_1Hz6_LP = 0x1B, /* @1Hz6 (low power) */ + LSM6DSO_XL_UI_1Hz6_ULP = 0x2B, /* @1Hz6 (ultra low/Gy, OIS imu off) */ + LSM6DSO_XL_UI_12Hz5_HP = 0x01, /* @12Hz5 (high performance) */ + LSM6DSO_XL_UI_12Hz5_LP = 0x11, /* @12Hz5 (low power) */ + LSM6DSO_XL_UI_12Hz5_ULP = 0x21, /* @12Hz5 (ultra low/Gy, OIS imu off) */ + LSM6DSO_XL_UI_26Hz_HP = 0x02, /* @26Hz (high performance) */ + LSM6DSO_XL_UI_26Hz_LP = 0x12, /* @26Hz (low power) */ + LSM6DSO_XL_UI_26Hz_ULP = 0x22, /* @26Hz (ultra low/Gy, OIS imu off) */ + LSM6DSO_XL_UI_52Hz_HP = 0x03, /* @52Hz (high performance) */ + LSM6DSO_XL_UI_52Hz_LP = 0x13, /* @52Hz (low power) */ + LSM6DSO_XL_UI_52Hz_ULP = 0x23, /* @52Hz (ultra low/Gy, OIS imu off) */ + LSM6DSO_XL_UI_104Hz_HP = 0x04, /* @104Hz (high performance) */ + LSM6DSO_XL_UI_104Hz_NM = 0x14, /* @104Hz (normal mode) */ + LSM6DSO_XL_UI_104Hz_ULP = 0x24, /* @104Hz (ultra low/Gy, OIS imu off) */ + LSM6DSO_XL_UI_208Hz_HP = 0x05, /* @208Hz (high performance) */ + LSM6DSO_XL_UI_208Hz_NM = 0x15, /* @208Hz (normal mode) */ + LSM6DSO_XL_UI_208Hz_ULP = 0x25, /* @208Hz (ultra low/Gy, OIS imu off) */ + LSM6DSO_XL_UI_416Hz_HP = 0x06, /* @416Hz (high performance) */ + LSM6DSO_XL_UI_833Hz_HP = 0x07, /* @833Hz (high performance) */ + LSM6DSO_XL_UI_1667Hz_HP = 0x08, /* @1kHz66 (high performance) */ + LSM6DSO_XL_UI_3333Hz_HP = 0x09, /* @3kHz33 (high performance) */ + LSM6DSO_XL_UI_6667Hz_HP = 0x0A, /* @6kHz66 (high performance) */ +} lsm6dso_odr_xl_ui_t; + +typedef enum +{ + LSM6DSO_XL_UI_2g = 0, + LSM6DSO_XL_UI_4g = 2, + LSM6DSO_XL_UI_8g = 3, + LSM6DSO_XL_UI_16g = 1, /* OIS full scale is also forced to be 16g */ +} lsm6dso_fs_xl_ui_t; + +typedef enum +{ + LSM6DSO_GY_UI_OFF = 0x00, /* gy in power down */ + LSM6DSO_GY_UI_12Hz5_LP = 0x11, /* gy @12Hz5 (low power) */ + LSM6DSO_GY_UI_12Hz5_HP = 0x01, /* gy @12Hz5 (high performance) */ + LSM6DSO_GY_UI_26Hz_LP = 0x12, /* gy @26Hz (low power) */ + LSM6DSO_GY_UI_26Hz_HP = 0x02, /* gy @26Hz (high performance) */ + LSM6DSO_GY_UI_52Hz_LP = 0x13, /* gy @52Hz (low power) */ + LSM6DSO_GY_UI_52Hz_HP = 0x03, /* gy @52Hz (high performance) */ + LSM6DSO_GY_UI_104Hz_NM = 0x14, /* gy @104Hz (low power) */ + LSM6DSO_GY_UI_104Hz_HP = 0x04, /* gy @104Hz (high performance) */ + LSM6DSO_GY_UI_208Hz_NM = 0x15, /* gy @208Hz (low power) */ + LSM6DSO_GY_UI_208Hz_HP = 0x05, /* gy @208Hz (high performance) */ + LSM6DSO_GY_UI_416Hz_HP = 0x06, /* gy @416Hz (high performance) */ + LSM6DSO_GY_UI_833Hz_HP = 0x07, /* gy @833Hz (high performance) */ + LSM6DSO_GY_UI_1667Hz_HP = 0x08, /* gy @1kHz66 (high performance) */ + LSM6DSO_GY_UI_3333Hz_HP = 0x09, /* gy @3kHz33 (high performance) */ + LSM6DSO_GY_UI_6667Hz_HP = 0x0A, /* gy @6kHz66 (high performance) */ +} lsm6dso_odr_g_ui_t; + +typedef enum +{ + LSM6DSO_GY_UI_250dps = 0, + LSM6DSO_GY_UI_125dps = 1, + LSM6DSO_GY_UI_500dps = 2, + LSM6DSO_GY_UI_1000dps = 4, + LSM6DSO_GY_UI_2000dps = 6, +} lsm6dso_fs_g_ui_t; + +typedef enum +{ + LSM6DSO_OIS_ONLY_AUX = 0x00, /* Auxiliary SPI full control */ + LSM6DSO_OIS_MIXED = 0x01, /* Enabling by UI / read-config by AUX */ +} lsm6dso_ctrl_md_t; + +typedef enum +{ + LSM6DSO_XL_OIS_OFF = 0x00, /* in power down */ + LSM6DSO_XL_OIS_6667Hz_HP = 0x01, /* @6kHz OIS imu active/NO ULP on UI */ +} lsm6dso_odr_xl_ois_noaux_t; + +typedef enum +{ + LSM6DSO_XL_OIS_2g = 0, + LSM6DSO_XL_OIS_4g = 2, + LSM6DSO_XL_OIS_8g = 3, + LSM6DSO_XL_OIS_16g = 1, /* UI full scale is also forced to be 16g */ +} lsm6dso_fs_xl_ois_noaux_t; + +typedef enum +{ + LSM6DSO_GY_OIS_OFF = 0x00, /* in power down */ + LSM6DSO_GY_OIS_6667Hz_HP = 0x01, /* @6kHz No Ultra Low Power*/ +} lsm6dso_odr_g_ois_noaux_t; + +typedef enum +{ + LSM6DSO_GY_OIS_250dps = 0, + LSM6DSO_GY_OIS_125dps = 1, + LSM6DSO_GY_OIS_500dps = 2, + LSM6DSO_GY_OIS_1000dps = 4, + LSM6DSO_GY_OIS_2000dps = 6, +} lsm6dso_fs_g_ois_noaux_t; + +typedef enum +{ + LSM6DSO_FSM_DISABLE = 0x00, + LSM6DSO_FSM_XL = 0x01, + LSM6DSO_FSM_GY = 0x02, + LSM6DSO_FSM_XL_GY = 0x03, +} lsm6dso_sens_fsm_t; + +typedef enum +{ + LSM6DSO_FSM_12Hz5 = 0x00, + LSM6DSO_FSM_26Hz = 0x01, + LSM6DSO_FSM_52Hz = 0x02, + LSM6DSO_FSM_104Hz = 0x03, +} lsm6dso_odr_fsm_t; + +typedef struct +{ + struct + { + struct + { + lsm6dso_odr_xl_ui_t odr; + lsm6dso_fs_xl_ui_t fs; + } xl; + struct + { + lsm6dso_odr_g_ui_t odr; + lsm6dso_fs_g_ui_t fs; + } gy; + } ui; + struct + { + lsm6dso_ctrl_md_t ctrl_md; + struct + { + lsm6dso_odr_xl_ois_noaux_t odr; + lsm6dso_fs_xl_ois_noaux_t fs; + } xl; + struct + { + lsm6dso_odr_g_ois_noaux_t odr; + lsm6dso_fs_g_ois_noaux_t fs; + } gy; + } ois; + struct + { + lsm6dso_sens_fsm_t sens; + lsm6dso_odr_fsm_t odr; + } fsm; +} lsm6dso_md_t; +int32_t lsm6dso_mode_set(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_md_t *val); +int32_t lsm6dso_mode_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_md_t *val); +typedef struct +{ + struct + { + struct + { + float_t mg[3]; + int16_t raw[3]; + } xl; + struct + { + float_t mdps[3]; + int16_t raw[3]; + } gy; + struct + { + float_t deg_c; + int16_t raw; + } heat; + } ui; + struct + { + struct + { + float_t mg[3]; + int16_t raw[3]; + } xl; + struct + { + float_t mdps[3]; + int16_t raw[3]; + } gy; + } ois; +} lsm6dso_data_t; +int32_t lsm6dso_data_get(stmdev_ctx_t *ctx, stmdev_ctx_t *aux_ctx, + lsm6dso_md_t *md, lsm6dso_data_t *data); + +typedef struct +{ + uint8_t sig_mot : 1; /* significant motion */ + uint8_t tilt : 1; /* tilt detection */ + uint8_t step : 1; /* step counter/detector */ + uint8_t step_adv : 1; /* step counter advanced mode */ + uint8_t fsm : 1; /* finite state machine */ + uint8_t fifo_compr : 1; /* FIFO compression */ +} lsm6dso_emb_sens_t; +int32_t lsm6dso_embedded_sens_set(stmdev_ctx_t *ctx, + lsm6dso_emb_sens_t *emb_sens); +int32_t lsm6dso_embedded_sens_get(stmdev_ctx_t *ctx, + lsm6dso_emb_sens_t *emb_sens); +int32_t lsm6dso_embedded_sens_off(stmdev_ctx_t *ctx); + +/** + * @} + * + */ + +#ifdef __cplusplus +} +#endif + +#endif /*LSM6DSO_DRIVER_H */ diff --git a/non_catalog_apps/airmouse/tracking/imu/bmi160.c b/non_catalog_apps/airmouse/tracking/imu/bmi160.c index 968dddd4def..9491b6bbc8b 100644 --- a/non_catalog_apps/airmouse/tracking/imu/bmi160.c +++ b/non_catalog_apps/airmouse/tracking/imu/bmi160.c @@ -1,5988 +1,86 @@ -/** -* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. -* -* BSD-3-Clause -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -* -* @file bmi160.c -* @date 2021-10-05 -* @version v3.9.2 -* -*/ +#include "imu.h" +#include "../../lib/bmi160-api/bmi160.h" -#include "bmi160.h" +#define BMI160_TAG "BMI160" +#define BMI160_DEV_ADDR (0x69 << 1) -/* Below look up table follows the enum bmi160_int_types. - * Hence any change should match to the enum bmi160_int_types - */ -const uint8_t int_mask_lookup_table[13] = { - BMI160_INT1_SLOPE_MASK, - BMI160_INT1_SLOPE_MASK, - BMI160_INT2_LOW_STEP_DETECT_MASK, - BMI160_INT1_DOUBLE_TAP_MASK, - BMI160_INT1_SINGLE_TAP_MASK, - BMI160_INT1_ORIENT_MASK, - BMI160_INT1_FLAT_MASK, - BMI160_INT1_HIGH_G_MASK, - BMI160_INT1_LOW_G_MASK, - BMI160_INT1_NO_MOTION_MASK, - BMI160_INT2_DATA_READY_MASK, - BMI160_INT2_FIFO_FULL_MASK, - BMI160_INT2_FIFO_WM_MASK}; +struct bmi160_dev bmi160dev; +struct bmi160_sensor_data bmi160_accel; +struct bmi160_sensor_data bmi160_gyro; -/*********************************************************************/ -/* Static function declarations */ - -/*! - * @brief This API configures the pins to fire the - * interrupt signal when it occurs - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_intr_pin_config(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the any-motion interrupt of the sensor. - * This interrupt occurs when accel values exceeds preset threshold - * for a certain period of time. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_any_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev); - -/*! - * @brief This API sets tap interrupts.Interrupt is fired when - * tap movements happen. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t set_accel_tap_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the data ready interrupt for both accel and gyro. - * This interrupt occurs when new accel and gyro data come. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t set_accel_gyro_data_ready_int( - const struct bmi160_int_settg* int_config, - const struct bmi160_dev* dev); - -/*! - * @brief This API sets the significant motion interrupt of the sensor.This - * interrupt occurs when there is change in user location. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_sig_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev); - -/*! - * @brief This API sets the no motion/slow motion interrupt of the sensor. - * Slow motion is similar to any motion interrupt.No motion interrupt - * occurs when slope bet. two accel values falls below preset threshold - * for preset duration. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_no_motion_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the step detection interrupt.This interrupt - * occurs when the single step causes accel values to go above - * preset threshold. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_step_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the orientation interrupt of the sensor.This - * interrupt occurs when there is orientation change in the sensor - * with respect to gravitational field vector g. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_orientation_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the flat interrupt of the sensor.This interrupt - * occurs in case of flat orientation - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_flat_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the low-g interrupt of the sensor.This interrupt - * occurs during free-fall. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_low_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the high-g interrupt of the sensor.The interrupt - * occurs if the absolute value of acceleration data of any enabled axis - * exceeds the programmed threshold and the sign of the value does not - * change for a preset duration. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t - set_accel_high_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the default configuration parameters of accel & gyro. - * Also maintain the previous state of configurations. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static void default_param_settg(struct bmi160_dev* dev); - -/*! - * @brief This API is used to validate the device structure pointer for - * null conditions. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t null_ptr_check(const struct bmi160_dev* dev); - -/*! - * @brief This API set the accel configuration. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t set_accel_conf(struct bmi160_dev* dev); - -/*! - * @brief This API gets the accel configuration. - * - * @param[out] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t get_accel_conf(struct bmi160_dev* dev); - -/*! - * @brief This API check the accel configuration. - * - * @param[in] data : Pointer to store the updated accel config. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t check_accel_config(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API process the accel odr. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_accel_odr(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API process the accel bandwidth. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_accel_bw(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API process the accel range. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_accel_range(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API checks the invalid settings for ODR & Bw for Accel and Gyro. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t check_invalid_settg(const struct bmi160_dev* dev); - -/*! - * @brief This API set the gyro configuration. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t set_gyro_conf(struct bmi160_dev* dev); - -/*! - * @brief This API get the gyro configuration. - * - * @param[out] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t get_gyro_conf(struct bmi160_dev* dev); - -/*! - * @brief This API check the gyro configuration. - * - * @param[in] data : Pointer to store the updated gyro config. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t check_gyro_config(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API process the gyro odr. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_gyro_odr(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API process the gyro bandwidth. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_gyro_bw(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API process the gyro range. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_gyro_range(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the accel power mode. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t set_accel_pwr(struct bmi160_dev* dev); - -/*! - * @brief This API process the undersampling setting of Accel. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t process_under_sampling(uint8_t* data, const struct bmi160_dev* dev); - -/*! - * @brief This API sets the gyro power mode. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - */ -static int8_t set_gyro_pwr(struct bmi160_dev* dev); - -/*! - * @brief This API reads accel data along with sensor time if time is requested - * by user. Kindly refer the user guide(README.md) for more info. - * - * @param[in] len : len to read no of bytes - * @param[out] accel : Structure pointer to store accel data - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - get_accel_data(uint8_t len, struct bmi160_sensor_data* accel, const struct bmi160_dev* dev); - -/*! - * @brief This API reads accel data along with sensor time if time is requested - * by user. Kindly refer the user guide(README.md) for more info. - * - * @param[in] len : len to read no of bytes - * @param[out] gyro : Structure pointer to store accel data - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - get_gyro_data(uint8_t len, struct bmi160_sensor_data* gyro, const struct bmi160_dev* dev); - -/*! - * @brief This API reads accel and gyro data along with sensor time - * if time is requested by user. - * Kindly refer the user guide(README.md) for more info. - * - * @param[in] len : len to read no of bytes - * @param[out] accel : Structure pointer to store accel data - * @param[out] gyro : Structure pointer to store accel data - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t get_accel_gyro_data( - uint8_t len, - struct bmi160_sensor_data* accel, - struct bmi160_sensor_data* gyro, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the any-motion interrupt for accel. - * - * @param[in] any_motion_int_cfg : Structure instance of - * bmi160_acc_any_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_accel_any_motion_int( - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - struct bmi160_dev* dev); - -/*! - * @brief This API disable the sig-motion interrupt. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t disable_sig_motion_int(const struct bmi160_dev* dev); - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for any-motion interrupt. - * - * @param[in] any_motion_int_cfg : Structure instance of - * bmi160_acc_any_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_any_motion_src( - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the duration and threshold of - * any-motion interrupt. - * - * @param[in] any_motion_int_cfg : Structure instance of - * bmi160_acc_any_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_any_dur_threshold( - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure necessary setting of any-motion interrupt. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] any_motion_int_cfg : Structure instance of - * bmi160_acc_any_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_any_motion_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API enable the data ready interrupt. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_data_ready_int(const struct bmi160_dev* dev); - -/*! - * @brief This API enables the no motion/slow motion interrupt. - * - * @param[in] no_mot_int_cfg : Structure instance of - * bmi160_acc_no_motion_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_no_motion_int( - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the interrupt PIN setting for - * no motion/slow motion interrupt. - * - * @param[in] int_config : structure instance of bmi160_int_settg. - * @param[in] no_mot_int_cfg : Structure instance of - * bmi160_acc_no_motion_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_no_motion_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the source of interrupt for no motion. - * - * @param[in] no_mot_int_cfg : Structure instance of - * bmi160_acc_no_motion_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_no_motion_data_src( - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the duration and threshold of - * no motion/slow motion interrupt along with selection of no/slow motion. - * - * @param[in] no_mot_int_cfg : Structure instance of - * bmi160_acc_no_motion_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_no_motion_dur_thr( - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the sig-motion motion interrupt. - * - * @param[in] sig_mot_int_cfg : Structure instance of - * bmi160_acc_sig_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_sig_motion_int( - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - struct bmi160_dev* dev); - -/*! - * @brief This API configure the interrupt PIN setting for - * significant motion interrupt. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] sig_mot_int_cfg : Structure instance of - * bmi160_acc_sig_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_sig_motion_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for sig motion interrupt. - * - * @param[in] sig_mot_int_cfg : Structure instance of - * bmi160_acc_sig_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_sig_motion_data_src( - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the threshold, skip and proof time of - * sig motion interrupt. - * - * @param[in] sig_mot_int_cfg : Structure instance of - * bmi160_acc_sig_mot_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_sig_dur_threshold( - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the step detector interrupt. - * - * @param[in] step_detect_int_cfg : Structure instance of - * bmi160_acc_step_detect_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_step_detect_int( - const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the step detector parameter. - * - * @param[in] step_detect_int_cfg : Structure instance of - * bmi160_acc_step_detect_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_step_detect( - const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the single/double tap interrupt. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_tap_int( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the interrupt PIN setting for - * tap interrupt. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_tap_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for tap interrupt. - * - * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_tap_data_src( - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the parameters of tap interrupt. - * Threshold, quite, shock, and duration. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] tap_int_cfg : Structure instance of bmi160_acc_tap_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_tap_param( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API enable the external mode configuration. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_sec_if(const struct bmi160_dev* dev); - -/*! - * @brief This API configure the ODR of the auxiliary sensor. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_aux_odr(const struct bmi160_dev* dev); - -/*! - * @brief This API maps the actual burst read length set by user. - * - * @param[in] len : Pointer to store the read length. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t map_read_len(uint16_t* len, const struct bmi160_dev* dev); - -/*! - * @brief This API configure the settings of auxiliary sensor. - * - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_aux_settg(const struct bmi160_dev* dev); - -/*! - * @brief This API extract the read data from auxiliary sensor. - * - * @param[in] map_len : burst read value. - * @param[in] reg_addr : Address of register to read. - * @param[in] aux_data : Pointer to store the read data. - * @param[in] len : length to read the data. - * @param[in] dev : Structure instance of bmi160_dev. - * @note : Refer user guide for detailed info. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t extract_aux_read( - uint16_t map_len, - uint8_t reg_addr, - uint8_t* aux_data, - uint16_t len, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the orient interrupt. - * - * @param[in] orient_int_cfg : Structure instance of bmi160_acc_orient_int_cfg. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_orient_int( - const struct bmi160_acc_orient_int_cfg* orient_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the necessary setting of orientation interrupt. - * - * @param[in] orient_int_cfg : Structure instance of bmi160_acc_orient_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_orient_int_settg( - const struct bmi160_acc_orient_int_cfg* orient_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the flat interrupt. - * - * @param[in] flat_int : Structure instance of bmi160_acc_flat_detect_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_flat_int( - const struct bmi160_acc_flat_detect_int_cfg* flat_int, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the necessary setting of flat interrupt. - * - * @param[in] flat_int : Structure instance of bmi160_acc_flat_detect_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_flat_int_settg( - const struct bmi160_acc_flat_detect_int_cfg* flat_int, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the Low-g interrupt. - * - * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_low_g_int( - const struct bmi160_acc_low_g_int_cfg* low_g_int, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the source of data(filter & pre-filter) for low-g interrupt. - * - * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_low_g_data_src( - const struct bmi160_acc_low_g_int_cfg* low_g_int, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the necessary setting of low-g interrupt. - * - * @param[in] low_g_int : Structure instance of bmi160_acc_low_g_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_low_g_int_settg( - const struct bmi160_acc_low_g_int_cfg* low_g_int, - const struct bmi160_dev* dev); - -/*! - * @brief This API enables the high-g interrupt. - * - * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_high_g_int( - const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for high-g interrupt. - * - * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_high_g_data_src( - const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the necessary setting of high-g interrupt. - * - * @param[in] high_g_int_cfg : Structure instance of bmi160_acc_high_g_int_cfg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t config_high_g_int_settg( - const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, - const struct bmi160_dev* dev); - -/*! - * @brief This API configure the behavioural setting of interrupt pin. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - config_int_out_ctrl(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API configure the mode(input enable, latch or non-latch) of interrupt pin. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - config_int_latch(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API performs the self test for accelerometer of BMI160 - * - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t perform_accel_self_test(struct bmi160_dev* dev); - -/*! - * @brief This API enables to perform the accel self test by setting proper - * configurations to facilitate accel self test - * - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_accel_self_test(struct bmi160_dev* dev); - -/*! - * @brief This API performs accel self test with positive excitation - * - * @param[in] accel_pos : Structure pointer to store accel data - * for positive excitation - * @param[in] dev : structure instance of bmi160_dev - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t accel_self_test_positive_excitation( - struct bmi160_sensor_data* accel_pos, - const struct bmi160_dev* dev); - -/*! - * @brief This API performs accel self test with negative excitation - * - * @param[in] accel_neg : Structure pointer to store accel data - * for negative excitation - * @param[in] dev : structure instance of bmi160_dev - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t accel_self_test_negative_excitation( - struct bmi160_sensor_data* accel_neg, - const struct bmi160_dev* dev); - -/*! - * @brief This API validates the accel self test results - * - * @param[in] accel_pos : Structure pointer to store accel data - * for positive excitation - * @param[in] accel_neg : Structure pointer to store accel data - * for negative excitation - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error / +ve value -> Self test fail - */ -static int8_t validate_accel_self_test( - const struct bmi160_sensor_data* accel_pos, - const struct bmi160_sensor_data* accel_neg); - -/*! - * @brief This API performs the self test for gyroscope of BMI160 - * - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t perform_gyro_self_test(const struct bmi160_dev* dev); - -/*! - * @brief This API enables the self test bit to trigger self test for gyro - * - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t enable_gyro_self_test(const struct bmi160_dev* dev); - -/*! - * @brief This API validates the self test results of gyro - * - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t validate_gyro_self_test(const struct bmi160_dev* dev); - -/*! - * @brief This API sets FIFO full interrupt of the sensor.This interrupt - * occurs when the FIFO is full and the next full data sample would cause - * a FIFO overflow, which may delete the old samples. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - set_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This enable the FIFO full interrupt engine. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - enable_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API sets FIFO watermark interrupt of the sensor.The FIFO - * watermark interrupt is fired, when the FIFO fill level is above a fifo - * watermark. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - set_fifo_watermark_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This enable the FIFO watermark interrupt engine. - * - * @param[in] int_config : Structure instance of bmi160_int_settg. - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - enable_fifo_wtm_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API is used to reset the FIFO related configurations - * in the fifo_frame structure. - * - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void reset_fifo_data_structure(const struct bmi160_dev* dev); - -/*! - * @brief This API is used to read number of bytes filled - * currently in FIFO buffer. - * - * @param[in] bytes_to_read : Number of bytes available in FIFO at the - * instant which is obtained from FIFO counter. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error. - * @retval Any non zero value -> Fail - * - */ -static int8_t get_fifo_byte_counter(uint16_t* bytes_to_read, struct bmi160_dev const* dev); - -/*! - * @brief This API is used to compute the number of bytes of accel FIFO data - * which is to be parsed in header-less mode - * - * @param[out] data_index : The start index for parsing data - * @param[out] data_read_length : Number of bytes to be parsed - * @param[in] acc_frame_count : Number of accelerometer frames to be read - * @param[in] dev : Structure instance of bmi160_dev. - * - */ -static void get_accel_len_to_parse( - uint16_t* data_index, - uint16_t* data_read_length, - const uint8_t* acc_frame_count, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the accelerometer data from the - * FIFO data in both header mode and header-less mode. - * It updates the idx value which is used to store the index of - * the current data byte which is parsed. - * - * @param[in,out] acc : structure instance of sensor data - * @param[in,out] idx : Index value of number of bytes parsed - * @param[in,out] acc_idx : Index value of accelerometer data - * (x,y,z axes) frames parsed - * @param[in] frame_info : It consists of either fifo_data_enable - * parameter in header-less mode or - * frame header data in header mode - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_accel_frame( - struct bmi160_sensor_data* acc, - uint16_t* idx, - uint8_t* acc_idx, - uint8_t frame_info, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the accelerometer data from the - * FIFO data and store it in the instance of the structure bmi160_sensor_data. - * - * @param[in,out] accel_data : structure instance of sensor data - * @param[in,out] data_start_index : Index value of number of bytes parsed - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_accel_data( - struct bmi160_sensor_data* accel_data, - uint16_t data_start_index, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the accelerometer data from the - * FIFO data in header mode. - * - * @param[in,out] accel_data : Structure instance of sensor data - * @param[in,out] accel_length : Number of accelerometer frames - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void extract_accel_header_mode( - struct bmi160_sensor_data* accel_data, - uint8_t* accel_length, - const struct bmi160_dev* dev); - -/*! - * @brief This API computes the number of bytes of gyro FIFO data - * which is to be parsed in header-less mode - * - * @param[out] data_index : The start index for parsing data - * @param[out] data_read_length : No of bytes to be parsed from FIFO buffer - * @param[in] gyro_frame_count : Number of Gyro data frames to be read - * @param[in] dev : Structure instance of bmi160_dev. - */ -static void get_gyro_len_to_parse( - uint16_t* data_index, - uint16_t* data_read_length, - const uint8_t* gyro_frame_count, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the gyroscope's data from the - * FIFO data in both header mode and header-less mode. - * It updates the idx value which is used to store the index of - * the current data byte which is parsed. - * - * @param[in,out] gyro : structure instance of sensor data - * @param[in,out] idx : Index value of number of bytes parsed - * @param[in,out] gyro_idx : Index value of gyro data - * (x,y,z axes) frames parsed - * @param[in] frame_info : It consists of either fifo_data_enable - * parameter in header-less mode or - * frame header data in header mode - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_gyro_frame( - struct bmi160_sensor_data* gyro, - uint16_t* idx, - uint8_t* gyro_idx, - uint8_t frame_info, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the gyro data from the - * FIFO data and store it in the instance of the structure bmi160_sensor_data. - * - * @param[in,out] gyro_data : structure instance of sensor data - * @param[in,out] data_start_index : Index value of number of bytes parsed - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_gyro_data( - struct bmi160_sensor_data* gyro_data, - uint16_t data_start_index, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the gyro data from the - * FIFO data in header mode. - * - * @param[in,out] gyro_data : Structure instance of sensor data - * @param[in,out] gyro_length : Number of gyro frames - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void extract_gyro_header_mode( - struct bmi160_sensor_data* gyro_data, - uint8_t* gyro_length, - const struct bmi160_dev* dev); - -/*! - * @brief This API computes the number of bytes of aux FIFO data - * which is to be parsed in header-less mode - * - * @param[out] data_index : The start index for parsing data - * @param[out] data_read_length : No of bytes to be parsed from FIFO buffer - * @param[in] aux_frame_count : Number of Aux data frames to be read - * @param[in] dev : Structure instance of bmi160_dev. - */ -static void get_aux_len_to_parse( - uint16_t* data_index, - uint16_t* data_read_length, - const uint8_t* aux_frame_count, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the aux's data from the - * FIFO data in both header mode and header-less mode. - * It updates the idx value which is used to store the index of - * the current data byte which is parsed - * - * @param[in,out] aux_data : structure instance of sensor data - * @param[in,out] idx : Index value of number of bytes parsed - * @param[in,out] aux_index : Index value of gyro data - * (x,y,z axes) frames parsed - * @param[in] frame_info : It consists of either fifo_data_enable - * parameter in header-less mode or - * frame header data in header mode - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_aux_frame( - struct bmi160_aux_data* aux_data, - uint16_t* idx, - uint8_t* aux_index, - uint8_t frame_info, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the aux data from the - * FIFO data and store it in the instance of the structure bmi160_aux_data. - * - * @param[in,out] aux_data : structure instance of sensor data - * @param[in,out] data_start_index : Index value of number of bytes parsed - * @param[in] dev : structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_aux_data( - struct bmi160_aux_data* aux_data, - uint16_t data_start_index, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse the aux data from the - * FIFO data in header mode. - * - * @param[in,out] aux_data : Structure instance of sensor data - * @param[in,out] aux_length : Number of aux frames - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void extract_aux_header_mode( - struct bmi160_aux_data* aux_data, - uint8_t* aux_length, - const struct bmi160_dev* dev); - -/*! - * @brief This API checks the presence of non-valid frames in the read fifo data. - * - * @param[in,out] data_index : The index of the current data to - * be parsed from fifo data - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void check_frame_validity(uint16_t* data_index, const struct bmi160_dev* dev); - -/*! - * @brief This API is used to move the data index ahead of the - * current_frame_length parameter when unnecessary FIFO data appears while - * extracting the user specified data. - * - * @param[in,out] data_index : Index of the FIFO data which - * is to be moved ahead of the - * current_frame_length - * @param[in] current_frame_length : Number of bytes in a particular frame - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void move_next_frame( - uint16_t* data_index, - uint8_t current_frame_length, - const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse and store the sensor time from the - * FIFO data in the structure instance dev. - * - * @param[in,out] data_index : Index of the FIFO data which - * has the sensor time. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_sensortime_frame(uint16_t* data_index, const struct bmi160_dev* dev); - -/*! - * @brief This API is used to parse and store the skipped_frame_count from - * the FIFO data in the structure instance dev. - * - * @param[in,out] data_index : Index of the FIFO data which - * has the skipped frame count. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static void unpack_skipped_frame(uint16_t* data_index, const struct bmi160_dev* dev); - -/*! - * @brief This API is used to get the FOC status from the sensor - * - * @param[in,out] foc_status : Result of FOC status. - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t get_foc_status(uint8_t* foc_status, struct bmi160_dev const* dev); - -/*! - * @brief This API is used to configure the offset enable bits in the sensor - * - * @param[in,out] foc_conf : Structure instance of bmi160_foc_conf which - * has the FOC and offset configurations - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - configure_offset_enable(const struct bmi160_foc_conf* foc_conf, struct bmi160_dev const* dev); - -/*! - * @brief This API is used to trigger the FOC in the sensor - * - * @param[in,out] offset : Structure instance of bmi160_offsets which - * reads and stores the offset values after FOC - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t trigger_foc(struct bmi160_offsets* offset, struct bmi160_dev const* dev); - -/*! - * @brief This API is used to map/unmap the Dataready(Accel & Gyro), FIFO full - * and FIFO watermark interrupt - * - * @param[in] int_config : Structure instance of bmi160_int_settg which - * stores the interrupt type and interrupt channel - * configurations to map/unmap the interrupt pins - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - map_hardware_interrupt(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*! - * @brief This API is used to map/unmap the Any/Sig motion, Step det/Low-g, - * Double tap, Single tap, Orientation, Flat, High-G, Nomotion interrupt pins. - * - * @param[in] int_config : Structure instance of bmi160_int_settg which - * stores the interrupt type and interrupt channel - * configurations to map/unmap the interrupt pins - * @param[in] dev : Structure instance of bmi160_dev. - * - * @return Result of API execution status - * @retval zero -> Success / -ve value -> Error - */ -static int8_t - map_feature_interrupt(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev); - -/*********************** User function definitions ****************************/ - -/*! - * @brief This API reads the data from the given register address - * of sensor. - */ -int8_t - bmi160_get_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - /* Null-pointer check */ - if((dev == NULL) || (dev->read == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else if(len == 0) { - rslt = BMI160_E_READ_WRITE_LENGTH_INVALID; - } else { - /* Configuring reg_addr for SPI Interface */ - if(dev->intf == BMI160_SPI_INTF) { - reg_addr = (reg_addr | BMI160_SPI_RD_MASK); - } - - rslt = dev->read(dev->id, reg_addr, data, len); - } - - return rslt; -} - -/*! - * @brief This API writes the given data to the register address - * of sensor. - */ -int8_t - bmi160_set_regs(uint8_t reg_addr, uint8_t* data, uint16_t len, const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - uint8_t count = 0; - - /* Null-pointer check */ - if((dev == NULL) || (dev->write == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else if(len == 0) { - rslt = BMI160_E_READ_WRITE_LENGTH_INVALID; - } else { - /* Configuring reg_addr for SPI Interface */ - if(dev->intf == BMI160_SPI_INTF) { - reg_addr = (reg_addr & BMI160_SPI_WR_MASK); - } - - if((dev->prev_accel_cfg.power == BMI160_ACCEL_NORMAL_MODE) || - (dev->prev_gyro_cfg.power == BMI160_GYRO_NORMAL_MODE)) { - rslt = dev->write(dev->id, reg_addr, data, len); - - /* Kindly refer bmi160 data sheet section 3.2.4 */ - dev->delay_ms(1); - - } else { - /*Burst write is not allowed in - * suspend & low power mode */ - for(; count < len; count++) { - rslt = dev->write(dev->id, reg_addr, &data[count], 1); - reg_addr++; - - /* Kindly refer bmi160 data sheet section 3.2.4 */ - dev->delay_ms(1); - } - } - - if(rslt != BMI160_OK) { - rslt = BMI160_E_COM_FAIL; - } - } - - return rslt; -} - -/*! - * @brief This API is the entry point for sensor.It performs - * the selection of I2C/SPI read mechanism according to the - * selected interface and reads the chip-id of bmi160 sensor. - */ -int8_t bmi160_init(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data; - uint8_t try = 3; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - - /* Dummy read of 0x7F register to enable SPI Interface - * if SPI is used */ - if((rslt == BMI160_OK) && (dev->intf == BMI160_SPI_INTF)) { - rslt = bmi160_get_regs(BMI160_SPI_COMM_TEST_ADDR, &data, 1, dev); - } - - if(rslt == BMI160_OK) { - /* Assign chip id as zero */ - dev->chip_id = 0; - - while((try--) && (dev->chip_id != BMI160_CHIP_ID)) { - /* Read chip_id */ - rslt = bmi160_get_regs(BMI160_CHIP_ID_ADDR, &dev->chip_id, 1, dev); - } - - if((rslt == BMI160_OK) && (dev->chip_id == BMI160_CHIP_ID)) { - dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; - - /* Soft reset */ - rslt = bmi160_soft_reset(dev); - } else { - rslt = BMI160_E_DEV_NOT_FOUND; - } - } - - return rslt; -} - -/*! - * @brief This API resets and restarts the device. - * All register values are overwritten with default parameters. - */ -int8_t bmi160_soft_reset(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = BMI160_SOFT_RESET_CMD; - - /* Null-pointer check */ - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Reset the device */ - rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &data, 1, dev); - dev->delay_ms(BMI160_SOFT_RESET_DELAY_MS); - if((rslt == BMI160_OK) && (dev->intf == BMI160_SPI_INTF)) { - /* Dummy read of 0x7F register to enable SPI Interface - * if SPI is used */ - rslt = bmi160_get_regs(BMI160_SPI_COMM_TEST_ADDR, &data, 1, dev); - } - - if(rslt == BMI160_OK) { - /* Update the default parameters */ - default_param_settg(dev); - } - } - - return rslt; -} - -/*! - * @brief This API configures the power mode, range and bandwidth - * of sensor. - */ -int8_t bmi160_set_sens_conf(struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - /* Null-pointer check */ - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = set_accel_conf(dev); - if(rslt == BMI160_OK) { - rslt = set_gyro_conf(dev); - if(rslt == BMI160_OK) { - /* write power mode for accel and gyro */ - rslt = bmi160_set_power_mode(dev); - if(rslt == BMI160_OK) { - rslt = check_invalid_settg(dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This API gets accel and gyro configurations. - */ -int8_t bmi160_get_sens_conf(struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - /* Null-pointer check */ - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = get_accel_conf(dev); - if(rslt == BMI160_OK) { - rslt = get_gyro_conf(dev); - } - } - - return rslt; -} - -/*! - * @brief This API sets the power mode of the sensor. - */ -int8_t bmi160_set_power_mode(struct bmi160_dev* dev) { - int8_t rslt = 0; - - /* Null-pointer check */ - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = set_accel_pwr(dev); - if(rslt == BMI160_OK) { - rslt = set_gyro_pwr(dev); - } - } - - return rslt; -} - -/*! - * @brief This API gets the power mode of the sensor. - */ -int8_t bmi160_get_power_mode(struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t power_mode = 0; - - /* Null-pointer check */ - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_get_regs(BMI160_PMU_STATUS_ADDR, &power_mode, 1, dev); - if(rslt == BMI160_OK) { - /* Power mode of the accel, gyro sensor is obtained */ - dev->gyro_cfg.power = BMI160_GET_BITS(power_mode, BMI160_GYRO_POWER_MODE); - dev->accel_cfg.power = BMI160_GET_BITS(power_mode, BMI160_ACCEL_POWER_MODE); - } - } - - return rslt; -} - -/*! - * @brief This API reads sensor data, stores it in - * the bmi160_sensor_data structure pointer passed by the user. - */ -int8_t bmi160_get_sensor_data( - uint8_t select_sensor, - struct bmi160_sensor_data* accel, - struct bmi160_sensor_data* gyro, - const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - uint8_t time_sel; - uint8_t sen_sel; - uint8_t len = 0; - - /*Extract the sensor and time select information*/ - sen_sel = select_sensor & BMI160_SEN_SEL_MASK; - time_sel = ((sen_sel & BMI160_TIME_SEL) >> 2); - sen_sel = sen_sel & (BMI160_ACCEL_SEL | BMI160_GYRO_SEL); - if(time_sel == 1) { - len = 3; - } - - /* Null-pointer check */ - if(dev != NULL) { - switch(sen_sel) { - case BMI160_ACCEL_ONLY: - - /* Null-pointer check */ - if(accel == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = get_accel_data(len, accel, dev); - } - - break; - case BMI160_GYRO_ONLY: - - /* Null-pointer check */ - if(gyro == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = get_gyro_data(len, gyro, dev); - } - - break; - case BMI160_BOTH_ACCEL_AND_GYRO: - - /* Null-pointer check */ - if((gyro == NULL) || (accel == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = get_accel_gyro_data(len, accel, gyro, dev); - } - - break; - default: - rslt = BMI160_E_INVALID_INPUT; - break; - } - } else { - rslt = BMI160_E_NULL_PTR; - } - - return rslt; -} - -/*! - * @brief This API configures the necessary interrupt based on - * the user settings in the bmi160_int_settg structure instance. - */ -int8_t bmi160_set_int_config(struct bmi160_int_settg* int_config, struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - switch(int_config->int_type) { - case BMI160_ACC_ANY_MOTION_INT: - - /*Any-motion interrupt*/ - rslt = set_accel_any_motion_int(int_config, dev); - break; - case BMI160_ACC_SIG_MOTION_INT: - - /* Significant motion interrupt */ - rslt = set_accel_sig_motion_int(int_config, dev); - break; - case BMI160_ACC_SLOW_NO_MOTION_INT: - - /* Slow or no motion interrupt */ - rslt = set_accel_no_motion_int(int_config, dev); - break; - case BMI160_ACC_DOUBLE_TAP_INT: - case BMI160_ACC_SINGLE_TAP_INT: - - /* Double tap and single tap Interrupt */ - rslt = set_accel_tap_int(int_config, dev); - break; - case BMI160_STEP_DETECT_INT: - - /* Step detector interrupt */ - rslt = set_accel_step_detect_int(int_config, dev); - break; - case BMI160_ACC_ORIENT_INT: - - /* Orientation interrupt */ - rslt = set_accel_orientation_int(int_config, dev); - break; - case BMI160_ACC_FLAT_INT: - - /* Flat detection interrupt */ - rslt = set_accel_flat_detect_int(int_config, dev); - break; - case BMI160_ACC_LOW_G_INT: - - /* Low-g interrupt */ - rslt = set_accel_low_g_int(int_config, dev); - break; - case BMI160_ACC_HIGH_G_INT: - - /* High-g interrupt */ - rslt = set_accel_high_g_int(int_config, dev); - break; - case BMI160_ACC_GYRO_DATA_RDY_INT: - - /* Data ready interrupt */ - rslt = set_accel_gyro_data_ready_int(int_config, dev); - break; - case BMI160_ACC_GYRO_FIFO_FULL_INT: - - /* Fifo full interrupt */ - rslt = set_fifo_full_int(int_config, dev); - break; - case BMI160_ACC_GYRO_FIFO_WATERMARK_INT: - - /* Fifo water-mark interrupt */ - rslt = set_fifo_watermark_int(int_config, dev); - break; - case BMI160_FIFO_TAG_INT_PIN: - - /* Fifo tagging feature support */ - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - break; - default: - break; - } - - return rslt; -} - -/*! - * @brief This API enables or disable the step counter feature. - * 1 - enable step counter (0 - disable) - */ -int8_t bmi160_set_step_counter(uint8_t step_cnt_enable, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_get_regs(BMI160_INT_STEP_CONFIG_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - if(step_cnt_enable == BMI160_ENABLE) { - data |= (uint8_t)(step_cnt_enable << 3); - } else { - data &= ~BMI160_STEP_COUNT_EN_BIT_MASK; - } - - rslt = bmi160_set_regs(BMI160_INT_STEP_CONFIG_1_ADDR, &data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API reads the step counter value. - */ -int8_t bmi160_read_step_counter(uint16_t* step_val, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[2] = {0, 0}; - uint16_t msb = 0; - uint8_t lsb = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_get_regs(BMI160_INT_STEP_CNT_0_ADDR, data, 2, dev); - if(rslt == BMI160_OK) { - lsb = data[0]; - msb = data[1] << 8; - *step_val = msb | lsb; - } - } - - return rslt; -} - -/*! - * @brief This API reads the mention no of byte of data from the given - * register address of auxiliary sensor. - */ -int8_t bmi160_aux_read( - uint8_t reg_addr, - uint8_t* aux_data, - uint16_t len, - const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - uint16_t map_len = 0; - - /* Null-pointer check */ - if((dev == NULL) || (dev->read == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - if(dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) { - rslt = map_read_len(&map_len, dev); - if(rslt == BMI160_OK) { - rslt = extract_aux_read(map_len, reg_addr, aux_data, len, dev); - } - } else { - rslt = BMI160_E_INVALID_INPUT; - } - } - - return rslt; -} - -/*! - * @brief This API writes the mention no of byte of data to the given - * register address of auxiliary sensor. - */ -int8_t bmi160_aux_write( - uint8_t reg_addr, - uint8_t* aux_data, - uint16_t len, - const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - uint8_t count = 0; - - /* Null-pointer check */ - if((dev == NULL) || (dev->write == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - for(; count < len; count++) { - /* set data to write */ - rslt = bmi160_set_regs(BMI160_AUX_IF_4_ADDR, aux_data, 1, dev); - dev->delay_ms(BMI160_AUX_COM_DELAY); - if(rslt == BMI160_OK) { - /* set address to write */ - rslt = bmi160_set_regs(BMI160_AUX_IF_3_ADDR, ®_addr, 1, dev); - dev->delay_ms(BMI160_AUX_COM_DELAY); - if(rslt == BMI160_OK && (count < len - 1)) { - aux_data++; - reg_addr++; - } - } - } - } - - return rslt; -} - -/*! - * @brief This API initialize the auxiliary sensor - * in order to access it. - */ -int8_t bmi160_aux_init(const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - if(dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) { - /* Configures the auxiliary sensor interface settings */ - rslt = config_aux_settg(dev); - } else { - rslt = BMI160_E_INVALID_INPUT; - } - } - - return rslt; -} - -/*! - * @brief This API is used to setup the auxiliary sensor of bmi160 in auto mode - * Thus enabling the auto update of 8 bytes of data from auxiliary sensor - * to BMI160 register address 0x04 to 0x0B - */ -int8_t bmi160_set_aux_auto_mode(uint8_t* data_addr, struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - if(dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) { - /* Write the aux. address to read in 0x4D of BMI160*/ - rslt = bmi160_set_regs(BMI160_AUX_IF_2_ADDR, data_addr, 1, dev); - dev->delay_ms(BMI160_AUX_COM_DELAY); - if(rslt == BMI160_OK) { - /* Configure the polling ODR for - * auxiliary sensor */ - rslt = config_aux_odr(dev); - if(rslt == BMI160_OK) { - /* Disable the aux. manual mode, i.e aux. - * sensor is in auto-mode (data-mode) */ - dev->aux_cfg.manual_enable = BMI160_DISABLE; - rslt = bmi160_config_aux_mode(dev); - - /* Auxiliary sensor data is obtained - * in auto mode from this point */ - } - } - } else { - rslt = BMI160_E_INVALID_INPUT; - } - } - - return rslt; -} - -/*! - * @brief This API configures the 0x4C register and settings like - * Auxiliary sensor manual enable/ disable and aux burst read length. - */ -int8_t bmi160_config_aux_mode(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t aux_if[2] = {(uint8_t)(dev->aux_cfg.aux_i2c_addr * 2), 0}; - - rslt = bmi160_get_regs(BMI160_AUX_IF_1_ADDR, &aux_if[1], 1, dev); - if(rslt == BMI160_OK) { - /* update the Auxiliary interface to manual/auto mode */ - aux_if[1] = BMI160_SET_BITS(aux_if[1], BMI160_MANUAL_MODE_EN, dev->aux_cfg.manual_enable); - - /* update the burst read length defined by user */ - aux_if[1] = - BMI160_SET_BITS_POS_0(aux_if[1], BMI160_AUX_READ_BURST, dev->aux_cfg.aux_rd_burst_len); - - /* Set the secondary interface address and manual mode - * along with burst read length */ - rslt = bmi160_set_regs(BMI160_AUX_IF_0_ADDR, &aux_if[0], 2, dev); - dev->delay_ms(BMI160_AUX_COM_DELAY); - } - - return rslt; -} - -/*! - * @brief This API is used to read the raw uncompensated auxiliary sensor - * data of 8 bytes from BMI160 register address 0x04 to 0x0B - */ -int8_t bmi160_read_aux_data_auto_mode(uint8_t* aux_data, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - if((dev->aux_cfg.aux_sensor_enable == BMI160_ENABLE) && - (dev->aux_cfg.manual_enable == BMI160_DISABLE)) { - /* Read the aux. sensor's raw data */ - rslt = bmi160_get_regs(BMI160_AUX_DATA_ADDR, aux_data, 8, dev); - } else { - rslt = BMI160_E_INVALID_INPUT; - } - } - - return rslt; -} - -/*! - * @brief This is used to perform self test of accel/gyro of the BMI160 sensor - */ -int8_t bmi160_perform_self_test(uint8_t select_sensor, struct bmi160_dev* dev) { - int8_t rslt; - int8_t self_test_rslt = 0; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Proceed if null check is fine */ - switch(select_sensor) { - case BMI160_ACCEL_ONLY: - rslt = perform_accel_self_test(dev); - break; - case BMI160_GYRO_ONLY: - - /* Set the power mode as normal mode */ - dev->gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; - rslt = bmi160_set_power_mode(dev); - - /* Perform gyro self test */ - if(rslt == BMI160_OK) { - /* Perform gyro self test */ - rslt = perform_gyro_self_test(dev); - } - - break; - default: - rslt = BMI160_E_INVALID_INPUT; - break; - } - - /* Check to ensure bus error does not occur */ - if(rslt >= BMI160_OK) { - /* Store the status of self test result */ - self_test_rslt = rslt; - - /* Perform soft reset */ - rslt = bmi160_soft_reset(dev); - } - - /* Check to ensure bus operations are success */ - if(rslt == BMI160_OK) { - /* Restore self_test_rslt as return value */ - rslt = self_test_rslt; - } - } - - return rslt; -} - -/*! - * @brief This API reads the data from fifo buffer. - */ -int8_t bmi160_get_fifo_data(struct bmi160_dev const* dev) { - int8_t rslt = 0; - uint16_t bytes_to_read = 0; - uint16_t user_fifo_len = 0; - - /* check the bmi160 structure as NULL*/ - if((dev == NULL) || (dev->fifo->data == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - reset_fifo_data_structure(dev); - - /* get current FIFO fill-level*/ - rslt = get_fifo_byte_counter(&bytes_to_read, dev); - if(rslt == BMI160_OK) { - user_fifo_len = dev->fifo->length; - if((dev->fifo->length > bytes_to_read)) { - /* Handling the case where user requests - * more data than available in FIFO */ - dev->fifo->length = bytes_to_read; - } - - if((dev->fifo->fifo_time_enable == BMI160_FIFO_TIME_ENABLE) && - (bytes_to_read + BMI160_FIFO_BYTES_OVERREAD <= user_fifo_len)) { - /* Handling case of sensor time availability*/ - dev->fifo->length = dev->fifo->length + BMI160_FIFO_BYTES_OVERREAD; - } - - /* read only the filled bytes in the FIFO Buffer */ - rslt = bmi160_get_regs(BMI160_FIFO_DATA_ADDR, dev->fifo->data, dev->fifo->length, dev); - } - } - - return rslt; -} - -/*! - * @brief This API writes fifo_flush command to command register.This - * action clears all data in the Fifo without changing fifo configuration - * settings - */ -int8_t bmi160_set_fifo_flush(const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t data = BMI160_FIFO_FLUSH_VALUE; - uint8_t reg_addr = BMI160_COMMAND_REG_ADDR; - - /* Check the bmi160_dev structure for NULL address*/ - if(dev == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); - } - - return rslt; -} - -/*! - * @brief This API sets the FIFO configuration in the sensor. - */ -int8_t bmi160_set_fifo_config(uint8_t config, uint8_t enable, struct bmi160_dev const* dev) { - int8_t rslt = 0; - uint8_t data = 0; - uint8_t reg_addr = BMI160_FIFO_CONFIG_1_ADDR; - uint8_t fifo_config = config & BMI160_FIFO_CONFIG_1_MASK; - - /* Check the bmi160_dev structure for NULL address*/ - if(dev == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); - if(rslt == BMI160_OK) { - if(fifo_config > 0) { - if(enable == BMI160_ENABLE) { - data = data | fifo_config; - } else { - data = data & (~fifo_config); - } - } - - /* write fifo frame content configuration*/ - rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); - if(rslt == BMI160_OK) { - /* read fifo frame content configuration*/ - rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); - if(rslt == BMI160_OK) { - /* extract fifo header enabled status */ - dev->fifo->fifo_header_enable = data & BMI160_FIFO_HEAD_ENABLE; - - /* extract accel/gyr/aux. data enabled status */ - dev->fifo->fifo_data_enable = data & BMI160_FIFO_M_G_A_ENABLE; - - /* extract fifo sensor time enabled status */ - dev->fifo->fifo_time_enable = data & BMI160_FIFO_TIME_ENABLE; - } - } - } - } - - return rslt; -} - -/*! @brief This API is used to configure the down sampling ratios of - * the accel and gyro data for FIFO.Also, it configures filtered or - * pre-filtered data for accel and gyro. - * - */ -int8_t bmi160_set_fifo_down(uint8_t fifo_down, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t data = 0; - uint8_t reg_addr = BMI160_FIFO_DOWN_ADDR; - - /* Check the bmi160_dev structure for NULL address*/ - if(dev == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_get_regs(reg_addr, &data, BMI160_ONE, dev); - if(rslt == BMI160_OK) { - data = data | fifo_down; - rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); - } - } - - return rslt; -} - -/*! - * @brief This API sets the FIFO watermark level in the sensor. - * - */ -int8_t bmi160_set_fifo_wm(uint8_t fifo_wm, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t data = fifo_wm; - uint8_t reg_addr = BMI160_FIFO_CONFIG_0_ADDR; - - /* Check the bmi160_dev structure for NULL address*/ - if(dev == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = bmi160_set_regs(reg_addr, &data, BMI160_ONE, dev); - } - - return rslt; -} - -/*! - * @brief This API parses and extracts the accelerometer frames from - * FIFO data read by the "bmi160_get_fifo_data" API and stores it in - * the "accel_data" structure instance. - */ -int8_t bmi160_extract_accel( - struct bmi160_sensor_data* accel_data, - uint8_t* accel_length, - struct bmi160_dev const* dev) { - int8_t rslt = 0; - uint16_t data_index = 0; - uint16_t data_read_length = 0; - uint8_t accel_index = 0; - uint8_t fifo_data_enable = 0; - - if(dev == NULL || dev->fifo == NULL || dev->fifo->data == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Parsing the FIFO data in header-less mode */ - if(dev->fifo->fifo_header_enable == 0) { - /* Number of bytes to be parsed from FIFO */ - get_accel_len_to_parse(&data_index, &data_read_length, accel_length, dev); - for(; data_index < data_read_length;) { - /*Check for the availability of next two bytes of FIFO data */ - check_frame_validity(&data_index, dev); - fifo_data_enable = dev->fifo->fifo_data_enable; - unpack_accel_frame(accel_data, &data_index, &accel_index, fifo_data_enable, dev); - } - - /* update number of accel data read*/ - *accel_length = accel_index; - - /*update the accel byte index*/ - dev->fifo->accel_byte_start_idx = data_index; - } else { - /* Parsing the FIFO data in header mode */ - extract_accel_header_mode(accel_data, accel_length, dev); - } - } - - return rslt; -} - -/*! - * @brief This API parses and extracts the gyro frames from - * FIFO data read by the "bmi160_get_fifo_data" API and stores it in - * the "gyro_data" structure instance. - */ -int8_t bmi160_extract_gyro( - struct bmi160_sensor_data* gyro_data, - uint8_t* gyro_length, - struct bmi160_dev const* dev) { - int8_t rslt = 0; - uint16_t data_index = 0; - uint16_t data_read_length = 0; - uint8_t gyro_index = 0; - uint8_t fifo_data_enable = 0; - - if(dev == NULL || dev->fifo->data == NULL) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Parsing the FIFO data in header-less mode */ - if(dev->fifo->fifo_header_enable == 0) { - /* Number of bytes to be parsed from FIFO */ - get_gyro_len_to_parse(&data_index, &data_read_length, gyro_length, dev); - for(; data_index < data_read_length;) { - /*Check for the availability of next two bytes of FIFO data */ - check_frame_validity(&data_index, dev); - fifo_data_enable = dev->fifo->fifo_data_enable; - unpack_gyro_frame(gyro_data, &data_index, &gyro_index, fifo_data_enable, dev); - } - - /* update number of gyro data read */ - *gyro_length = gyro_index; - - /* update the gyro byte index */ - dev->fifo->gyro_byte_start_idx = data_index; - } else { - /* Parsing the FIFO data in header mode */ - extract_gyro_header_mode(gyro_data, gyro_length, dev); - } - } - - return rslt; -} - -/*! - * @brief This API parses and extracts the aux frames from - * FIFO data read by the "bmi160_get_fifo_data" API and stores it in - * the "aux_data" structure instance. - */ -int8_t bmi160_extract_aux( - struct bmi160_aux_data* aux_data, - uint8_t* aux_len, - struct bmi160_dev const* dev) { - int8_t rslt = 0; - uint16_t data_index = 0; - uint16_t data_read_length = 0; - uint8_t aux_index = 0; - uint8_t fifo_data_enable = 0; - - if((dev == NULL) || (dev->fifo->data == NULL) || (aux_data == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Parsing the FIFO data in header-less mode */ - if(dev->fifo->fifo_header_enable == 0) { - /* Number of bytes to be parsed from FIFO */ - get_aux_len_to_parse(&data_index, &data_read_length, aux_len, dev); - for(; data_index < data_read_length;) { - /* Check for the availability of next two - * bytes of FIFO data */ - check_frame_validity(&data_index, dev); - fifo_data_enable = dev->fifo->fifo_data_enable; - unpack_aux_frame(aux_data, &data_index, &aux_index, fifo_data_enable, dev); - } - - /* update number of aux data read */ - *aux_len = aux_index; - - /* update the aux byte index */ - dev->fifo->aux_byte_start_idx = data_index; - } else { - /* Parsing the FIFO data in header mode */ - extract_aux_header_mode(aux_data, aux_len, dev); - } - } - - return rslt; -} - -/*! - * @brief This API starts the FOC of accel and gyro - * - * @note FOC should not be used in low-power mode of sensor - * - * @note Accel FOC targets values of +1g , 0g , -1g - * Gyro FOC always targets value of 0 dps - */ -int8_t bmi160_start_foc( - const struct bmi160_foc_conf* foc_conf, - struct bmi160_offsets* offset, - struct bmi160_dev const* dev) { - int8_t rslt; - uint8_t data; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Set the offset enable bits */ - rslt = configure_offset_enable(foc_conf, dev); - if(rslt == BMI160_OK) { - /* Read the FOC config from the sensor */ - rslt = bmi160_get_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); - - /* Set the FOC config for gyro */ - data = BMI160_SET_BITS(data, BMI160_GYRO_FOC_EN, foc_conf->foc_gyr_en); - - /* Set the FOC config for accel xyz axes */ - data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_X_CONF, foc_conf->foc_acc_x); - data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_Y_CONF, foc_conf->foc_acc_y); - data = BMI160_SET_BITS_POS_0(data, BMI160_ACCEL_FOC_Z_CONF, foc_conf->foc_acc_z); - if(rslt == BMI160_OK) { - /* Set the FOC config in the sensor */ - rslt = bmi160_set_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* Procedure to trigger - * FOC and check status */ - rslt = trigger_foc(offset, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This API reads and stores the offset values of accel and gyro - */ -int8_t bmi160_get_offsets(struct bmi160_offsets* offset, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[7]; - uint8_t lsb, msb; - int16_t offset_msb, offset_lsb; - int16_t offset_data; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Read the FOC config from the sensor */ - rslt = bmi160_get_regs(BMI160_OFFSET_ADDR, data, 7, dev); - - /* Accel offsets */ - offset->off_acc_x = (int8_t)data[0]; - offset->off_acc_y = (int8_t)data[1]; - offset->off_acc_z = (int8_t)data[2]; - - /* Gyro x-axis offset */ - lsb = data[3]; - msb = BMI160_GET_BITS_POS_0(data[6], BMI160_GYRO_OFFSET_X); - offset_msb = (int16_t)(msb << 14); - offset_lsb = lsb << 6; - offset_data = offset_msb | offset_lsb; - - /* Divide by 64 to get the Right shift by 6 value */ - offset->off_gyro_x = (int16_t)(offset_data / 64); - - /* Gyro y-axis offset */ - lsb = data[4]; - msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Y); - offset_msb = (int16_t)(msb << 14); - offset_lsb = lsb << 6; - offset_data = offset_msb | offset_lsb; - - /* Divide by 64 to get the Right shift by 6 value */ - offset->off_gyro_y = (int16_t)(offset_data / 64); - - /* Gyro z-axis offset */ - lsb = data[5]; - msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Z); - offset_msb = (int16_t)(msb << 14); - offset_lsb = lsb << 6; - offset_data = offset_msb | offset_lsb; - - /* Divide by 64 to get the Right shift by 6 value */ - offset->off_gyro_z = (int16_t)(offset_data / 64); - } - - return rslt; -} - -/*! - * @brief This API writes the offset values of accel and gyro to - * the sensor but these values will be reset on POR or soft reset. - */ -int8_t bmi160_set_offsets( - const struct bmi160_foc_conf* foc_conf, - const struct bmi160_offsets* offset, - struct bmi160_dev const* dev) { - int8_t rslt; - uint8_t data[7]; - uint8_t x_msb, y_msb, z_msb; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Update the accel offset */ - data[0] = (uint8_t)offset->off_acc_x; - data[1] = (uint8_t)offset->off_acc_y; - data[2] = (uint8_t)offset->off_acc_z; - - /* Update the LSB of gyro offset */ - data[3] = BMI160_GET_LSB(offset->off_gyro_x); - data[4] = BMI160_GET_LSB(offset->off_gyro_y); - data[5] = BMI160_GET_LSB(offset->off_gyro_z); - - /* Update the MSB of gyro offset */ - x_msb = BMI160_GET_BITS(offset->off_gyro_x, BMI160_GYRO_OFFSET); - y_msb = BMI160_GET_BITS(offset->off_gyro_y, BMI160_GYRO_OFFSET); - z_msb = BMI160_GET_BITS(offset->off_gyro_z, BMI160_GYRO_OFFSET); - data[6] = (uint8_t)(z_msb << 4 | y_msb << 2 | x_msb); - - /* Set the offset enable/disable for gyro and accel */ - data[6] = BMI160_SET_BITS(data[6], BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); - data[6] = BMI160_SET_BITS(data[6], BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); - - /* Set the offset config and values in the sensor */ - rslt = bmi160_set_regs(BMI160_OFFSET_ADDR, data, 7, dev); - } - - return rslt; -} - -/*! - * @brief This API writes the image registers values to NVM which is - * stored even after POR or soft reset - */ -int8_t bmi160_update_nvm(struct bmi160_dev const* dev) { - int8_t rslt; - uint8_t data; - uint8_t cmd = BMI160_NVM_BACKUP_EN; - - /* Read the nvm_prog_en configuration */ - rslt = bmi160_get_regs(BMI160_CONF_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - data = BMI160_SET_BITS(data, BMI160_NVM_UPDATE, 1); - - /* Set the nvm_prog_en bit in the sensor */ - rslt = bmi160_set_regs(BMI160_CONF_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* Update NVM */ - rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); - if(rslt == BMI160_OK) { - /* Check for NVM ready status */ - rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - data = BMI160_GET_BITS(data, BMI160_NVM_STATUS); - if(data != BMI160_ENABLE) { - /* Delay to update NVM */ - dev->delay_ms(25); - } - } - } - } - } - - return rslt; -} - -/*! - * @brief This API gets the interrupt status from the sensor. - */ -int8_t bmi160_get_int_status( - enum bmi160_int_status_sel int_status_sel, - union bmi160_int_status* int_status, - struct bmi160_dev const* dev) { - int8_t rslt = 0; - - /* To get the status of all interrupts */ - if(int_status_sel == BMI160_INT_STATUS_ALL) { - rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR, &int_status->data[0], 4, dev); - } else { - if(int_status_sel & BMI160_INT_STATUS_0) { - rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR, &int_status->data[0], 1, dev); - } - - if(int_status_sel & BMI160_INT_STATUS_1) { - rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 1, &int_status->data[1], 1, dev); - } - - if(int_status_sel & BMI160_INT_STATUS_2) { - rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 2, &int_status->data[2], 1, dev); - } - - if(int_status_sel & BMI160_INT_STATUS_3) { - rslt = bmi160_get_regs(BMI160_INT_STATUS_ADDR + 3, &int_status->data[3], 1, dev); - } - } - - return rslt; -} - -/*********************** Local function definitions ***************************/ - -/*! - * @brief This API sets the any-motion interrupt of the sensor. - * This interrupt occurs when accel values exceeds preset threshold - * for a certain period of time. - */ -static int8_t - set_accel_any_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg = - &(int_config->int_type_cfg.acc_any_motion_int); - rslt = enable_accel_any_motion_int(any_motion_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_any_motion_int_settg(int_config, any_motion_int_cfg, dev); - } - } - - return rslt; -} - -/*! - * @brief This API sets tap interrupts.Interrupt is fired when - * tap movements happen. - */ -static int8_t - set_accel_tap_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_tap_int_cfg* tap_int_cfg = &(int_config->int_type_cfg.acc_tap_int); - rslt = enable_tap_int(int_config, tap_int_cfg, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_tap_int_settg(int_config, tap_int_cfg, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API sets the data ready interrupt for both accel and gyro. - * This interrupt occurs when new accel and gyro data comes. - */ -static int8_t set_accel_gyro_data_ready_int( - const struct bmi160_int_settg* int_config, - const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - rslt = enable_data_ready_int(dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_hardware_interrupt(int_config, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API sets the significant motion interrupt of the sensor.This - * interrupt occurs when there is change in user location. - */ -static int8_t - set_accel_sig_motion_int(struct bmi160_int_settg* int_config, struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg = - &(int_config->int_type_cfg.acc_sig_motion_int); - rslt = enable_sig_motion_int(sig_mot_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_sig_motion_int_settg(int_config, sig_mot_int_cfg, dev); - } - } - - return rslt; -} - -/*! - * @brief This API sets the no motion/slow motion interrupt of the sensor. - * Slow motion is similar to any motion interrupt.No motion interrupt - * occurs when slope bet. two accel values falls below preset threshold - * for preset duration. - */ -static int8_t - set_accel_no_motion_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg = - &(int_config->int_type_cfg.acc_no_motion_int); - rslt = enable_no_motion_int(no_mot_int_cfg, dev); - if(rslt == BMI160_OK) { - /* Configure the INT PIN settings*/ - rslt = config_no_motion_int_settg(int_config, no_mot_int_cfg, dev); - } - } - - return rslt; -} - -/*! - * @brief This API sets the step detection interrupt.This interrupt - * occurs when the single step causes accel values to go above - * preset threshold. - */ -static int8_t - set_accel_step_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg = - &(int_config->int_type_cfg.acc_step_detect_int); - rslt = enable_step_detect_int(step_detect_int_cfg, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_step_detect(step_detect_int_cfg, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This API sets the orientation interrupt of the sensor.This - * interrupt occurs when there is orientation change in the sensor - * with respect to gravitational field vector g. - */ -static int8_t - set_accel_orientation_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_orient_int_cfg* orient_int_cfg = - &(int_config->int_type_cfg.acc_orient_int); - rslt = enable_orient_int(orient_int_cfg, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - /* map INT pin to orient interrupt */ - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - /* configure the - * orientation setting*/ - rslt = config_orient_int_settg(orient_int_cfg, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This API sets the flat interrupt of the sensor.This interrupt - * occurs in case of flat orientation - */ -static int8_t - set_accel_flat_detect_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_flat_detect_int_cfg* flat_detect_int = - &(int_config->int_type_cfg.acc_flat_int); - - /* enable the flat interrupt */ - rslt = enable_flat_int(flat_detect_int, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - /* map INT pin to flat interrupt */ - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - /* configure the flat setting*/ - rslt = config_flat_int_settg(flat_detect_int, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This API sets the low-g interrupt of the sensor.This interrupt - * occurs during free-fall. - */ -static int8_t - set_accel_low_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_low_g_int_cfg* low_g_int = &(int_config->int_type_cfg.acc_low_g_int); - - /* Enable the low-g interrupt*/ - rslt = enable_low_g_int(low_g_int, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - /* Map INT pin to low-g interrupt */ - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - /* configure the data source - * for low-g interrupt*/ - rslt = config_low_g_data_src(low_g_int, dev); - if(rslt == BMI160_OK) { - rslt = config_low_g_int_settg(low_g_int, dev); - } - } - } - } - } - - return rslt; -} - -/*! - * @brief This API sets the high-g interrupt of the sensor.The interrupt - * occurs if the absolute value of acceleration data of any enabled axis - * exceeds the programmed threshold and the sign of the value does not - * change for a preset duration. - */ -static int8_t - set_accel_high_g_int(struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if((rslt != BMI160_OK) || (int_config == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* updating the interrupt structure to local structure */ - struct bmi160_acc_high_g_int_cfg* high_g_int_cfg = - &(int_config->int_type_cfg.acc_high_g_int); - - /* Enable the high-g interrupt */ - rslt = enable_high_g_int(high_g_int_cfg, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - /* Map INT pin to high-g interrupt */ - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - /* configure the data source - * for high-g interrupt*/ - rslt = config_high_g_data_src(high_g_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_high_g_int_settg(high_g_int_cfg, dev); - } - } - } - } - } - - return rslt; -} - -/*! - * @brief This API configures the pins to fire the - * interrupt signal when it occurs. - */ -static int8_t - set_intr_pin_config(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - - /* configure the behavioural settings of interrupt pin */ - rslt = config_int_out_ctrl(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_int_latch(int_config, dev); - } - - return rslt; -} - -/*! - * @brief This internal API is used to validate the device structure pointer for - * null conditions. - */ -static int8_t null_ptr_check(const struct bmi160_dev* dev) { - int8_t rslt; - - if((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Device structure is fine */ - rslt = BMI160_OK; - } - - return rslt; -} - -/*! - * @brief This API sets the default configuration parameters of accel & gyro. - * Also maintain the previous state of configurations. - */ -static void default_param_settg(struct bmi160_dev* dev) { - /* Initializing accel and gyro params with - * default values */ - dev->accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; - dev->accel_cfg.odr = BMI160_ACCEL_ODR_100HZ; - dev->accel_cfg.power = BMI160_ACCEL_SUSPEND_MODE; - dev->accel_cfg.range = BMI160_ACCEL_RANGE_2G; - dev->gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; - dev->gyro_cfg.odr = BMI160_GYRO_ODR_100HZ; - dev->gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE; - dev->gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; - - /* To maintain the previous state of accel configuration */ - dev->prev_accel_cfg = dev->accel_cfg; - - /* To maintain the previous state of gyro configuration */ - dev->prev_gyro_cfg = dev->gyro_cfg; -} - -/*! - * @brief This API set the accel configuration. - */ -static int8_t set_accel_conf(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[2] = {0}; - - rslt = check_accel_config(data, dev); - if(rslt == BMI160_OK) { - /* Write output data rate and bandwidth */ - rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, &data[0], 1, dev); - if(rslt == BMI160_OK) { - dev->prev_accel_cfg.odr = dev->accel_cfg.odr; - dev->prev_accel_cfg.bw = dev->accel_cfg.bw; - - /* write accel range */ - rslt = bmi160_set_regs(BMI160_ACCEL_RANGE_ADDR, &data[1], 1, dev); - if(rslt == BMI160_OK) { - dev->prev_accel_cfg.range = dev->accel_cfg.range; - } - } - } - - return rslt; -} - -/*! - * @brief This API gets the accel configuration. - */ -static int8_t get_accel_conf(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[2] = {0}; - - /* Get accel configurations */ - rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 2, dev); - if(rslt == BMI160_OK) { - dev->accel_cfg.odr = (data[0] & BMI160_ACCEL_ODR_MASK); - dev->accel_cfg.bw = (data[0] & BMI160_ACCEL_BW_MASK) >> BMI160_ACCEL_BW_POS; - dev->accel_cfg.range = (data[1] & BMI160_ACCEL_RANGE_MASK); - } - - return rslt; -} - -/*! - * @brief This API check the accel configuration. - */ -static int8_t check_accel_config(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt; - - /* read accel Output data rate and bandwidth */ - rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 2, dev); - if(rslt == BMI160_OK) { - rslt = process_accel_odr(&data[0], dev); - if(rslt == BMI160_OK) { - rslt = process_accel_bw(&data[0], dev); - if(rslt == BMI160_OK) { - rslt = process_accel_range(&data[1], dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API process the accel odr. - */ -static int8_t process_accel_odr(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t temp = 0; - uint8_t odr = 0; - - if(dev->accel_cfg.odr <= BMI160_ACCEL_ODR_1600HZ) { - if(dev->accel_cfg.odr != dev->prev_accel_cfg.odr) { - odr = (uint8_t)dev->accel_cfg.odr; - temp = *data & ~BMI160_ACCEL_ODR_MASK; - - /* Adding output data rate */ - *data = temp | (odr & BMI160_ACCEL_ODR_MASK); - } - } else { - rslt = BMI160_E_OUT_OF_RANGE; - } - - return rslt; -} - -/*! - * @brief This API process the accel bandwidth. - */ -static int8_t process_accel_bw(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t temp = 0; - uint8_t bw = 0; - - if(dev->accel_cfg.bw <= BMI160_ACCEL_BW_RES_AVG128) { - if(dev->accel_cfg.bw != dev->prev_accel_cfg.bw) { - bw = (uint8_t)dev->accel_cfg.bw; - temp = *data & ~BMI160_ACCEL_BW_MASK; - - /* Adding bandwidth */ - *data = temp | ((bw << 4) & BMI160_ACCEL_BW_MASK); - } - } else { - rslt = BMI160_E_OUT_OF_RANGE; - } - - return rslt; -} - -/*! - * @brief This API process the accel range. - */ -static int8_t process_accel_range(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t temp = 0; - uint8_t range = 0; - - if(dev->accel_cfg.range <= BMI160_ACCEL_RANGE_16G) { - if(dev->accel_cfg.range != dev->prev_accel_cfg.range) { - range = (uint8_t)dev->accel_cfg.range; - temp = *data & ~BMI160_ACCEL_RANGE_MASK; - - /* Adding range */ - *data = temp | (range & BMI160_ACCEL_RANGE_MASK); - } - } else { - rslt = BMI160_E_OUT_OF_RANGE; - } - - return rslt; -} - -/*! - * @brief This API checks the invalid settings for ODR & Bw for - * Accel and Gyro. - */ -static int8_t check_invalid_settg(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - - /* read the error reg */ - rslt = bmi160_get_regs(BMI160_ERROR_REG_ADDR, &data, 1, dev); - data = data >> 1; - data = data & BMI160_ERR_REG_MASK; - if(data == 1) { - rslt = BMI160_E_ACCEL_ODR_BW_INVALID; - } else if(data == 2) { - rslt = BMI160_E_GYRO_ODR_BW_INVALID; - } else if(data == 3) { - rslt = BMI160_E_LWP_PRE_FLTR_INT_INVALID; - } else if(data == 7) { - rslt = BMI160_E_LWP_PRE_FLTR_INVALID; - } - - return rslt; -} -static int8_t set_gyro_conf(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[2] = {0}; - - rslt = check_gyro_config(data, dev); - if(rslt == BMI160_OK) { - /* Write output data rate and bandwidth */ - rslt = bmi160_set_regs(BMI160_GYRO_CONFIG_ADDR, &data[0], 1, dev); - if(rslt == BMI160_OK) { - dev->prev_gyro_cfg.odr = dev->gyro_cfg.odr; - dev->prev_gyro_cfg.bw = dev->gyro_cfg.bw; - - /* Write gyro range */ - rslt = bmi160_set_regs(BMI160_GYRO_RANGE_ADDR, &data[1], 1, dev); - if(rslt == BMI160_OK) { - dev->prev_gyro_cfg.range = dev->gyro_cfg.range; - } - } - } - - return rslt; -} - -/*! - * @brief This API gets the gyro configuration. - */ -static int8_t get_gyro_conf(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[2] = {0}; - - /* Get accel configurations */ - rslt = bmi160_get_regs(BMI160_GYRO_CONFIG_ADDR, data, 2, dev); - if(rslt == BMI160_OK) { - dev->gyro_cfg.odr = (data[0] & BMI160_GYRO_ODR_MASK); - dev->gyro_cfg.bw = (data[0] & BMI160_GYRO_BW_MASK) >> BMI160_GYRO_BW_POS; - dev->gyro_cfg.range = (data[1] & BMI160_GYRO_RANGE_MASK); - } - - return rslt; -} - -/*! - * @brief This API check the gyro configuration. - */ -static int8_t check_gyro_config(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt; - - /* read gyro Output data rate and bandwidth */ - rslt = bmi160_get_regs(BMI160_GYRO_CONFIG_ADDR, data, 2, dev); - if(rslt == BMI160_OK) { - rslt = process_gyro_odr(&data[0], dev); - if(rslt == BMI160_OK) { - rslt = process_gyro_bw(&data[0], dev); - if(rslt == BMI160_OK) { - rslt = process_gyro_range(&data[1], dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API process the gyro odr. - */ -static int8_t process_gyro_odr(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t temp = 0; - uint8_t odr = 0; - - if(dev->gyro_cfg.odr <= BMI160_GYRO_ODR_3200HZ) { - if(dev->gyro_cfg.odr != dev->prev_gyro_cfg.odr) { - odr = (uint8_t)dev->gyro_cfg.odr; - temp = (*data & ~BMI160_GYRO_ODR_MASK); - - /* Adding output data rate */ - *data = temp | (odr & BMI160_GYRO_ODR_MASK); - } - } else { - rslt = BMI160_E_OUT_OF_RANGE; - } - - return rslt; -} - -/*! - * @brief This API process the gyro bandwidth. - */ -static int8_t process_gyro_bw(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t temp = 0; - uint8_t bw = 0; - - if(dev->gyro_cfg.bw <= BMI160_GYRO_BW_NORMAL_MODE) { - bw = (uint8_t)dev->gyro_cfg.bw; - temp = *data & ~BMI160_GYRO_BW_MASK; - - /* Adding bandwidth */ - *data = temp | ((bw << 4) & BMI160_GYRO_BW_MASK); - } else { - rslt = BMI160_E_OUT_OF_RANGE; - } - - return rslt; -} - -/*! - * @brief This API process the gyro range. - */ -static int8_t process_gyro_range(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t temp = 0; - uint8_t range = 0; - - if(dev->gyro_cfg.range <= BMI160_GYRO_RANGE_125_DPS) { - if(dev->gyro_cfg.range != dev->prev_gyro_cfg.range) { - range = (uint8_t)dev->gyro_cfg.range; - temp = *data & ~BMI160_GYRO_RANGE_MASK; - - /* Adding range */ - *data = temp | (range & BMI160_GYRO_RANGE_MASK); - } - } else { - rslt = BMI160_E_OUT_OF_RANGE; - } - - return rslt; -} - -/*! - * @brief This API sets the accel power. - */ -static int8_t set_accel_pwr(struct bmi160_dev* dev) { - int8_t rslt = 0; - uint8_t data = 0; - - if((dev->accel_cfg.power >= BMI160_ACCEL_SUSPEND_MODE) && - (dev->accel_cfg.power <= BMI160_ACCEL_LOWPOWER_MODE)) { - if(dev->accel_cfg.power != dev->prev_accel_cfg.power) { - rslt = process_under_sampling(&data, dev); - if(rslt == BMI160_OK) { - /* Write accel power */ - rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->accel_cfg.power, 1, dev); - - /* Add delay of 3.8 ms - refer data sheet table 24*/ - if(dev->prev_accel_cfg.power == BMI160_ACCEL_SUSPEND_MODE) { - dev->delay_ms(BMI160_ACCEL_DELAY_MS); - } - - dev->prev_accel_cfg.power = dev->accel_cfg.power; - } - } - } else { - rslt = BMI160_E_INVALID_CONFIG; - } - - return rslt; -} - -/*! - * @brief This API process the undersampling setting of Accel. - */ -static int8_t process_under_sampling(uint8_t* data, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t pre_filter[2] = {0}; - - rslt = bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); - if(rslt == BMI160_OK) { - if(dev->accel_cfg.power == BMI160_ACCEL_LOWPOWER_MODE) { - temp = *data & ~BMI160_ACCEL_UNDERSAMPLING_MASK; - - /* Set under-sampling parameter */ - *data = temp | ((1 << 7) & BMI160_ACCEL_UNDERSAMPLING_MASK); - - /* Write data */ - rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); - - /* Disable the pre-filter data in low power mode */ - if(rslt == BMI160_OK) { - /* Disable the Pre-filter data*/ - rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, pre_filter, 2, dev); - } - } else if(*data & BMI160_ACCEL_UNDERSAMPLING_MASK) { - temp = *data & ~BMI160_ACCEL_UNDERSAMPLING_MASK; - - /* Disable under-sampling parameter if already enabled */ - *data = temp; - - /* Write data */ - rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API sets the gyro power mode. - */ -static int8_t set_gyro_pwr(struct bmi160_dev* dev) { - int8_t rslt = 0; - - if((dev->gyro_cfg.power == BMI160_GYRO_SUSPEND_MODE) || - (dev->gyro_cfg.power == BMI160_GYRO_NORMAL_MODE) || - (dev->gyro_cfg.power == BMI160_GYRO_FASTSTARTUP_MODE)) { - if(dev->gyro_cfg.power != dev->prev_gyro_cfg.power) { - /* Write gyro power */ - rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->gyro_cfg.power, 1, dev); - if(dev->prev_gyro_cfg.power == BMI160_GYRO_SUSPEND_MODE) { - /* Delay of 80 ms - datasheet Table 24 */ - dev->delay_ms(BMI160_GYRO_DELAY_MS); - } else if( - (dev->prev_gyro_cfg.power == BMI160_GYRO_FASTSTARTUP_MODE) && - (dev->gyro_cfg.power == BMI160_GYRO_NORMAL_MODE)) { - /* This delay is required for transition from - * fast-startup mode to normal mode - datasheet Table 3 */ - dev->delay_ms(10); - } else { - /* do nothing */ - } - - dev->prev_gyro_cfg.power = dev->gyro_cfg.power; - } - } else { - rslt = BMI160_E_INVALID_CONFIG; - } - - return rslt; -} - -/*! - * @brief This API reads accel data along with sensor time if time is requested - * by user. Kindly refer the user guide(README.md) for more info. - */ -static int8_t - get_accel_data(uint8_t len, struct bmi160_sensor_data* accel, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t idx = 0; - uint8_t data_array[9] = {0}; - uint8_t time_0 = 0; - uint16_t time_1 = 0; - uint32_t time_2 = 0; - uint8_t lsb; - uint8_t msb; - int16_t msblsb; - - /* read accel sensor data along with time if requested */ - rslt = bmi160_get_regs(BMI160_ACCEL_DATA_ADDR, data_array, 6 + len, dev); - if(rslt == BMI160_OK) { - /* Accel Data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - accel->x = msblsb; /* Data in X axis */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - accel->y = msblsb; /* Data in Y axis */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - accel->z = msblsb; /* Data in Z axis */ - if(len == 3) { - time_0 = data_array[idx++]; - time_1 = (uint16_t)(data_array[idx++] << 8); - time_2 = (uint32_t)(data_array[idx++] << 16); - accel->sensortime = (uint32_t)(time_2 | time_1 | time_0); - } else { - accel->sensortime = 0; - } - } else { - rslt = BMI160_E_COM_FAIL; - } - - return rslt; -} - -/*! - * @brief This API reads accel data along with sensor time if time is requested - * by user. Kindly refer the user guide(README.md) for more info. - */ -static int8_t - get_gyro_data(uint8_t len, struct bmi160_sensor_data* gyro, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t idx = 0; - uint8_t data_array[15] = {0}; - uint8_t time_0 = 0; - uint16_t time_1 = 0; - uint32_t time_2 = 0; - uint8_t lsb; - uint8_t msb; - int16_t msblsb; - - if(len == 0) { - /* read gyro data only */ - rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 6, dev); - if(rslt == BMI160_OK) { - /* Gyro Data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->x = msblsb; /* Data in X axis */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->y = msblsb; /* Data in Y axis */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->z = msblsb; /* Data in Z axis */ - gyro->sensortime = 0; - } else { - rslt = BMI160_E_COM_FAIL; - } - } else { - /* read gyro sensor data along with time */ - rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 12 + len, dev); - if(rslt == BMI160_OK) { - /* Gyro Data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->x = msblsb; /* gyro X axis data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->y = msblsb; /* gyro Y axis data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->z = msblsb; /* gyro Z axis data */ - idx = idx + 6; - time_0 = data_array[idx++]; - time_1 = (uint16_t)(data_array[idx++] << 8); - time_2 = (uint32_t)(data_array[idx++] << 16); - gyro->sensortime = (uint32_t)(time_2 | time_1 | time_0); - } else { - rslt = BMI160_E_COM_FAIL; - } - } - - return rslt; -} - -/*! - * @brief This API reads accel and gyro data along with sensor time - * if time is requested by user. - * Kindly refer the user guide(README.md) for more info. - */ -static int8_t get_accel_gyro_data( - uint8_t len, - struct bmi160_sensor_data* accel, - struct bmi160_sensor_data* gyro, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t idx = 0; - uint8_t data_array[15] = {0}; - uint8_t time_0 = 0; - uint16_t time_1 = 0; - uint32_t time_2 = 0; - uint8_t lsb; - uint8_t msb; - int16_t msblsb; - - /* read both accel and gyro sensor data - * along with time if requested */ - rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 12 + len, dev); - if(rslt == BMI160_OK) { - /* Gyro Data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->x = msblsb; /* gyro X axis data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->y = msblsb; /* gyro Y axis data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - gyro->z = msblsb; /* gyro Z axis data */ - /* Accel Data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - accel->x = (int16_t)msblsb; /* accel X axis data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - accel->y = (int16_t)msblsb; /* accel Y axis data */ - lsb = data_array[idx++]; - msb = data_array[idx++]; - msblsb = (int16_t)((msb << 8) | lsb); - accel->z = (int16_t)msblsb; /* accel Z axis data */ - if(len == 3) { - time_0 = data_array[idx++]; - time_1 = (uint16_t)(data_array[idx++] << 8); - time_2 = (uint32_t)(data_array[idx++] << 16); - accel->sensortime = (uint32_t)(time_2 | time_1 | time_0); - gyro->sensortime = (uint32_t)(time_2 | time_1 | time_0); - } else { - accel->sensortime = 0; - gyro->sensortime = 0; - } - } else { - rslt = BMI160_E_COM_FAIL; - } - - return rslt; -} - -/*! - * @brief This API enables the any-motion interrupt for accel. - */ -static int8_t enable_accel_any_motion_int( - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable any motion x, any motion y, any motion z - * in Int Enable 0 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - if(any_motion_int_cfg->anymotion_en == BMI160_ENABLE) { - temp = data & ~BMI160_ANY_MOTION_X_INT_EN_MASK; - - /* Adding Any_motion x axis */ - data = temp | (any_motion_int_cfg->anymotion_x & BMI160_ANY_MOTION_X_INT_EN_MASK); - temp = data & ~BMI160_ANY_MOTION_Y_INT_EN_MASK; - - /* Adding Any_motion y axis */ - data = temp | - ((any_motion_int_cfg->anymotion_y << 1) & BMI160_ANY_MOTION_Y_INT_EN_MASK); - temp = data & ~BMI160_ANY_MOTION_Z_INT_EN_MASK; - - /* Adding Any_motion z axis */ - data = temp | - ((any_motion_int_cfg->anymotion_z << 2) & BMI160_ANY_MOTION_Z_INT_EN_MASK); - - /* any-motion feature selected*/ - dev->any_sig_sel = BMI160_ANY_MOTION_ENABLED; - } else { - data = data & ~BMI160_ANY_MOTION_ALL_INT_EN_MASK; - - /* neither any-motion feature nor sig-motion selected */ - dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; - } - - /* write data to Int Enable 0 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API disable the sig-motion interrupt. - */ -static int8_t disable_sig_motion_int(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Disabling Significant motion interrupt if enabled */ - rslt = bmi160_get_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = (data & BMI160_SIG_MOTION_SEL_MASK); - if(temp) { - temp = data & ~BMI160_SIG_MOTION_SEL_MASK; - data = temp; - - /* Write data to register */ - rslt = bmi160_set_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API is used to map/unmap the Any/Sig motion, Step det/Low-g, - * Double tap, Single tap, Orientation, Flat, High-G, Nomotion interrupt pins. - */ -static int8_t - map_feature_interrupt(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data[3] = {0, 0, 0}; - uint8_t temp[3] = {0, 0, 0}; - - rslt = bmi160_get_regs(BMI160_INT_MAP_0_ADDR, data, 3, dev); - if(rslt == BMI160_OK) { - temp[0] = data[0] & ~int_mask_lookup_table[int_config->int_type]; - temp[2] = data[2] & ~int_mask_lookup_table[int_config->int_type]; - switch(int_config->int_channel) { - case BMI160_INT_CHANNEL_NONE: - data[0] = temp[0]; - data[2] = temp[2]; - break; - case BMI160_INT_CHANNEL_1: - data[0] = temp[0] | int_mask_lookup_table[int_config->int_type]; - data[2] = temp[2]; - break; - case BMI160_INT_CHANNEL_2: - data[2] = temp[2] | int_mask_lookup_table[int_config->int_type]; - data[0] = temp[0]; - break; - case BMI160_INT_CHANNEL_BOTH: - data[0] = temp[0] | int_mask_lookup_table[int_config->int_type]; - data[2] = temp[2] | int_mask_lookup_table[int_config->int_type]; - break; - default: - rslt = BMI160_E_OUT_OF_RANGE; - } - if(rslt == BMI160_OK) { - rslt = bmi160_set_regs(BMI160_INT_MAP_0_ADDR, data, 3, dev); - } - } - - return rslt; -} - -/*! - * @brief This API is used to map/unmap the Dataready(Accel & Gyro), FIFO full - * and FIFO watermark interrupt. - */ -static int8_t map_hardware_interrupt( - const struct bmi160_int_settg* int_config, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - rslt = bmi160_get_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~int_mask_lookup_table[int_config->int_type]; - temp = temp & ~((uint8_t)(int_mask_lookup_table[int_config->int_type] << 4)); - switch(int_config->int_channel) { - case BMI160_INT_CHANNEL_NONE: - data = temp; - break; - case BMI160_INT_CHANNEL_1: - data = temp | (uint8_t)((int_mask_lookup_table[int_config->int_type]) << 4); - break; - case BMI160_INT_CHANNEL_2: - data = temp | int_mask_lookup_table[int_config->int_type]; - break; - case BMI160_INT_CHANNEL_BOTH: - data = temp | int_mask_lookup_table[int_config->int_type]; - data = data | (uint8_t)((int_mask_lookup_table[int_config->int_type]) << 4); - break; - default: - rslt = BMI160_E_OUT_OF_RANGE; - } - if(rslt == BMI160_OK) { - rslt = bmi160_set_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for any-motion interrupt. - */ -static int8_t config_any_motion_src( - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Configure Int data 1 register to add source of interrupt */ - rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_MOTION_SRC_INT_MASK; - data = temp | ((any_motion_int_cfg->anymotion_data_src << 7) & BMI160_MOTION_SRC_INT_MASK); - - /* Write data to DATA 1 address */ - rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the duration and threshold of - * any-motion interrupt. - */ -static int8_t config_any_dur_threshold( - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - uint8_t data_array[2] = {0}; - uint8_t dur; - - /* Configure Int Motion 0 register */ - rslt = bmi160_get_regs(BMI160_INT_MOTION_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* slope duration */ - dur = (uint8_t)any_motion_int_cfg->anymotion_dur; - temp = data & ~BMI160_SLOPE_INT_DUR_MASK; - data = temp | (dur & BMI160_MOTION_SRC_INT_MASK); - data_array[0] = data; - - /* add slope threshold */ - data_array[1] = any_motion_int_cfg->anymotion_thr; - - /* INT MOTION 0 and INT MOTION 1 address lie consecutively, - * hence writing data to respective registers at one go */ - - /* Writing to Int_motion 0 and - * Int_motion 1 Address simultaneously */ - rslt = bmi160_set_regs(BMI160_INT_MOTION_0_ADDR, data_array, 2, dev); - } - - return rslt; -} - -/*! - * @brief This API configure necessary setting of any-motion interrupt. - */ -static int8_t config_any_motion_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_any_mot_int_cfg* any_motion_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = disable_sig_motion_int(dev); - if(rslt == BMI160_OK) { - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_any_motion_src(any_motion_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_any_dur_threshold(any_motion_int_cfg, dev); - } - } - } - } - - return rslt; -} - -/*! - * @brief This API enable the data ready interrupt. - */ -static int8_t enable_data_ready_int(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable data ready interrupt in Int Enable 1 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_DATA_RDY_INT_EN_MASK; - data = temp | ((1 << 4) & BMI160_DATA_RDY_INT_EN_MASK); - - /* Writing data to INT ENABLE 1 Address */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API enables the no motion/slow motion interrupt. - */ -static int8_t enable_no_motion_int( - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable no motion x, no motion y, no motion z - * in Int Enable 2 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - if(no_mot_int_cfg->no_motion_x == 1) { - temp = data & ~BMI160_NO_MOTION_X_INT_EN_MASK; - - /* Adding No_motion x axis */ - data = temp | (1 & BMI160_NO_MOTION_X_INT_EN_MASK); - } - - if(no_mot_int_cfg->no_motion_y == 1) { - temp = data & ~BMI160_NO_MOTION_Y_INT_EN_MASK; - - /* Adding No_motion x axis */ - data = temp | ((1 << 1) & BMI160_NO_MOTION_Y_INT_EN_MASK); - } - - if(no_mot_int_cfg->no_motion_z == 1) { - temp = data & ~BMI160_NO_MOTION_Z_INT_EN_MASK; - - /* Adding No_motion x axis */ - data = temp | ((1 << 2) & BMI160_NO_MOTION_Z_INT_EN_MASK); - } - - /* write data to Int Enable 2 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the interrupt PIN setting for - * no motion/slow motion interrupt. - */ -static int8_t config_no_motion_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_no_motion_data_src(no_mot_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_no_motion_dur_thr(no_mot_int_cfg, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API configure the source of interrupt for no motion. - */ -static int8_t config_no_motion_data_src( - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Configure Int data 1 register to add source of interrupt */ - rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_MOTION_SRC_INT_MASK; - data = temp | ((no_mot_int_cfg->no_motion_src << 7) & BMI160_MOTION_SRC_INT_MASK); - - /* Write data to DATA 1 address */ - rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the duration and threshold of - * no motion/slow motion interrupt along with selection of no/slow motion. - */ -static int8_t config_no_motion_dur_thr( - const struct bmi160_acc_no_motion_int_cfg* no_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - uint8_t temp_1 = 0; - uint8_t reg_addr; - uint8_t data_array[2] = {0}; - - /* Configuring INT_MOTION register */ - reg_addr = BMI160_INT_MOTION_0_ADDR; - rslt = bmi160_get_regs(reg_addr, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_NO_MOTION_INT_DUR_MASK; - - /* Adding no_motion duration */ - data = temp | ((no_mot_int_cfg->no_motion_dur << 2) & BMI160_NO_MOTION_INT_DUR_MASK); - - /* Write data to NO_MOTION 0 address */ - rslt = bmi160_set_regs(reg_addr, &data, 1, dev); - if(rslt == BMI160_OK) { - reg_addr = BMI160_INT_MOTION_3_ADDR; - rslt = bmi160_get_regs(reg_addr, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_NO_MOTION_SEL_BIT_MASK; - - /* Adding no_motion_sel bit */ - temp_1 = (no_mot_int_cfg->no_motion_sel & BMI160_NO_MOTION_SEL_BIT_MASK); - data = (temp | temp_1); - data_array[1] = data; - - /* Adding no motion threshold */ - data_array[0] = no_mot_int_cfg->no_motion_thres; - reg_addr = BMI160_INT_MOTION_2_ADDR; - - /* writing data to INT_MOTION 2 and INT_MOTION 3 - * address simultaneously */ - rslt = bmi160_set_regs(reg_addr, data_array, 2, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API enables the sig-motion motion interrupt. - */ -static int8_t enable_sig_motion_int( - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* For significant motion,enable any motion x,any motion y, - * any motion z in Int Enable 0 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - if(sig_mot_int_cfg->sig_en == BMI160_ENABLE) { - temp = data & ~BMI160_SIG_MOTION_INT_EN_MASK; - data = temp | (7 & BMI160_SIG_MOTION_INT_EN_MASK); - - /* sig-motion feature selected*/ - dev->any_sig_sel = BMI160_SIG_MOTION_ENABLED; - } else { - data = data & ~BMI160_SIG_MOTION_INT_EN_MASK; - - /* neither any-motion feature nor sig-motion selected */ - dev->any_sig_sel = BMI160_BOTH_ANY_SIG_MOTION_DISABLED; - } - - /* write data to Int Enable 0 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the interrupt PIN setting for - * significant motion interrupt. - */ -static int8_t config_sig_motion_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_sig_motion_data_src(sig_mot_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_sig_dur_threshold(sig_mot_int_cfg, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for sig motion interrupt. - */ -static int8_t config_sig_motion_data_src( - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Configure Int data 1 register to add source of interrupt */ - rslt = bmi160_get_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_MOTION_SRC_INT_MASK; - data = temp | ((sig_mot_int_cfg->sig_data_src << 7) & BMI160_MOTION_SRC_INT_MASK); - - /* Write data to DATA 1 address */ - rslt = bmi160_set_regs(BMI160_INT_DATA_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the threshold, skip and proof time of - * sig motion interrupt. - */ -static int8_t config_sig_dur_threshold( - const struct bmi160_acc_sig_mot_int_cfg* sig_mot_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data; - uint8_t temp = 0; - - /* Configuring INT_MOTION registers */ - - /* Write significant motion threshold. - * This threshold is same as any motion threshold */ - data = sig_mot_int_cfg->sig_mot_thres; - - /* Write data to INT_MOTION 1 address */ - rslt = bmi160_set_regs(BMI160_INT_MOTION_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - rslt = bmi160_get_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_SIG_MOTION_SKIP_MASK; - - /* adding skip time of sig_motion interrupt*/ - data = temp | ((sig_mot_int_cfg->sig_mot_skip << 2) & BMI160_SIG_MOTION_SKIP_MASK); - temp = data & ~BMI160_SIG_MOTION_PROOF_MASK; - - /* adding proof time of sig_motion interrupt */ - data = temp | ((sig_mot_int_cfg->sig_mot_proof << 4) & BMI160_SIG_MOTION_PROOF_MASK); - - /* configure the int_sig_mot_sel bit to select - * significant motion interrupt */ - temp = data & ~BMI160_SIG_MOTION_SEL_MASK; - data = temp | ((sig_mot_int_cfg->sig_en << 1) & BMI160_SIG_MOTION_SEL_MASK); - rslt = bmi160_set_regs(BMI160_INT_MOTION_3_ADDR, &data, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API enables the step detector interrupt. - */ -static int8_t enable_step_detect_int( - const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable data ready interrupt in Int Enable 2 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_STEP_DETECT_INT_EN_MASK; - data = temp | - ((step_detect_int_cfg->step_detector_en << 3) & BMI160_STEP_DETECT_INT_EN_MASK); - - /* Writing data to INT ENABLE 2 Address */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_2_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the step detector parameter. - */ -static int8_t config_step_detect( - const struct bmi160_acc_step_detect_int_cfg* step_detect_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t data_array[2] = {0}; - - if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_NORMAL) { - /* Normal mode setting */ - data_array[0] = 0x15; - data_array[1] = 0x03; - } else if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_SENSITIVE) { - /* Sensitive mode setting */ - data_array[0] = 0x2D; - data_array[1] = 0x00; - } else if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_ROBUST) { - /* Robust mode setting */ - data_array[0] = 0x1D; - data_array[1] = 0x07; - } else if(step_detect_int_cfg->step_detector_mode == BMI160_STEP_DETECT_USER_DEFINE) { - /* Non recommended User defined setting */ - /* Configuring STEP_CONFIG register */ - rslt = bmi160_get_regs(BMI160_INT_STEP_CONFIG_0_ADDR, &data_array[0], 2, dev); - if(rslt == BMI160_OK) { - temp = data_array[0] & ~BMI160_STEP_DETECT_MIN_THRES_MASK; - - /* Adding min_threshold */ - data_array[0] = temp | ((step_detect_int_cfg->min_threshold << 3) & - BMI160_STEP_DETECT_MIN_THRES_MASK); - temp = data_array[0] & ~BMI160_STEP_DETECT_STEPTIME_MIN_MASK; - - /* Adding steptime_min */ - data_array[0] = temp | ((step_detect_int_cfg->steptime_min) & - BMI160_STEP_DETECT_STEPTIME_MIN_MASK); - temp = data_array[1] & ~BMI160_STEP_MIN_BUF_MASK; - - /* Adding steptime_min */ - data_array[1] = temp | - ((step_detect_int_cfg->step_min_buf) & BMI160_STEP_MIN_BUF_MASK); - } - } - - /* Write data to STEP_CONFIG register */ - rslt = bmi160_set_regs(BMI160_INT_STEP_CONFIG_0_ADDR, data_array, 2, dev); - - return rslt; -} - -/*! - * @brief This API enables the single/double tap interrupt. - */ -static int8_t enable_tap_int( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable single tap or double tap interrupt in Int Enable 0 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - if(int_config->int_type == BMI160_ACC_SINGLE_TAP_INT) { - temp = data & ~BMI160_SINGLE_TAP_INT_EN_MASK; - data = temp | ((tap_int_cfg->tap_en << 5) & BMI160_SINGLE_TAP_INT_EN_MASK); - } else { - temp = data & ~BMI160_DOUBLE_TAP_INT_EN_MASK; - data = temp | ((tap_int_cfg->tap_en << 4) & BMI160_DOUBLE_TAP_INT_EN_MASK); - } - - /* Write to Enable 0 Address */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the interrupt PIN setting for - * tap interrupt. - */ -static int8_t config_tap_int_settg( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_feature_interrupt(int_config, dev); - if(rslt == BMI160_OK) { - rslt = config_tap_data_src(tap_int_cfg, dev); - if(rslt == BMI160_OK) { - rslt = config_tap_param(int_config, tap_int_cfg, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for tap interrupt. - */ -static int8_t config_tap_data_src( - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Configure Int data 0 register to add source of interrupt */ - rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_TAP_SRC_INT_MASK; - data = temp | ((tap_int_cfg->tap_data_src << 3) & BMI160_TAP_SRC_INT_MASK); - - /* Write data to Data 0 address */ - rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the parameters of tap interrupt. - * Threshold, quite, shock, and duration. - */ -static int8_t config_tap_param( - const struct bmi160_int_settg* int_config, - const struct bmi160_acc_tap_int_cfg* tap_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t data = 0; - uint8_t data_array[2] = {0}; - uint8_t count = 0; - uint8_t dur, shock, quiet, thres; - - /* Configure tap 0 register for tap shock,tap quiet duration - * in case of single tap interrupt */ - rslt = bmi160_get_regs(BMI160_INT_TAP_0_ADDR, data_array, 2, dev); - if(rslt == BMI160_OK) { - data = data_array[count]; - if(int_config->int_type == BMI160_ACC_DOUBLE_TAP_INT) { - dur = (uint8_t)tap_int_cfg->tap_dur; - temp = (data & ~BMI160_TAP_DUR_MASK); - - /* Add tap duration data in case of - * double tap interrupt */ - data = temp | (dur & BMI160_TAP_DUR_MASK); - } - - shock = (uint8_t)tap_int_cfg->tap_shock; - temp = data & ~BMI160_TAP_SHOCK_DUR_MASK; - data = temp | ((shock << 6) & BMI160_TAP_SHOCK_DUR_MASK); - quiet = (uint8_t)tap_int_cfg->tap_quiet; - temp = data & ~BMI160_TAP_QUIET_DUR_MASK; - data = temp | ((quiet << 7) & BMI160_TAP_QUIET_DUR_MASK); - data_array[count++] = data; - data = data_array[count]; - thres = (uint8_t)tap_int_cfg->tap_thr; - temp = data & ~BMI160_TAP_THRES_MASK; - data = temp | (thres & BMI160_TAP_THRES_MASK); - data_array[count++] = data; - - /* TAP 0 and TAP 1 address lie consecutively, - * hence writing data to respective registers at one go */ - - /* Writing to Tap 0 and Tap 1 Address simultaneously */ - rslt = bmi160_set_regs(BMI160_INT_TAP_0_ADDR, data_array, count, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the secondary interface. - */ -static int8_t config_sec_if(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t if_conf = 0; - uint8_t cmd = BMI160_AUX_NORMAL_MODE; - - /* set the aux power mode to normal*/ - rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); - if(rslt == BMI160_OK) { - /* 0.5ms delay - refer datasheet table 24*/ - dev->delay_ms(1); - rslt = bmi160_get_regs(BMI160_IF_CONF_ADDR, &if_conf, 1, dev); - if_conf |= (uint8_t)(1 << 5); - if(rslt == BMI160_OK) { - /*enable the secondary interface also*/ - rslt = bmi160_set_regs(BMI160_IF_CONF_ADDR, &if_conf, 1, dev); - } - } - - return rslt; -} - -/*! - * @brief This API configure the ODR of the auxiliary sensor. - */ -static int8_t config_aux_odr(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t aux_odr; - - rslt = bmi160_get_regs(BMI160_AUX_ODR_ADDR, &aux_odr, 1, dev); - if(rslt == BMI160_OK) { - aux_odr = (uint8_t)(dev->aux_cfg.aux_odr); - - /* Set the secondary interface ODR - * i.e polling rate of secondary sensor */ - rslt = bmi160_set_regs(BMI160_AUX_ODR_ADDR, &aux_odr, 1, dev); - dev->delay_ms(BMI160_AUX_COM_DELAY); - } - - return rslt; -} - -/*! - * @brief This API maps the actual burst read length set by user. - */ -static int8_t map_read_len(uint16_t* len, const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - switch(dev->aux_cfg.aux_rd_burst_len) { - case BMI160_AUX_READ_LEN_0: - *len = 1; - break; - case BMI160_AUX_READ_LEN_1: - *len = 2; - break; - case BMI160_AUX_READ_LEN_2: - *len = 6; - break; - case BMI160_AUX_READ_LEN_3: - *len = 8; - break; - default: - rslt = BMI160_E_INVALID_INPUT; - break; - } - - return rslt; -} - -/*! - * @brief This API configure the settings of auxiliary sensor. - */ -static int8_t config_aux_settg(const struct bmi160_dev* dev) { - int8_t rslt; - - rslt = config_sec_if(dev); - if(rslt == BMI160_OK) { - /* Configures the auxiliary interface settings */ - rslt = bmi160_config_aux_mode(dev); - } - - return rslt; -} - -/*! - * @brief This API extract the read data from auxiliary sensor. - */ -static int8_t extract_aux_read( - uint16_t map_len, - uint8_t reg_addr, - uint8_t* aux_data, - uint16_t len, - const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - uint8_t data[8] = { - 0, - }; - uint8_t read_addr = BMI160_AUX_DATA_ADDR; - uint8_t count = 0; - uint8_t read_count; - uint8_t read_len = (uint8_t)map_len; - - for(; count < len;) { - /* set address to read */ - rslt = bmi160_set_regs(BMI160_AUX_IF_2_ADDR, ®_addr, 1, dev); - dev->delay_ms(BMI160_AUX_COM_DELAY); - if(rslt == BMI160_OK) { - rslt = bmi160_get_regs(read_addr, data, map_len, dev); - if(rslt == BMI160_OK) { - read_count = 0; - - /* if read len is less the burst read len - * mention by user*/ - if(len < map_len) { - read_len = (uint8_t)len; - } else if((len - count) < map_len) { - read_len = (uint8_t)(len - count); - } - - for(; read_count < read_len; read_count++) { - aux_data[count + read_count] = data[read_count]; - } - - reg_addr += (uint8_t)map_len; - count += (uint8_t)map_len; - } else { - rslt = BMI160_E_COM_FAIL; - break; - } - } - } - - return rslt; -} - -/*! - * @brief This API enables the orient interrupt. - */ -static int8_t enable_orient_int( - const struct bmi160_acc_orient_int_cfg* orient_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable data ready interrupt in Int Enable 0 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_ORIENT_INT_EN_MASK; - data = temp | ((orient_int_cfg->orient_en << 6) & BMI160_ORIENT_INT_EN_MASK); - - /* write data to Int Enable 0 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the necessary setting of orientation interrupt. - */ -static int8_t config_orient_int_settg( - const struct bmi160_acc_orient_int_cfg* orient_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - uint8_t data_array[2] = {0, 0}; - - /* Configuring INT_ORIENT registers */ - rslt = bmi160_get_regs(BMI160_INT_ORIENT_0_ADDR, data_array, 2, dev); - if(rslt == BMI160_OK) { - data = data_array[0]; - temp = data & ~BMI160_ORIENT_MODE_MASK; - - /* Adding Orientation mode */ - data = temp | ((orient_int_cfg->orient_mode) & BMI160_ORIENT_MODE_MASK); - temp = data & ~BMI160_ORIENT_BLOCK_MASK; - - /* Adding Orientation blocking */ - data = temp | ((orient_int_cfg->orient_blocking << 2) & BMI160_ORIENT_BLOCK_MASK); - temp = data & ~BMI160_ORIENT_HYST_MASK; - - /* Adding Orientation hysteresis */ - data = temp | ((orient_int_cfg->orient_hyst << 4) & BMI160_ORIENT_HYST_MASK); - data_array[0] = data; - data = data_array[1]; - temp = data & ~BMI160_ORIENT_THETA_MASK; - - /* Adding Orientation threshold */ - data = temp | ((orient_int_cfg->orient_theta) & BMI160_ORIENT_THETA_MASK); - temp = data & ~BMI160_ORIENT_UD_ENABLE; - - /* Adding Orient_ud_en */ - data = temp | ((orient_int_cfg->orient_ud_en << 6) & BMI160_ORIENT_UD_ENABLE); - temp = data & ~BMI160_AXES_EN_MASK; - - /* Adding axes_en */ - data = temp | ((orient_int_cfg->axes_ex << 7) & BMI160_AXES_EN_MASK); - data_array[1] = data; - - /* Writing data to INT_ORIENT 0 and INT_ORIENT 1 - * registers simultaneously */ - rslt = bmi160_set_regs(BMI160_INT_ORIENT_0_ADDR, data_array, 2, dev); - } - - return rslt; -} - -/*! - * @brief This API enables the flat interrupt. - */ -static int8_t enable_flat_int( - const struct bmi160_acc_flat_detect_int_cfg* flat_int, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable flat interrupt in Int Enable 0 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_FLAT_INT_EN_MASK; - data = temp | ((flat_int->flat_en << 7) & BMI160_FLAT_INT_EN_MASK); - - /* write data to Int Enable 0 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the necessary setting of flat interrupt. - */ -static int8_t config_flat_int_settg( - const struct bmi160_acc_flat_detect_int_cfg* flat_int, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - uint8_t data_array[2] = {0, 0}; - - /* Configuring INT_FLAT register */ - rslt = bmi160_get_regs(BMI160_INT_FLAT_0_ADDR, data_array, 2, dev); - if(rslt == BMI160_OK) { - data = data_array[0]; - temp = data & ~BMI160_FLAT_THRES_MASK; - - /* Adding flat theta */ - data = temp | ((flat_int->flat_theta) & BMI160_FLAT_THRES_MASK); - data_array[0] = data; - data = data_array[1]; - temp = data & ~BMI160_FLAT_HOLD_TIME_MASK; - - /* Adding flat hold time */ - data = temp | ((flat_int->flat_hold_time << 4) & BMI160_FLAT_HOLD_TIME_MASK); - temp = data & ~BMI160_FLAT_HYST_MASK; - - /* Adding flat hysteresis */ - data = temp | ((flat_int->flat_hy) & BMI160_FLAT_HYST_MASK); - data_array[1] = data; - - /* Writing data to INT_FLAT 0 and INT_FLAT 1 - * registers simultaneously */ - rslt = bmi160_set_regs(BMI160_INT_FLAT_0_ADDR, data_array, 2, dev); - } - - return rslt; -} - -/*! - * @brief This API enables the Low-g interrupt. - */ -static int8_t enable_low_g_int( - const struct bmi160_acc_low_g_int_cfg* low_g_int, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable low-g interrupt in Int Enable 1 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_LOW_G_INT_EN_MASK; - data = temp | ((low_g_int->low_en << 3) & BMI160_LOW_G_INT_EN_MASK); - - /* write data to Int Enable 0 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for low-g interrupt. - */ -static int8_t config_low_g_data_src( - const struct bmi160_acc_low_g_int_cfg* low_g_int, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Configure Int data 0 register to add source of interrupt */ - rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_LOW_HIGH_SRC_INT_MASK; - data = temp | ((low_g_int->low_data_src << 7) & BMI160_LOW_HIGH_SRC_INT_MASK); - - /* Write data to Data 0 address */ - rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the necessary setting of low-g interrupt. - */ -static int8_t config_low_g_int_settg( - const struct bmi160_acc_low_g_int_cfg* low_g_int, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t data_array[3] = {0, 0, 0}; - - /* Configuring INT_LOWHIGH register for low-g interrupt */ - rslt = bmi160_get_regs(BMI160_INT_LOWHIGH_2_ADDR, &data_array[2], 1, dev); - if(rslt == BMI160_OK) { - temp = data_array[2] & ~BMI160_LOW_G_HYST_MASK; - - /* Adding low-g hysteresis */ - data_array[2] = temp | (low_g_int->low_hyst & BMI160_LOW_G_HYST_MASK); - temp = data_array[2] & ~BMI160_LOW_G_LOW_MODE_MASK; - - /* Adding low-mode */ - data_array[2] = temp | ((low_g_int->low_mode << 2) & BMI160_LOW_G_LOW_MODE_MASK); - - /* Adding low-g threshold */ - data_array[1] = low_g_int->low_thres; - - /* Adding low-g interrupt delay */ - data_array[0] = low_g_int->low_dur; - - /* Writing data to INT_LOWHIGH 0,1,2 registers simultaneously*/ - rslt = bmi160_set_regs(BMI160_INT_LOWHIGH_0_ADDR, data_array, 3, dev); - } - - return rslt; -} - -/*! - * @brief This API enables the high-g interrupt. - */ -static int8_t enable_high_g_int( - const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Enable low-g interrupt in Int Enable 1 register */ - rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* Adding high-g X-axis */ - temp = data & ~BMI160_HIGH_G_X_INT_EN_MASK; - data = temp | (high_g_int_cfg->high_g_x & BMI160_HIGH_G_X_INT_EN_MASK); - - /* Adding high-g Y-axis */ - temp = data & ~BMI160_HIGH_G_Y_INT_EN_MASK; - data = temp | ((high_g_int_cfg->high_g_y << 1) & BMI160_HIGH_G_Y_INT_EN_MASK); - - /* Adding high-g Z-axis */ - temp = data & ~BMI160_HIGH_G_Z_INT_EN_MASK; - data = temp | ((high_g_int_cfg->high_g_z << 2) & BMI160_HIGH_G_Z_INT_EN_MASK); - - /* write data to Int Enable 0 register */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the source of data(filter & pre-filter) - * for high-g interrupt. - */ -static int8_t config_high_g_data_src( - const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - uint8_t temp = 0; - - /* Configure Int data 0 register to add source of interrupt */ - rslt = bmi160_get_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - temp = data & ~BMI160_LOW_HIGH_SRC_INT_MASK; - data = temp | ((high_g_int_cfg->high_data_src << 7) & BMI160_LOW_HIGH_SRC_INT_MASK); - - /* Write data to Data 0 address */ - rslt = bmi160_set_regs(BMI160_INT_DATA_0_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the necessary setting of high-g interrupt. - */ -static int8_t config_high_g_int_settg( - const struct bmi160_acc_high_g_int_cfg* high_g_int_cfg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t data_array[3] = {0, 0, 0}; - - rslt = bmi160_get_regs(BMI160_INT_LOWHIGH_2_ADDR, &data_array[0], 1, dev); - if(rslt == BMI160_OK) { - temp = data_array[0] & ~BMI160_HIGH_G_HYST_MASK; - - /* Adding high-g hysteresis */ - data_array[0] = temp | ((high_g_int_cfg->high_hy << 6) & BMI160_HIGH_G_HYST_MASK); - - /* Adding high-g duration */ - data_array[1] = high_g_int_cfg->high_dur; - - /* Adding high-g threshold */ - data_array[2] = high_g_int_cfg->high_thres; - rslt = bmi160_set_regs(BMI160_INT_LOWHIGH_2_ADDR, data_array, 3, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the behavioural setting of interrupt pin. - */ -static int8_t - config_int_out_ctrl(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t data = 0; - - /* Configuration of output interrupt signals on pins INT1 and INT2 are - * done in BMI160_INT_OUT_CTRL_ADDR register*/ - rslt = bmi160_get_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* updating the interrupt pin structure to local structure */ - const struct bmi160_int_pin_settg* intr_pin_sett = &(int_config->int_pin_settg); - - /* Configuring channel 1 */ - if(int_config->int_channel == BMI160_INT_CHANNEL_1) { - /* Output enable */ - temp = data & ~BMI160_INT1_OUTPUT_EN_MASK; - data = temp | ((intr_pin_sett->output_en << 3) & BMI160_INT1_OUTPUT_EN_MASK); - - /* Output mode */ - temp = data & ~BMI160_INT1_OUTPUT_MODE_MASK; - data = temp | ((intr_pin_sett->output_mode << 2) & BMI160_INT1_OUTPUT_MODE_MASK); - - /* Output type */ - temp = data & ~BMI160_INT1_OUTPUT_TYPE_MASK; - data = temp | ((intr_pin_sett->output_type << 1) & BMI160_INT1_OUTPUT_TYPE_MASK); - - /* edge control */ - temp = data & ~BMI160_INT1_EDGE_CTRL_MASK; - data = temp | ((intr_pin_sett->edge_ctrl) & BMI160_INT1_EDGE_CTRL_MASK); - } else { - /* Configuring channel 2 */ - /* Output enable */ - temp = data & ~BMI160_INT2_OUTPUT_EN_MASK; - data = temp | ((intr_pin_sett->output_en << 7) & BMI160_INT2_OUTPUT_EN_MASK); - - /* Output mode */ - temp = data & ~BMI160_INT2_OUTPUT_MODE_MASK; - data = temp | ((intr_pin_sett->output_mode << 6) & BMI160_INT2_OUTPUT_MODE_MASK); - - /* Output type */ - temp = data & ~BMI160_INT2_OUTPUT_TYPE_MASK; - data = temp | ((intr_pin_sett->output_type << 5) & BMI160_INT2_OUTPUT_TYPE_MASK); - - /* edge control */ - temp = data & ~BMI160_INT2_EDGE_CTRL_MASK; - data = temp | ((intr_pin_sett->edge_ctrl << 4) & BMI160_INT2_EDGE_CTRL_MASK); - } - - rslt = bmi160_set_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API configure the mode(input enable, latch or non-latch) of interrupt pin. - */ -static int8_t - config_int_latch(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t temp = 0; - uint8_t data = 0; - - /* Configuration of latch on pins INT1 and INT2 are done in - * BMI160_INT_LATCH_ADDR register*/ - rslt = bmi160_get_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* updating the interrupt pin structure to local structure */ - const struct bmi160_int_pin_settg* intr_pin_sett = &(int_config->int_pin_settg); - if(int_config->int_channel == BMI160_INT_CHANNEL_1) { - /* Configuring channel 1 */ - /* Input enable */ - temp = data & ~BMI160_INT1_INPUT_EN_MASK; - data = temp | ((intr_pin_sett->input_en << 4) & BMI160_INT1_INPUT_EN_MASK); - } else { - /* Configuring channel 2 */ - /* Input enable */ - temp = data & ~BMI160_INT2_INPUT_EN_MASK; - data = temp | ((intr_pin_sett->input_en << 5) & BMI160_INT2_INPUT_EN_MASK); - } - - /* In case of latch interrupt,update the latch duration */ - - /* Latching holds the interrupt for the amount of latch - * duration time */ - temp = data & ~BMI160_INT_LATCH_MASK; - data = temp | (intr_pin_sett->latch_dur & BMI160_INT_LATCH_MASK); - - /* OUT_CTRL_INT and LATCH_INT address lie consecutively, - * hence writing data to respective registers at one go */ - rslt = bmi160_set_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API performs the self test for accelerometer of BMI160 - */ -static int8_t perform_accel_self_test(struct bmi160_dev* dev) { - int8_t rslt; - struct bmi160_sensor_data accel_pos, accel_neg; - - /* Enable Gyro self test bit */ - rslt = enable_accel_self_test(dev); - if(rslt == BMI160_OK) { - /* Perform accel self test with positive excitation */ - rslt = accel_self_test_positive_excitation(&accel_pos, dev); - if(rslt == BMI160_OK) { - /* Perform accel self test with negative excitation */ - rslt = accel_self_test_negative_excitation(&accel_neg, dev); - if(rslt == BMI160_OK) { - /* Validate the self test result */ - rslt = validate_accel_self_test(&accel_pos, &accel_neg); - } - } - } - - return rslt; -} - -/*! - * @brief This API enables to perform the accel self test by setting proper - * configurations to facilitate accel self test - */ -static int8_t enable_accel_self_test(struct bmi160_dev* dev) { - int8_t rslt; - uint8_t reg_data; - - /* Set the Accel power mode as normal mode */ - dev->accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; - - /* Set the sensor range configuration as 8G */ - dev->accel_cfg.range = BMI160_ACCEL_RANGE_8G; - rslt = bmi160_set_sens_conf(dev); - if(rslt == BMI160_OK) { - /* Accel configurations are set to facilitate self test - * acc_odr - 1600Hz ; acc_bwp = 2 ; acc_us = 0 */ - reg_data = BMI160_ACCEL_SELF_TEST_CONFIG; - rslt = bmi160_set_regs(BMI160_ACCEL_CONFIG_ADDR, ®_data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API performs accel self test with positive excitation - */ -static int8_t accel_self_test_positive_excitation( - struct bmi160_sensor_data* accel_pos, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t reg_data; - - /* Enable accel self test with positive self-test excitation - * and with amplitude of deflection set as high */ - reg_data = BMI160_ACCEL_SELF_TEST_POSITIVE_EN; - rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); - if(rslt == BMI160_OK) { - /* Read the data after a delay of 50ms - refer datasheet 2.8.1 accel self test*/ - dev->delay_ms(BMI160_ACCEL_SELF_TEST_DELAY); - rslt = bmi160_get_sensor_data(BMI160_ACCEL_ONLY, accel_pos, NULL, dev); - } - - return rslt; -} - -/*! - * @brief This API performs accel self test with negative excitation - */ -static int8_t accel_self_test_negative_excitation( - struct bmi160_sensor_data* accel_neg, - const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t reg_data; - - /* Enable accel self test with negative self-test excitation - * and with amplitude of deflection set as high */ - reg_data = BMI160_ACCEL_SELF_TEST_NEGATIVE_EN; - rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); - if(rslt == BMI160_OK) { - /* Read the data after a delay of 50ms */ - dev->delay_ms(BMI160_ACCEL_SELF_TEST_DELAY); - rslt = bmi160_get_sensor_data(BMI160_ACCEL_ONLY, accel_neg, NULL, dev); - } - - return rslt; -} - -/*! - * @brief This API validates the accel self test results - */ -static int8_t validate_accel_self_test( - const struct bmi160_sensor_data* accel_pos, - const struct bmi160_sensor_data* accel_neg) { - int8_t rslt; - - /* Validate the results of self test */ - if(((accel_neg->x - accel_pos->x) > BMI160_ACCEL_SELF_TEST_LIMIT) && - ((accel_neg->y - accel_pos->y) > BMI160_ACCEL_SELF_TEST_LIMIT) && - ((accel_neg->z - accel_pos->z) > BMI160_ACCEL_SELF_TEST_LIMIT)) { - /* Self test pass condition */ - rslt = BMI160_OK; - } else { - rslt = BMI160_W_ACCEl_SELF_TEST_FAIL; - } - - return rslt; -} - -/*! - * @brief This API performs the self test for gyroscope of BMI160 - */ -static int8_t perform_gyro_self_test(const struct bmi160_dev* dev) { - int8_t rslt; - - /* Enable Gyro self test bit */ - rslt = enable_gyro_self_test(dev); - if(rslt == BMI160_OK) { - /* Validate the gyro self test a delay of 50ms */ - dev->delay_ms(50); - - /* Validate the gyro self test results */ - rslt = validate_gyro_self_test(dev); - } - - return rslt; -} - -/*! - * @brief This API enables the self test bit to trigger self test for Gyro - */ -static int8_t enable_gyro_self_test(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t reg_data; - - /* Enable the Gyro self test bit to trigger the self test */ - rslt = bmi160_get_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); - if(rslt == BMI160_OK) { - reg_data = BMI160_SET_BITS(reg_data, BMI160_GYRO_SELF_TEST, 1); - rslt = bmi160_set_regs(BMI160_SELF_TEST_ADDR, ®_data, 1, dev); - if(rslt == BMI160_OK) { - /* Delay to enable gyro self test */ - dev->delay_ms(15); - } - } - - return rslt; -} - -/*! - * @brief This API validates the self test results of Gyro - */ -static int8_t validate_gyro_self_test(const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t reg_data; - - /* Validate the Gyro self test result */ - rslt = bmi160_get_regs(BMI160_STATUS_ADDR, ®_data, 1, dev); - if(rslt == BMI160_OK) { - reg_data = BMI160_GET_BITS(reg_data, BMI160_GYRO_SELF_TEST_STATUS); - if(reg_data == BMI160_ENABLE) { - /* Gyro self test success case */ - rslt = BMI160_OK; - } else { - rslt = BMI160_W_GYRO_SELF_TEST_FAIL; - } - } - - return rslt; -} - -/*! - * @brief This API sets FIFO full interrupt of the sensor.This interrupt - * occurs when the FIFO is full and the next full data sample would cause - * a FIFO overflow, which may delete the old samples. - */ -static int8_t - set_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - /* Null-pointer check */ - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /*enable the fifo full interrupt */ - rslt = enable_fifo_full_int(int_config, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_hardware_interrupt(int_config, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This enable the FIFO full interrupt engine. - */ -static int8_t - enable_fifo_full_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - - rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - data = BMI160_SET_BITS(data, BMI160_FIFO_FULL_INT, int_config->fifo_full_int_en); - - /* Writing data to INT ENABLE 1 Address */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API sets FIFO watermark interrupt of the sensor.The FIFO - * watermark interrupt is fired, when the FIFO fill level is above a fifo - * watermark. - */ -static int8_t set_fifo_watermark_int( - const struct bmi160_int_settg* int_config, - const struct bmi160_dev* dev) { - int8_t rslt = BMI160_OK; - - if((dev == NULL) || (dev->delay_ms == NULL)) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Enable fifo-watermark interrupt in Int Enable 1 register */ - rslt = enable_fifo_wtm_int(int_config, dev); - if(rslt == BMI160_OK) { - /* Configure Interrupt pins */ - rslt = set_intr_pin_config(int_config, dev); - if(rslt == BMI160_OK) { - rslt = map_hardware_interrupt(int_config, dev); - } - } - } - - return rslt; -} - -/*! - * @brief This enable the FIFO watermark interrupt engine. - */ -static int8_t - enable_fifo_wtm_int(const struct bmi160_int_settg* int_config, const struct bmi160_dev* dev) { - int8_t rslt; - uint8_t data = 0; - - rslt = bmi160_get_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - data = BMI160_SET_BITS(data, BMI160_FIFO_WTM_INT, int_config->fifo_wtm_int_en); - - /* Writing data to INT ENABLE 1 Address */ - rslt = bmi160_set_regs(BMI160_INT_ENABLE_1_ADDR, &data, 1, dev); - } - - return rslt; -} - -/*! - * @brief This API is used to reset the FIFO related configurations - * in the fifo_frame structure. - */ -static void reset_fifo_data_structure(const struct bmi160_dev* dev) { - /*Prepare for next FIFO read by resetting FIFO's - * internal data structures*/ - dev->fifo->accel_byte_start_idx = 0; - dev->fifo->gyro_byte_start_idx = 0; - dev->fifo->aux_byte_start_idx = 0; - dev->fifo->sensor_time = 0; - dev->fifo->skipped_frame_count = 0; -} - -/*! - * @brief This API is used to read fifo_byte_counter value (i.e) - * current fill-level in Fifo buffer. - */ -static int8_t get_fifo_byte_counter(uint16_t* bytes_to_read, struct bmi160_dev const* dev) { - int8_t rslt = 0; - uint8_t data[2]; - uint8_t addr = BMI160_FIFO_LENGTH_ADDR; - - rslt |= bmi160_get_regs(addr, data, 2, dev); - data[1] = data[1] & BMI160_FIFO_BYTE_COUNTER_MASK; - - /* Available data in FIFO is stored in bytes_to_read*/ - *bytes_to_read = (((uint16_t)data[1] << 8) | ((uint16_t)data[0])); - - return rslt; -} - -/*! - * @brief This API is used to compute the number of bytes of accel FIFO data - * which is to be parsed in header-less mode - */ -static void get_accel_len_to_parse( - uint16_t* data_index, - uint16_t* data_read_length, - const uint8_t* acc_frame_count, - const struct bmi160_dev* dev) { - /* Data start index */ - *data_index = dev->fifo->accel_byte_start_idx; - if(dev->fifo->fifo_data_enable == BMI160_FIFO_A_ENABLE) { - *data_read_length = (*acc_frame_count) * BMI160_FIFO_A_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_G_A_ENABLE) { - *data_read_length = (*acc_frame_count) * BMI160_FIFO_GA_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_A_ENABLE) { - *data_read_length = (*acc_frame_count) * BMI160_FIFO_MA_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) { - *data_read_length = (*acc_frame_count) * BMI160_FIFO_MGA_LENGTH; - } else { - /* When accel is not enabled ,there will be no accel data. - * so we update the data index as complete */ - *data_index = dev->fifo->length; - } - - if(*data_read_length > dev->fifo->length) { - /* Handling the case where more data is requested - * than that is available*/ - *data_read_length = dev->fifo->length; - } -} - -/*! - * @brief This API is used to parse the accelerometer data from the - * FIFO data in both header mode and header-less mode. - * It updates the idx value which is used to store the index of - * the current data byte which is parsed. - */ -static void unpack_accel_frame( - struct bmi160_sensor_data* acc, - uint16_t* idx, - uint8_t* acc_idx, - uint8_t frame_info, - const struct bmi160_dev* dev) { - switch(frame_info) { - case BMI160_FIFO_HEAD_A: - case BMI160_FIFO_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_A_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into the structure instance "acc" */ - unpack_accel_data(&acc[*acc_idx], *idx, dev); - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_A_LENGTH; - (*acc_idx)++; - break; - case BMI160_FIFO_HEAD_G_A: - case BMI160_FIFO_G_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_GA_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into structure instance "acc"*/ - unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_G_LENGTH, dev); - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_GA_LENGTH; - (*acc_idx)++; - break; - case BMI160_FIFO_HEAD_M_A: - case BMI160_FIFO_M_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_MA_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into structure instance "acc"*/ - unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_M_LENGTH, dev); - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_MA_LENGTH; - (*acc_idx)++; - break; - case BMI160_FIFO_HEAD_M_G_A: - case BMI160_FIFO_M_G_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into structure instance "acc"*/ - unpack_accel_data(&acc[*acc_idx], *idx + BMI160_FIFO_MG_LENGTH, dev); - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_MGA_LENGTH; - (*acc_idx)++; - break; - case BMI160_FIFO_HEAD_M: - case BMI160_FIFO_M_ENABLE: - (*idx) = (*idx) + BMI160_FIFO_M_LENGTH; - break; - case BMI160_FIFO_HEAD_G: - case BMI160_FIFO_G_ENABLE: - (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; - break; - case BMI160_FIFO_HEAD_M_G: - case BMI160_FIFO_M_G_ENABLE: - (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; - break; - default: - break; - } -} - -/*! - * @brief This API is used to parse the accelerometer data from the - * FIFO data and store it in the instance of the structure bmi160_sensor_data. - */ -static void unpack_accel_data( - struct bmi160_sensor_data* accel_data, - uint16_t data_start_index, - const struct bmi160_dev* dev) { - uint16_t data_lsb; - uint16_t data_msb; - - /* Accel raw x data */ - data_lsb = dev->fifo->data[data_start_index++]; - data_msb = dev->fifo->data[data_start_index++]; - accel_data->x = (int16_t)((data_msb << 8) | data_lsb); - - /* Accel raw y data */ - data_lsb = dev->fifo->data[data_start_index++]; - data_msb = dev->fifo->data[data_start_index++]; - accel_data->y = (int16_t)((data_msb << 8) | data_lsb); - - /* Accel raw z data */ - data_lsb = dev->fifo->data[data_start_index++]; - data_msb = dev->fifo->data[data_start_index++]; - accel_data->z = (int16_t)((data_msb << 8) | data_lsb); -} - -/*! - * @brief This API is used to parse the accelerometer data from the - * FIFO data in header mode. - */ -static void extract_accel_header_mode( - struct bmi160_sensor_data* accel_data, - uint8_t* accel_length, - const struct bmi160_dev* dev) { - uint8_t frame_header = 0; - uint16_t data_index; - uint8_t accel_index = 0; - - for(data_index = dev->fifo->accel_byte_start_idx; data_index < dev->fifo->length;) { - /* extracting Frame header */ - frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); - - /*Index is moved to next byte where the data is starting*/ - data_index++; - switch(frame_header) { - /* Accel frame */ - case BMI160_FIFO_HEAD_A: - case BMI160_FIFO_HEAD_M_A: - case BMI160_FIFO_HEAD_G_A: - case BMI160_FIFO_HEAD_M_G_A: - unpack_accel_frame(accel_data, &data_index, &accel_index, frame_header, dev); - break; - case BMI160_FIFO_HEAD_M: - move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); - break; - case BMI160_FIFO_HEAD_G: - move_next_frame(&data_index, BMI160_FIFO_G_LENGTH, dev); - break; - case BMI160_FIFO_HEAD_M_G: - move_next_frame(&data_index, BMI160_FIFO_MG_LENGTH, dev); - break; - - /* Sensor time frame */ - case BMI160_FIFO_HEAD_SENSOR_TIME: - unpack_sensortime_frame(&data_index, dev); - break; - - /* Skip frame */ - case BMI160_FIFO_HEAD_SKIP_FRAME: - unpack_skipped_frame(&data_index, dev); - break; - - /* Input config frame */ - case BMI160_FIFO_HEAD_INPUT_CONFIG: - move_next_frame(&data_index, 1, dev); - break; - case BMI160_FIFO_HEAD_OVER_READ: - - /* Update the data index as complete in case of Over read */ - data_index = dev->fifo->length; - break; - default: - break; - } - if(*accel_length == accel_index) { - /* Number of frames to read completed */ - break; - } - } - - /*Update number of accel data read*/ - *accel_length = accel_index; - - /*Update the accel frame index*/ - dev->fifo->accel_byte_start_idx = data_index; -} - -/*! - * @brief This API computes the number of bytes of gyro FIFO data - * which is to be parsed in header-less mode - */ -static void get_gyro_len_to_parse( - uint16_t* data_index, - uint16_t* data_read_length, - const uint8_t* gyro_frame_count, - const struct bmi160_dev* dev) { - /* Data start index */ - *data_index = dev->fifo->gyro_byte_start_idx; - if(dev->fifo->fifo_data_enable == BMI160_FIFO_G_ENABLE) { - *data_read_length = (*gyro_frame_count) * BMI160_FIFO_G_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_G_A_ENABLE) { - *data_read_length = (*gyro_frame_count) * BMI160_FIFO_GA_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_ENABLE) { - *data_read_length = (*gyro_frame_count) * BMI160_FIFO_MG_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) { - *data_read_length = (*gyro_frame_count) * BMI160_FIFO_MGA_LENGTH; - } else { - /* When gyro is not enabled ,there will be no gyro data. - * so we update the data index as complete */ - *data_index = dev->fifo->length; - } - - if(*data_read_length > dev->fifo->length) { - /* Handling the case where more data is requested - * than that is available*/ - *data_read_length = dev->fifo->length; - } -} - -/*! - * @brief This API is used to parse the gyroscope's data from the - * FIFO data in both header mode and header-less mode. - * It updates the idx value which is used to store the index of - * the current data byte which is parsed. - */ -static void unpack_gyro_frame( - struct bmi160_sensor_data* gyro, - uint16_t* idx, - uint8_t* gyro_idx, - uint8_t frame_info, - const struct bmi160_dev* dev) { - switch(frame_info) { - case BMI160_FIFO_HEAD_G: - case BMI160_FIFO_G_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_G_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into structure instance "gyro"*/ - unpack_gyro_data(&gyro[*gyro_idx], *idx, dev); - - /*Move the data index*/ - (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; - (*gyro_idx)++; - break; - case BMI160_FIFO_HEAD_G_A: - case BMI160_FIFO_G_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_GA_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /* Unpack the data array into structure instance "gyro" */ - unpack_gyro_data(&gyro[*gyro_idx], *idx, dev); - - /* Move the data index */ - *idx = *idx + BMI160_FIFO_GA_LENGTH; - (*gyro_idx)++; - break; - case BMI160_FIFO_HEAD_M_G_A: - case BMI160_FIFO_M_G_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into structure instance "gyro"*/ - unpack_gyro_data(&gyro[*gyro_idx], *idx + BMI160_FIFO_M_LENGTH, dev); - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_MGA_LENGTH; - (*gyro_idx)++; - break; - case BMI160_FIFO_HEAD_M_A: - case BMI160_FIFO_M_A_ENABLE: - - /* Move the data index */ - *idx = *idx + BMI160_FIFO_MA_LENGTH; - break; - case BMI160_FIFO_HEAD_M: - case BMI160_FIFO_M_ENABLE: - (*idx) = (*idx) + BMI160_FIFO_M_LENGTH; - break; - case BMI160_FIFO_HEAD_M_G: - case BMI160_FIFO_M_G_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_MG_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *idx = dev->fifo->length; - break; - } - - /*Unpack the data array into structure instance "gyro"*/ - unpack_gyro_data(&gyro[*gyro_idx], *idx + BMI160_FIFO_M_LENGTH, dev); - - /*Move the data index*/ - (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; - (*gyro_idx)++; - break; - case BMI160_FIFO_HEAD_A: - case BMI160_FIFO_A_ENABLE: - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_A_LENGTH; - break; - default: - break; - } -} - -/*! - * @brief This API is used to parse the gyro data from the - * FIFO data and store it in the instance of the structure bmi160_sensor_data. - */ -static void unpack_gyro_data( - struct bmi160_sensor_data* gyro_data, - uint16_t data_start_index, - const struct bmi160_dev* dev) { - uint16_t data_lsb; - uint16_t data_msb; - - /* Gyro raw x data */ - data_lsb = dev->fifo->data[data_start_index++]; - data_msb = dev->fifo->data[data_start_index++]; - gyro_data->x = (int16_t)((data_msb << 8) | data_lsb); - - /* Gyro raw y data */ - data_lsb = dev->fifo->data[data_start_index++]; - data_msb = dev->fifo->data[data_start_index++]; - gyro_data->y = (int16_t)((data_msb << 8) | data_lsb); - - /* Gyro raw z data */ - data_lsb = dev->fifo->data[data_start_index++]; - data_msb = dev->fifo->data[data_start_index++]; - gyro_data->z = (int16_t)((data_msb << 8) | data_lsb); -} - -/*! - * @brief This API is used to parse the gyro data from the - * FIFO data in header mode. - */ -static void extract_gyro_header_mode( - struct bmi160_sensor_data* gyro_data, - uint8_t* gyro_length, - const struct bmi160_dev* dev) { - uint8_t frame_header = 0; - uint16_t data_index; - uint8_t gyro_index = 0; - - for(data_index = dev->fifo->gyro_byte_start_idx; data_index < dev->fifo->length;) { - /* extracting Frame header */ - frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); - - /*Index is moved to next byte where the data is starting*/ - data_index++; - switch(frame_header) { - /* GYRO frame */ - case BMI160_FIFO_HEAD_G: - case BMI160_FIFO_HEAD_G_A: - case BMI160_FIFO_HEAD_M_G: - case BMI160_FIFO_HEAD_M_G_A: - unpack_gyro_frame(gyro_data, &data_index, &gyro_index, frame_header, dev); - break; - case BMI160_FIFO_HEAD_A: - move_next_frame(&data_index, BMI160_FIFO_A_LENGTH, dev); - break; - case BMI160_FIFO_HEAD_M: - move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); - break; - case BMI160_FIFO_HEAD_M_A: - move_next_frame(&data_index, BMI160_FIFO_M_LENGTH, dev); - break; - - /* Sensor time frame */ - case BMI160_FIFO_HEAD_SENSOR_TIME: - unpack_sensortime_frame(&data_index, dev); - break; - - /* Skip frame */ - case BMI160_FIFO_HEAD_SKIP_FRAME: - unpack_skipped_frame(&data_index, dev); - break; - - /* Input config frame */ - case BMI160_FIFO_HEAD_INPUT_CONFIG: - move_next_frame(&data_index, 1, dev); - break; - case BMI160_FIFO_HEAD_OVER_READ: - - /* Update the data index as complete in case of over read */ - data_index = dev->fifo->length; - break; - default: - break; - } - if(*gyro_length == gyro_index) { - /*Number of frames to read completed*/ - break; - } - } - - /*Update number of gyro data read*/ - *gyro_length = gyro_index; - - /*Update the gyro frame index*/ - dev->fifo->gyro_byte_start_idx = data_index; +int8_t bmi160_write_i2c(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len) { + if(furi_hal_i2c_write_mem(&furi_hal_i2c_handle_external, dev_addr, reg_addr, data, len, 50)) + return BMI160_OK; + return BMI160_E_COM_FAIL; } -/*! - * @brief This API computes the number of bytes of aux FIFO data - * which is to be parsed in header-less mode - */ -static void get_aux_len_to_parse( - uint16_t* data_index, - uint16_t* data_read_length, - const uint8_t* aux_frame_count, - const struct bmi160_dev* dev) { - /* Data start index */ - *data_index = dev->fifo->gyro_byte_start_idx; - if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_ENABLE) { - *data_read_length = (*aux_frame_count) * BMI160_FIFO_M_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_A_ENABLE) { - *data_read_length = (*aux_frame_count) * BMI160_FIFO_MA_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_ENABLE) { - *data_read_length = (*aux_frame_count) * BMI160_FIFO_MG_LENGTH; - } else if(dev->fifo->fifo_data_enable == BMI160_FIFO_M_G_A_ENABLE) { - *data_read_length = (*aux_frame_count) * BMI160_FIFO_MGA_LENGTH; - } else { - /* When aux is not enabled ,there will be no aux data. - * so we update the data index as complete */ - *data_index = dev->fifo->length; - } - - if(*data_read_length > dev->fifo->length) { - /* Handling the case where more data is requested - * than that is available */ - *data_read_length = dev->fifo->length; - } +int8_t bmi160_read_i2c(uint8_t dev_addr, uint8_t reg_addr, uint8_t* read_data, uint16_t len) { + if(furi_hal_i2c_read_mem(&furi_hal_i2c_handle_external, dev_addr, reg_addr, read_data, len, 50)) + return BMI160_OK; + return BMI160_E_COM_FAIL; } -/*! - * @brief This API is used to parse the aux's data from the - * FIFO data in both header mode and header-less mode. - * It updates the idx value which is used to store the index of - * the current data byte which is parsed - */ -static void unpack_aux_frame( - struct bmi160_aux_data* aux_data, - uint16_t* idx, - uint8_t* aux_index, - uint8_t frame_info, - const struct bmi160_dev* dev) { - switch(frame_info) { - case BMI160_FIFO_HEAD_M: - case BMI160_FIFO_M_ENABLE: - - /* Partial read, then skip the data */ - if((*idx + BMI160_FIFO_M_LENGTH) > dev->fifo->length) { - /* Update the data index as complete */ - *idx = dev->fifo->length; - break; - } - - /* Unpack the data array into structure instance */ - unpack_aux_data(&aux_data[*aux_index], *idx, dev); - - /* Move the data index */ - *idx = *idx + BMI160_FIFO_M_LENGTH; - (*aux_index)++; - break; - case BMI160_FIFO_HEAD_M_A: - case BMI160_FIFO_M_A_ENABLE: - - /* Partial read, then skip the data */ - if((*idx + BMI160_FIFO_MA_LENGTH) > dev->fifo->length) { - /* Update the data index as complete */ - *idx = dev->fifo->length; - break; - } - - /* Unpack the data array into structure instance */ - unpack_aux_data(&aux_data[*aux_index], *idx, dev); - - /* Move the data index */ - *idx = *idx + BMI160_FIFO_MA_LENGTH; - (*aux_index)++; - break; - case BMI160_FIFO_HEAD_M_G: - case BMI160_FIFO_M_G_ENABLE: - - /* Partial read, then skip the data */ - if((*idx + BMI160_FIFO_MG_LENGTH) > dev->fifo->length) { - /* Update the data index as complete */ - *idx = dev->fifo->length; - break; - } +bool bmi160_begin() { + FURI_LOG_I(BMI160_TAG, "Init BMI160"); - /* Unpack the data array into structure instance */ - unpack_aux_data(&aux_data[*aux_index], *idx, dev); - - /* Move the data index */ - (*idx) = (*idx) + BMI160_FIFO_MG_LENGTH; - (*aux_index)++; - break; - case BMI160_FIFO_HEAD_M_G_A: - case BMI160_FIFO_M_G_A_ENABLE: - - /*Partial read, then skip the data*/ - if((*idx + BMI160_FIFO_MGA_LENGTH) > dev->fifo->length) { - /* Update the data index as complete */ - *idx = dev->fifo->length; - break; - } - - /* Unpack the data array into structure instance */ - unpack_aux_data(&aux_data[*aux_index], *idx, dev); - - /*Move the data index*/ - *idx = *idx + BMI160_FIFO_MGA_LENGTH; - (*aux_index)++; - break; - case BMI160_FIFO_HEAD_G: - case BMI160_FIFO_G_ENABLE: - - /* Move the data index */ - (*idx) = (*idx) + BMI160_FIFO_G_LENGTH; - break; - case BMI160_FIFO_HEAD_G_A: - case BMI160_FIFO_G_A_ENABLE: - - /* Move the data index */ - *idx = *idx + BMI160_FIFO_GA_LENGTH; - break; - case BMI160_FIFO_HEAD_A: - case BMI160_FIFO_A_ENABLE: - - /* Move the data index */ - *idx = *idx + BMI160_FIFO_A_LENGTH; - break; - default: - break; + if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, BMI160_DEV_ADDR, 50)) { + FURI_LOG_E(BMI160_TAG, "Device not ready!"); + return false; } -} -/*! - * @brief This API is used to parse the aux data from the - * FIFO data and store it in the instance of the structure bmi160_aux_data. - */ -static void unpack_aux_data( - struct bmi160_aux_data* aux_data, - uint16_t data_start_index, - const struct bmi160_dev* dev) { - /* Aux data bytes */ - aux_data->data[0] = dev->fifo->data[data_start_index++]; - aux_data->data[1] = dev->fifo->data[data_start_index++]; - aux_data->data[2] = dev->fifo->data[data_start_index++]; - aux_data->data[3] = dev->fifo->data[data_start_index++]; - aux_data->data[4] = dev->fifo->data[data_start_index++]; - aux_data->data[5] = dev->fifo->data[data_start_index++]; - aux_data->data[6] = dev->fifo->data[data_start_index++]; - aux_data->data[7] = dev->fifo->data[data_start_index++]; -} - -/*! - * @brief This API is used to parse the aux data from the - * FIFO data in header mode. - */ -static void extract_aux_header_mode( - struct bmi160_aux_data* aux_data, - uint8_t* aux_length, - const struct bmi160_dev* dev) { - uint8_t frame_header = 0; - uint16_t data_index; - uint8_t aux_index = 0; - - for(data_index = dev->fifo->aux_byte_start_idx; data_index < dev->fifo->length;) { - /* extracting Frame header */ - frame_header = (dev->fifo->data[data_index] & BMI160_FIFO_TAG_INTR_MASK); - - /*Index is moved to next byte where the data is starting*/ - data_index++; - switch(frame_header) { - /* Aux frame */ - case BMI160_FIFO_HEAD_M: - case BMI160_FIFO_HEAD_M_A: - case BMI160_FIFO_HEAD_M_G: - case BMI160_FIFO_HEAD_M_G_A: - unpack_aux_frame(aux_data, &data_index, &aux_index, frame_header, dev); - break; - case BMI160_FIFO_HEAD_G: - move_next_frame(&data_index, BMI160_FIFO_G_LENGTH, dev); - break; - case BMI160_FIFO_HEAD_G_A: - move_next_frame(&data_index, BMI160_FIFO_GA_LENGTH, dev); - break; - case BMI160_FIFO_HEAD_A: - move_next_frame(&data_index, BMI160_FIFO_A_LENGTH, dev); - break; + FURI_LOG_I(BMI160_TAG, "Device ready!"); - /* Sensor time frame */ - case BMI160_FIFO_HEAD_SENSOR_TIME: - unpack_sensortime_frame(&data_index, dev); - break; + bmi160dev.id = BMI160_DEV_ADDR; + bmi160dev.intf = BMI160_I2C_INTF; + bmi160dev.read = bmi160_read_i2c; + bmi160dev.write = bmi160_write_i2c; + bmi160dev.delay_ms = furi_delay_ms; - /* Skip frame */ - case BMI160_FIFO_HEAD_SKIP_FRAME: - unpack_skipped_frame(&data_index, dev); - break; - - /* Input config frame */ - case BMI160_FIFO_HEAD_INPUT_CONFIG: - move_next_frame(&data_index, 1, dev); - break; - case BMI160_FIFO_HEAD_OVER_READ: - - /* Update the data index as complete in case - * of over read */ - data_index = dev->fifo->length; - break; - default: - - /* Update the data index as complete in case of - * getting other headers like 0x00 */ - data_index = dev->fifo->length; - break; - } - if(*aux_length == aux_index) { - /*Number of frames to read completed*/ - break; - } + if(bmi160_init(&bmi160dev) != BMI160_OK) { + FURI_LOG_E(BMI160_TAG, "Initialization failure!"); + FURI_LOG_E(BMI160_TAG, "Chip ID 0x%X", bmi160dev.chip_id); + return false; } - /* Update number of aux data read */ - *aux_length = aux_index; - - /* Update the aux frame index */ - dev->fifo->aux_byte_start_idx = data_index; -} - -/*! - * @brief This API checks the presence of non-valid frames in the read fifo data. - */ -static void check_frame_validity(uint16_t* data_index, const struct bmi160_dev* dev) { - if((*data_index + 2) < dev->fifo->length) { - /* Check if FIFO is empty */ - if((dev->fifo->data[*data_index] == FIFO_CONFIG_MSB_CHECK) && - (dev->fifo->data[*data_index + 1] == FIFO_CONFIG_LSB_CHECK)) { - /*Update the data index as complete*/ - *data_index = dev->fifo->length; - } - } -} + bmi160dev.accel_cfg.odr = BMI160_ACCEL_ODR_400HZ; + bmi160dev.accel_cfg.range = BMI160_ACCEL_RANGE_4G; + bmi160dev.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; + bmi160dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; + bmi160dev.gyro_cfg.odr = BMI160_GYRO_ODR_400HZ; + bmi160dev.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; + bmi160dev.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; + bmi160dev.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; -/*! - * @brief This API is used to move the data index ahead of the - * current_frame_length parameter when unnecessary FIFO data appears while - * extracting the user specified data. - */ -static void move_next_frame( - uint16_t* data_index, - uint8_t current_frame_length, - const struct bmi160_dev* dev) { - /*Partial read, then move the data index to last data*/ - if((*data_index + current_frame_length) > dev->fifo->length) { - /*Update the data index as complete*/ - *data_index = dev->fifo->length; - } else { - /*Move the data index to next frame*/ - *data_index = *data_index + current_frame_length; + if(bmi160_set_sens_conf(&bmi160dev) != BMI160_OK) { + FURI_LOG_E(BMI160_TAG, "Initialization failure!"); + FURI_LOG_E(BMI160_TAG, "Chip ID 0x%X", bmi160dev.chip_id); + return false; } -} - -/*! - * @brief This API is used to parse and store the sensor time from the - * FIFO data in the structure instance dev. - */ -static void unpack_sensortime_frame(uint16_t* data_index, const struct bmi160_dev* dev) { - uint32_t sensor_time_byte3 = 0; - uint16_t sensor_time_byte2 = 0; - uint8_t sensor_time_byte1 = 0; - /*Partial read, then move the data index to last data*/ - if((*data_index + BMI160_SENSOR_TIME_LENGTH) > dev->fifo->length) { - /*Update the data index as complete*/ - *data_index = dev->fifo->length; - } else { - sensor_time_byte3 = dev->fifo->data[(*data_index) + BMI160_SENSOR_TIME_MSB_BYTE] << 16; - sensor_time_byte2 = dev->fifo->data[(*data_index) + BMI160_SENSOR_TIME_XLSB_BYTE] << 8; - sensor_time_byte1 = dev->fifo->data[(*data_index)]; + FURI_LOG_I(BMI160_TAG, "Initialization success!"); + FURI_LOG_I(BMI160_TAG, "Chip ID 0x%X", bmi160dev.chip_id); - /* Sensor time */ - dev->fifo->sensor_time = - (uint32_t)(sensor_time_byte3 | sensor_time_byte2 | sensor_time_byte1); - *data_index = (*data_index) + BMI160_SENSOR_TIME_LENGTH; - } + return true; } -/*! - * @brief This API is used to parse and store the skipped_frame_count from - * the FIFO data in the structure instance dev. - */ -static void unpack_skipped_frame(uint16_t* data_index, const struct bmi160_dev* dev) { - /*Partial read, then move the data index to last data*/ - if(*data_index >= dev->fifo->length) { - /*Update the data index as complete*/ - *data_index = dev->fifo->length; - } else { - dev->fifo->skipped_frame_count = dev->fifo->data[*data_index]; - - /*Move the data index*/ - *data_index = (*data_index) + 1; +int bmi160_read(double* vec) { + if(bmi160_get_sensor_data( + (BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &bmi160_accel, &bmi160_gyro, &bmi160dev) != + BMI160_OK) { + return 0; } -} - -/*! - * @brief This API is used to get the FOC status from the sensor - */ -static int8_t get_foc_status(uint8_t* foc_status, struct bmi160_dev const* dev) { - int8_t rslt; - uint8_t data; - /* Read the FOC status from sensor */ - rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* Get the foc_status bit */ - *foc_status = BMI160_GET_BITS(data, BMI160_FOC_STATUS); - } + vec[0] = ((double)bmi160_accel.x * 4 / 32768) * GRAVITY; + vec[1] = ((double)bmi160_accel.y * 4 / 32768) * GRAVITY; + vec[2] = ((double)bmi160_accel.z * 4 / 32768) * GRAVITY; + vec[3] = ((double)bmi160_gyro.x * 2000 / 32768) * DEG_TO_RAD; + vec[4] = ((double)bmi160_gyro.y * 2000 / 32768) * DEG_TO_RAD; + vec[5] = ((double)bmi160_gyro.z * 2000 / 32768) * DEG_TO_RAD; - return rslt; + return ACC_DATA_READY | GYR_DATA_READY; } -/*! - * @brief This API is used to configure the offset enable bits in the sensor - */ -static int8_t - configure_offset_enable(const struct bmi160_foc_conf* foc_conf, struct bmi160_dev const* dev) { - int8_t rslt; - uint8_t data; - - /* Null-pointer check */ - rslt = null_ptr_check(dev); - if(rslt != BMI160_OK) { - rslt = BMI160_E_NULL_PTR; - } else { - /* Read the FOC config from the sensor */ - rslt = bmi160_get_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); - if(rslt == BMI160_OK) { - /* Set the offset enable/disable for gyro */ - data = BMI160_SET_BITS(data, BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); - - /* Set the offset enable/disable for accel */ - data = BMI160_SET_BITS(data, BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); - - /* Set the offset config in the sensor */ - rslt = bmi160_set_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); - } - } - - return rslt; +void bmi160_end() { } -static int8_t trigger_foc(struct bmi160_offsets* offset, struct bmi160_dev const* dev) { - int8_t rslt; - uint8_t foc_status = BMI160_ENABLE; - uint8_t cmd = BMI160_START_FOC_CMD; - uint8_t timeout = 0; - uint8_t data_array[20]; - - /* Start the FOC process */ - rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); - if(rslt == BMI160_OK) { - /* Check the FOC status*/ - rslt = get_foc_status(&foc_status, dev); - - if((rslt != BMI160_OK) || (foc_status != BMI160_ENABLE)) { - while((foc_status != BMI160_ENABLE) && (timeout < 11)) { - /* Maximum time of 250ms is given in 10 - * steps of 25ms each - 250ms refer datasheet 2.9.1 */ - dev->delay_ms(25); - - /* Check the FOC status*/ - rslt = get_foc_status(&foc_status, dev); - timeout++; - } - - if((rslt == BMI160_OK) && (foc_status == BMI160_ENABLE)) { - /* Get offset values from sensor */ - rslt = bmi160_get_offsets(offset, dev); - } else { - /* FOC failure case */ - rslt = BMI160_E_FOC_FAILURE; - } - } - - if(rslt == BMI160_OK) { - /* Read registers 0x04-0x17 */ - rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, data_array, 20, dev); - } - } - - return rslt; -} +struct imu_t imu_bmi160 = {BMI160_DEV_ADDR, bmi160_begin, bmi160_end, bmi160_read, BMI160_TAG}; diff --git a/non_catalog_apps/airmouse/tracking/imu/bmi160_defs.h b/non_catalog_apps/airmouse/tracking/imu/bmi160_defs.h deleted file mode 100644 index 458ecaad5e7..00000000000 --- a/non_catalog_apps/airmouse/tracking/imu/bmi160_defs.h +++ /dev/null @@ -1,1619 +0,0 @@ -/** -* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved. -* -* BSD-3-Clause -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -* -* @file bmi160_defs.h -* @date 2021-10-05 -* @version v3.9.2 -* -*/ - -#ifndef BMI160_DEFS_H_ -#define BMI160_DEFS_H_ - -/*************************** C types headers *****************************/ -#ifdef __KERNEL__ -#include -#include -#else -#include -#include -#endif - -/*************************** Common macros *****************************/ - -#if !defined(UINT8_C) && !defined(INT8_C) -#define INT8_C(x) S8_C(x) -#define UINT8_C(x) U8_C(x) -#endif - -#if !defined(UINT16_C) && !defined(INT16_C) -#define INT16_C(x) S16_C(x) -#define UINT16_C(x) U16_C(x) -#endif - -#if !defined(INT32_C) && !defined(UINT32_C) -#define INT32_C(x) S32_C(x) -#define UINT32_C(x) U32_C(x) -#endif - -#if !defined(INT64_C) && !defined(UINT64_C) -#define INT64_C(x) S64_C(x) -#define UINT64_C(x) U64_C(x) -#endif - -/**@}*/ -/**\name C standard macros */ -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void*)0) -#endif -#endif - -/*************************** Sensor macros *****************************/ -/* Test for an endian machine */ -#ifndef __ORDER_LITTLE_ENDIAN__ -#define __ORDER_LITTLE_ENDIAN__ 0 -#endif - -#ifndef __BYTE_ORDER__ -#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -#endif - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1 -#endif -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 1 -#endif -#else -#error "Code does not support Endian format of the processor" -#endif - -/** Mask definitions */ -#define BMI160_ACCEL_BW_MASK UINT8_C(0x70) -#define BMI160_ACCEL_ODR_MASK UINT8_C(0x0F) -#define BMI160_ACCEL_UNDERSAMPLING_MASK UINT8_C(0x80) -#define BMI160_ACCEL_RANGE_MASK UINT8_C(0x0F) -#define BMI160_GYRO_BW_MASK UINT8_C(0x30) -#define BMI160_GYRO_ODR_MASK UINT8_C(0x0F) -#define BMI160_GYRO_RANGE_MASK UINT8_C(0x07) - -#define BMI160_ACCEL_BW_POS UINT8_C(4) -#define BMI160_GYRO_BW_POS UINT8_C(4) - -/** Mask definitions for INT_EN registers */ -#define BMI160_ANY_MOTION_X_INT_EN_MASK UINT8_C(0x01) -#define BMI160_HIGH_G_X_INT_EN_MASK UINT8_C(0x01) -#define BMI160_NO_MOTION_X_INT_EN_MASK UINT8_C(0x01) -#define BMI160_ANY_MOTION_Y_INT_EN_MASK UINT8_C(0x02) -#define BMI160_HIGH_G_Y_INT_EN_MASK UINT8_C(0x02) -#define BMI160_NO_MOTION_Y_INT_EN_MASK UINT8_C(0x02) -#define BMI160_ANY_MOTION_Z_INT_EN_MASK UINT8_C(0x04) -#define BMI160_HIGH_G_Z_INT_EN_MASK UINT8_C(0x04) -#define BMI160_NO_MOTION_Z_INT_EN_MASK UINT8_C(0x04) -#define BMI160_SIG_MOTION_INT_EN_MASK UINT8_C(0x07) -#define BMI160_ANY_MOTION_ALL_INT_EN_MASK UINT8_C(0x07) -#define BMI160_STEP_DETECT_INT_EN_MASK UINT8_C(0x08) -#define BMI160_DOUBLE_TAP_INT_EN_MASK UINT8_C(0x10) -#define BMI160_SINGLE_TAP_INT_EN_MASK UINT8_C(0x20) -#define BMI160_FIFO_FULL_INT_EN_MASK UINT8_C(0x20) -#define BMI160_ORIENT_INT_EN_MASK UINT8_C(0x40) -#define BMI160_FIFO_WATERMARK_INT_EN_MASK UINT8_C(0x40) -#define BMI160_LOW_G_INT_EN_MASK UINT8_C(0x08) -#define BMI160_STEP_DETECT_EN_MASK UINT8_C(0x08) -#define BMI160_FLAT_INT_EN_MASK UINT8_C(0x80) -#define BMI160_DATA_RDY_INT_EN_MASK UINT8_C(0x10) - -/** PMU status Macros */ -#define BMI160_AUX_PMU_SUSPEND UINT8_C(0x00) -#define BMI160_AUX_PMU_NORMAL UINT8_C(0x01) -#define BMI160_AUX_PMU_LOW_POWER UINT8_C(0x02) - -#define BMI160_GYRO_PMU_SUSPEND UINT8_C(0x00) -#define BMI160_GYRO_PMU_NORMAL UINT8_C(0x01) -#define BMI160_GYRO_PMU_FSU UINT8_C(0x03) - -#define BMI160_ACCEL_PMU_SUSPEND UINT8_C(0x00) -#define BMI160_ACCEL_PMU_NORMAL UINT8_C(0x01) -#define BMI160_ACCEL_PMU_LOW_POWER UINT8_C(0x02) - -/** Mask definitions for INT_OUT_CTRL register */ -#define BMI160_INT1_EDGE_CTRL_MASK UINT8_C(0x01) -#define BMI160_INT1_OUTPUT_MODE_MASK UINT8_C(0x04) -#define BMI160_INT1_OUTPUT_TYPE_MASK UINT8_C(0x02) -#define BMI160_INT1_OUTPUT_EN_MASK UINT8_C(0x08) -#define BMI160_INT2_EDGE_CTRL_MASK UINT8_C(0x10) -#define BMI160_INT2_OUTPUT_MODE_MASK UINT8_C(0x40) -#define BMI160_INT2_OUTPUT_TYPE_MASK UINT8_C(0x20) -#define BMI160_INT2_OUTPUT_EN_MASK UINT8_C(0x80) - -/** Mask definitions for INT_LATCH register */ -#define BMI160_INT1_INPUT_EN_MASK UINT8_C(0x10) -#define BMI160_INT2_INPUT_EN_MASK UINT8_C(0x20) -#define BMI160_INT_LATCH_MASK UINT8_C(0x0F) - -/** Mask definitions for INT_MAP register */ -#define BMI160_INT1_LOW_G_MASK UINT8_C(0x01) -#define BMI160_INT1_HIGH_G_MASK UINT8_C(0x02) -#define BMI160_INT1_SLOPE_MASK UINT8_C(0x04) -#define BMI160_INT1_NO_MOTION_MASK UINT8_C(0x08) -#define BMI160_INT1_DOUBLE_TAP_MASK UINT8_C(0x10) -#define BMI160_INT1_SINGLE_TAP_MASK UINT8_C(0x20) -#define BMI160_INT1_FIFO_FULL_MASK UINT8_C(0x20) -#define BMI160_INT1_FIFO_WM_MASK UINT8_C(0x40) -#define BMI160_INT1_ORIENT_MASK UINT8_C(0x40) -#define BMI160_INT1_FLAT_MASK UINT8_C(0x80) -#define BMI160_INT1_DATA_READY_MASK UINT8_C(0x80) -#define BMI160_INT2_LOW_G_MASK UINT8_C(0x01) -#define BMI160_INT1_LOW_STEP_DETECT_MASK UINT8_C(0x01) -#define BMI160_INT2_LOW_STEP_DETECT_MASK UINT8_C(0x01) -#define BMI160_INT2_HIGH_G_MASK UINT8_C(0x02) -#define BMI160_INT2_FIFO_FULL_MASK UINT8_C(0x02) -#define BMI160_INT2_FIFO_WM_MASK UINT8_C(0x04) -#define BMI160_INT2_SLOPE_MASK UINT8_C(0x04) -#define BMI160_INT2_DATA_READY_MASK UINT8_C(0x08) -#define BMI160_INT2_NO_MOTION_MASK UINT8_C(0x08) -#define BMI160_INT2_DOUBLE_TAP_MASK UINT8_C(0x10) -#define BMI160_INT2_SINGLE_TAP_MASK UINT8_C(0x20) -#define BMI160_INT2_ORIENT_MASK UINT8_C(0x40) -#define BMI160_INT2_FLAT_MASK UINT8_C(0x80) - -/** Mask definitions for INT_DATA register */ -#define BMI160_TAP_SRC_INT_MASK UINT8_C(0x08) -#define BMI160_LOW_HIGH_SRC_INT_MASK UINT8_C(0x80) -#define BMI160_MOTION_SRC_INT_MASK UINT8_C(0x80) - -/** Mask definitions for INT_MOTION register */ -#define BMI160_SLOPE_INT_DUR_MASK UINT8_C(0x03) -#define BMI160_NO_MOTION_INT_DUR_MASK UINT8_C(0xFC) -#define BMI160_NO_MOTION_SEL_BIT_MASK UINT8_C(0x01) - -/** Mask definitions for INT_TAP register */ -#define BMI160_TAP_DUR_MASK UINT8_C(0x07) -#define BMI160_TAP_SHOCK_DUR_MASK UINT8_C(0x40) -#define BMI160_TAP_QUIET_DUR_MASK UINT8_C(0x80) -#define BMI160_TAP_THRES_MASK UINT8_C(0x1F) - -/** Mask definitions for INT_FLAT register */ -#define BMI160_FLAT_THRES_MASK UINT8_C(0x3F) -#define BMI160_FLAT_HOLD_TIME_MASK UINT8_C(0x30) -#define BMI160_FLAT_HYST_MASK UINT8_C(0x07) - -/** Mask definitions for INT_LOWHIGH register */ -#define BMI160_LOW_G_HYST_MASK UINT8_C(0x03) -#define BMI160_LOW_G_LOW_MODE_MASK UINT8_C(0x04) -#define BMI160_HIGH_G_HYST_MASK UINT8_C(0xC0) - -/** Mask definitions for INT_SIG_MOTION register */ -#define BMI160_SIG_MOTION_SEL_MASK UINT8_C(0x02) -#define BMI160_SIG_MOTION_SKIP_MASK UINT8_C(0x0C) -#define BMI160_SIG_MOTION_PROOF_MASK UINT8_C(0x30) - -/** Mask definitions for INT_ORIENT register */ -#define BMI160_ORIENT_MODE_MASK UINT8_C(0x03) -#define BMI160_ORIENT_BLOCK_MASK UINT8_C(0x0C) -#define BMI160_ORIENT_HYST_MASK UINT8_C(0xF0) -#define BMI160_ORIENT_THETA_MASK UINT8_C(0x3F) -#define BMI160_ORIENT_UD_ENABLE UINT8_C(0x40) -#define BMI160_AXES_EN_MASK UINT8_C(0x80) - -/** Mask definitions for FIFO_CONFIG register */ -#define BMI160_FIFO_GYRO UINT8_C(0x80) -#define BMI160_FIFO_ACCEL UINT8_C(0x40) -#define BMI160_FIFO_AUX UINT8_C(0x20) -#define BMI160_FIFO_TAG_INT1 UINT8_C(0x08) -#define BMI160_FIFO_TAG_INT2 UINT8_C(0x04) -#define BMI160_FIFO_TIME UINT8_C(0x02) -#define BMI160_FIFO_HEADER UINT8_C(0x10) -#define BMI160_FIFO_CONFIG_1_MASK UINT8_C(0xFE) - -/** Mask definitions for STEP_CONF register */ -#define BMI160_STEP_COUNT_EN_BIT_MASK UINT8_C(0x08) -#define BMI160_STEP_DETECT_MIN_THRES_MASK UINT8_C(0x18) -#define BMI160_STEP_DETECT_STEPTIME_MIN_MASK UINT8_C(0x07) -#define BMI160_STEP_MIN_BUF_MASK UINT8_C(0x07) - -/** Mask definition for FIFO Header Data Tag */ -#define BMI160_FIFO_TAG_INTR_MASK UINT8_C(0xFC) - -/** Fifo byte counter mask definitions */ -#define BMI160_FIFO_BYTE_COUNTER_MASK UINT8_C(0x07) - -/** Enable/disable bit value */ -#define BMI160_ENABLE UINT8_C(0x01) -#define BMI160_DISABLE UINT8_C(0x00) - -/** Latch Duration */ -#define BMI160_LATCH_DUR_NONE UINT8_C(0x00) -#define BMI160_LATCH_DUR_312_5_MICRO_SEC UINT8_C(0x01) -#define BMI160_LATCH_DUR_625_MICRO_SEC UINT8_C(0x02) -#define BMI160_LATCH_DUR_1_25_MILLI_SEC UINT8_C(0x03) -#define BMI160_LATCH_DUR_2_5_MILLI_SEC UINT8_C(0x04) -#define BMI160_LATCH_DUR_5_MILLI_SEC UINT8_C(0x05) -#define BMI160_LATCH_DUR_10_MILLI_SEC UINT8_C(0x06) -#define BMI160_LATCH_DUR_20_MILLI_SEC UINT8_C(0x07) -#define BMI160_LATCH_DUR_40_MILLI_SEC UINT8_C(0x08) -#define BMI160_LATCH_DUR_80_MILLI_SEC UINT8_C(0x09) -#define BMI160_LATCH_DUR_160_MILLI_SEC UINT8_C(0x0A) -#define BMI160_LATCH_DUR_320_MILLI_SEC UINT8_C(0x0B) -#define BMI160_LATCH_DUR_640_MILLI_SEC UINT8_C(0x0C) -#define BMI160_LATCH_DUR_1_28_SEC UINT8_C(0x0D) -#define BMI160_LATCH_DUR_2_56_SEC UINT8_C(0x0E) -#define BMI160_LATCHED UINT8_C(0x0F) - -/** BMI160 Register map */ -#define BMI160_CHIP_ID_ADDR UINT8_C(0x00) -#define BMI160_ERROR_REG_ADDR UINT8_C(0x02) -#define BMI160_PMU_STATUS_ADDR UINT8_C(0x03) -#define BMI160_AUX_DATA_ADDR UINT8_C(0x04) -#define BMI160_GYRO_DATA_ADDR UINT8_C(0x0C) -#define BMI160_ACCEL_DATA_ADDR UINT8_C(0x12) -#define BMI160_STATUS_ADDR UINT8_C(0x1B) -#define BMI160_INT_STATUS_ADDR UINT8_C(0x1C) -#define BMI160_FIFO_LENGTH_ADDR UINT8_C(0x22) -#define BMI160_FIFO_DATA_ADDR UINT8_C(0x24) -#define BMI160_ACCEL_CONFIG_ADDR UINT8_C(0x40) -#define BMI160_ACCEL_RANGE_ADDR UINT8_C(0x41) -#define BMI160_GYRO_CONFIG_ADDR UINT8_C(0x42) -#define BMI160_GYRO_RANGE_ADDR UINT8_C(0x43) -#define BMI160_AUX_ODR_ADDR UINT8_C(0x44) -#define BMI160_FIFO_DOWN_ADDR UINT8_C(0x45) -#define BMI160_FIFO_CONFIG_0_ADDR UINT8_C(0x46) -#define BMI160_FIFO_CONFIG_1_ADDR UINT8_C(0x47) -#define BMI160_AUX_IF_0_ADDR UINT8_C(0x4B) -#define BMI160_AUX_IF_1_ADDR UINT8_C(0x4C) -#define BMI160_AUX_IF_2_ADDR UINT8_C(0x4D) -#define BMI160_AUX_IF_3_ADDR UINT8_C(0x4E) -#define BMI160_AUX_IF_4_ADDR UINT8_C(0x4F) -#define BMI160_INT_ENABLE_0_ADDR UINT8_C(0x50) -#define BMI160_INT_ENABLE_1_ADDR UINT8_C(0x51) -#define BMI160_INT_ENABLE_2_ADDR UINT8_C(0x52) -#define BMI160_INT_OUT_CTRL_ADDR UINT8_C(0x53) -#define BMI160_INT_LATCH_ADDR UINT8_C(0x54) -#define BMI160_INT_MAP_0_ADDR UINT8_C(0x55) -#define BMI160_INT_MAP_1_ADDR UINT8_C(0x56) -#define BMI160_INT_MAP_2_ADDR UINT8_C(0x57) -#define BMI160_INT_DATA_0_ADDR UINT8_C(0x58) -#define BMI160_INT_DATA_1_ADDR UINT8_C(0x59) -#define BMI160_INT_LOWHIGH_0_ADDR UINT8_C(0x5A) -#define BMI160_INT_LOWHIGH_1_ADDR UINT8_C(0x5B) -#define BMI160_INT_LOWHIGH_2_ADDR UINT8_C(0x5C) -#define BMI160_INT_LOWHIGH_3_ADDR UINT8_C(0x5D) -#define BMI160_INT_LOWHIGH_4_ADDR UINT8_C(0x5E) -#define BMI160_INT_MOTION_0_ADDR UINT8_C(0x5F) -#define BMI160_INT_MOTION_1_ADDR UINT8_C(0x60) -#define BMI160_INT_MOTION_2_ADDR UINT8_C(0x61) -#define BMI160_INT_MOTION_3_ADDR UINT8_C(0x62) -#define BMI160_INT_TAP_0_ADDR UINT8_C(0x63) -#define BMI160_INT_TAP_1_ADDR UINT8_C(0x64) -#define BMI160_INT_ORIENT_0_ADDR UINT8_C(0x65) -#define BMI160_INT_ORIENT_1_ADDR UINT8_C(0x66) -#define BMI160_INT_FLAT_0_ADDR UINT8_C(0x67) -#define BMI160_INT_FLAT_1_ADDR UINT8_C(0x68) -#define BMI160_FOC_CONF_ADDR UINT8_C(0x69) -#define BMI160_CONF_ADDR UINT8_C(0x6A) - -#define BMI160_IF_CONF_ADDR UINT8_C(0x6B) -#define BMI160_SELF_TEST_ADDR UINT8_C(0x6D) -#define BMI160_OFFSET_ADDR UINT8_C(0x71) -#define BMI160_OFFSET_CONF_ADDR UINT8_C(0x77) -#define BMI160_INT_STEP_CNT_0_ADDR UINT8_C(0x78) -#define BMI160_INT_STEP_CONFIG_0_ADDR UINT8_C(0x7A) -#define BMI160_INT_STEP_CONFIG_1_ADDR UINT8_C(0x7B) -#define BMI160_COMMAND_REG_ADDR UINT8_C(0x7E) -#define BMI160_SPI_COMM_TEST_ADDR UINT8_C(0x7F) -#define BMI160_INTL_PULLUP_CONF_ADDR UINT8_C(0x85) - -/** Error code definitions */ -#define BMI160_OK INT8_C(0) -#define BMI160_E_NULL_PTR INT8_C(-1) -#define BMI160_E_COM_FAIL INT8_C(-2) -#define BMI160_E_DEV_NOT_FOUND INT8_C(-3) -#define BMI160_E_OUT_OF_RANGE INT8_C(-4) -#define BMI160_E_INVALID_INPUT INT8_C(-5) -#define BMI160_E_ACCEL_ODR_BW_INVALID INT8_C(-6) -#define BMI160_E_GYRO_ODR_BW_INVALID INT8_C(-7) -#define BMI160_E_LWP_PRE_FLTR_INT_INVALID INT8_C(-8) -#define BMI160_E_LWP_PRE_FLTR_INVALID INT8_C(-9) -#define BMI160_E_AUX_NOT_FOUND INT8_C(-10) -#define BMI160_E_FOC_FAILURE INT8_C(-11) -#define BMI160_E_READ_WRITE_LENGTH_INVALID INT8_C(-12) -#define BMI160_E_INVALID_CONFIG INT8_C(-13) - -/**\name API warning codes */ -#define BMI160_W_GYRO_SELF_TEST_FAIL INT8_C(1) -#define BMI160_W_ACCEl_SELF_TEST_FAIL INT8_C(2) - -/** BMI160 unique chip identifier */ -#define BMI160_CHIP_ID UINT8_C(0xD1) - -/** Soft reset command */ -#define BMI160_SOFT_RESET_CMD UINT8_C(0xb6) -#define BMI160_SOFT_RESET_DELAY_MS UINT8_C(1) - -/** Start FOC command */ -#define BMI160_START_FOC_CMD UINT8_C(0x03) - -/** NVM backup enabling command */ -#define BMI160_NVM_BACKUP_EN UINT8_C(0xA0) - -/* Delay in ms settings */ -#define BMI160_ACCEL_DELAY_MS UINT8_C(5) -#define BMI160_GYRO_DELAY_MS UINT8_C(80) -#define BMI160_ONE_MS_DELAY UINT8_C(1) -#define BMI160_AUX_COM_DELAY UINT8_C(10) -#define BMI160_GYRO_SELF_TEST_DELAY UINT8_C(20) -#define BMI160_ACCEL_SELF_TEST_DELAY UINT8_C(50) - -/** Self test configurations */ -#define BMI160_ACCEL_SELF_TEST_CONFIG UINT8_C(0x2C) -#define BMI160_ACCEL_SELF_TEST_POSITIVE_EN UINT8_C(0x0D) -#define BMI160_ACCEL_SELF_TEST_NEGATIVE_EN UINT8_C(0x09) -#define BMI160_ACCEL_SELF_TEST_LIMIT UINT16_C(8192) - -/** Power mode settings */ -/* Accel power mode */ -#define BMI160_ACCEL_NORMAL_MODE UINT8_C(0x11) -#define BMI160_ACCEL_LOWPOWER_MODE UINT8_C(0x12) -#define BMI160_ACCEL_SUSPEND_MODE UINT8_C(0x10) - -/* Gyro power mode */ -#define BMI160_GYRO_SUSPEND_MODE UINT8_C(0x14) -#define BMI160_GYRO_NORMAL_MODE UINT8_C(0x15) -#define BMI160_GYRO_FASTSTARTUP_MODE UINT8_C(0x17) - -/* Aux power mode */ -#define BMI160_AUX_SUSPEND_MODE UINT8_C(0x18) -#define BMI160_AUX_NORMAL_MODE UINT8_C(0x19) -#define BMI160_AUX_LOWPOWER_MODE UINT8_C(0x1A) - -/** Range settings */ -/* Accel Range */ -#define BMI160_ACCEL_RANGE_2G UINT8_C(0x03) -#define BMI160_ACCEL_RANGE_4G UINT8_C(0x05) -#define BMI160_ACCEL_RANGE_8G UINT8_C(0x08) -#define BMI160_ACCEL_RANGE_16G UINT8_C(0x0C) - -/* Gyro Range */ -#define BMI160_GYRO_RANGE_2000_DPS UINT8_C(0x00) -#define BMI160_GYRO_RANGE_1000_DPS UINT8_C(0x01) -#define BMI160_GYRO_RANGE_500_DPS UINT8_C(0x02) -#define BMI160_GYRO_RANGE_250_DPS UINT8_C(0x03) -#define BMI160_GYRO_RANGE_125_DPS UINT8_C(0x04) - -/** Bandwidth settings */ -/* Accel Bandwidth */ -#define BMI160_ACCEL_BW_OSR4_AVG1 UINT8_C(0x00) -#define BMI160_ACCEL_BW_OSR2_AVG2 UINT8_C(0x01) -#define BMI160_ACCEL_BW_NORMAL_AVG4 UINT8_C(0x02) -#define BMI160_ACCEL_BW_RES_AVG8 UINT8_C(0x03) -#define BMI160_ACCEL_BW_RES_AVG16 UINT8_C(0x04) -#define BMI160_ACCEL_BW_RES_AVG32 UINT8_C(0x05) -#define BMI160_ACCEL_BW_RES_AVG64 UINT8_C(0x06) -#define BMI160_ACCEL_BW_RES_AVG128 UINT8_C(0x07) - -#define BMI160_GYRO_BW_OSR4_MODE UINT8_C(0x00) -#define BMI160_GYRO_BW_OSR2_MODE UINT8_C(0x01) -#define BMI160_GYRO_BW_NORMAL_MODE UINT8_C(0x02) - -/* Output Data Rate settings */ -/* Accel Output data rate */ -#define BMI160_ACCEL_ODR_RESERVED UINT8_C(0x00) -#define BMI160_ACCEL_ODR_0_78HZ UINT8_C(0x01) -#define BMI160_ACCEL_ODR_1_56HZ UINT8_C(0x02) -#define BMI160_ACCEL_ODR_3_12HZ UINT8_C(0x03) -#define BMI160_ACCEL_ODR_6_25HZ UINT8_C(0x04) -#define BMI160_ACCEL_ODR_12_5HZ UINT8_C(0x05) -#define BMI160_ACCEL_ODR_25HZ UINT8_C(0x06) -#define BMI160_ACCEL_ODR_50HZ UINT8_C(0x07) -#define BMI160_ACCEL_ODR_100HZ UINT8_C(0x08) -#define BMI160_ACCEL_ODR_200HZ UINT8_C(0x09) -#define BMI160_ACCEL_ODR_400HZ UINT8_C(0x0A) -#define BMI160_ACCEL_ODR_800HZ UINT8_C(0x0B) -#define BMI160_ACCEL_ODR_1600HZ UINT8_C(0x0C) -#define BMI160_ACCEL_ODR_RESERVED0 UINT8_C(0x0D) -#define BMI160_ACCEL_ODR_RESERVED1 UINT8_C(0x0E) -#define BMI160_ACCEL_ODR_RESERVED2 UINT8_C(0x0F) - -/* Gyro Output data rate */ -#define BMI160_GYRO_ODR_RESERVED UINT8_C(0x00) -#define BMI160_GYRO_ODR_25HZ UINT8_C(0x06) -#define BMI160_GYRO_ODR_50HZ UINT8_C(0x07) -#define BMI160_GYRO_ODR_100HZ UINT8_C(0x08) -#define BMI160_GYRO_ODR_200HZ UINT8_C(0x09) -#define BMI160_GYRO_ODR_400HZ UINT8_C(0x0A) -#define BMI160_GYRO_ODR_800HZ UINT8_C(0x0B) -#define BMI160_GYRO_ODR_1600HZ UINT8_C(0x0C) -#define BMI160_GYRO_ODR_3200HZ UINT8_C(0x0D) - -/* Auxiliary sensor Output data rate */ -#define BMI160_AUX_ODR_RESERVED UINT8_C(0x00) -#define BMI160_AUX_ODR_0_78HZ UINT8_C(0x01) -#define BMI160_AUX_ODR_1_56HZ UINT8_C(0x02) -#define BMI160_AUX_ODR_3_12HZ UINT8_C(0x03) -#define BMI160_AUX_ODR_6_25HZ UINT8_C(0x04) -#define BMI160_AUX_ODR_12_5HZ UINT8_C(0x05) -#define BMI160_AUX_ODR_25HZ UINT8_C(0x06) -#define BMI160_AUX_ODR_50HZ UINT8_C(0x07) -#define BMI160_AUX_ODR_100HZ UINT8_C(0x08) -#define BMI160_AUX_ODR_200HZ UINT8_C(0x09) -#define BMI160_AUX_ODR_400HZ UINT8_C(0x0A) -#define BMI160_AUX_ODR_800HZ UINT8_C(0x0B) - -/** FIFO_CONFIG Definitions */ -#define BMI160_FIFO_TIME_ENABLE UINT8_C(0x02) -#define BMI160_FIFO_TAG_INT2_ENABLE UINT8_C(0x04) -#define BMI160_FIFO_TAG_INT1_ENABLE UINT8_C(0x08) -#define BMI160_FIFO_HEAD_ENABLE UINT8_C(0x10) -#define BMI160_FIFO_M_ENABLE UINT8_C(0x20) -#define BMI160_FIFO_A_ENABLE UINT8_C(0x40) -#define BMI160_FIFO_M_A_ENABLE UINT8_C(0x60) -#define BMI160_FIFO_G_ENABLE UINT8_C(0x80) -#define BMI160_FIFO_M_G_ENABLE UINT8_C(0xA0) -#define BMI160_FIFO_G_A_ENABLE UINT8_C(0xC0) -#define BMI160_FIFO_M_G_A_ENABLE UINT8_C(0xE0) - -/* Macro to specify the number of bytes over-read from the - * FIFO in order to get the sensor time at the end of FIFO */ -#ifndef BMI160_FIFO_BYTES_OVERREAD -#define BMI160_FIFO_BYTES_OVERREAD UINT8_C(25) -#endif - -/* Accel, gyro and aux. sensor length and also their combined - * length definitions in FIFO */ -#define BMI160_FIFO_G_LENGTH UINT8_C(6) -#define BMI160_FIFO_A_LENGTH UINT8_C(6) -#define BMI160_FIFO_M_LENGTH UINT8_C(8) -#define BMI160_FIFO_GA_LENGTH UINT8_C(12) -#define BMI160_FIFO_MA_LENGTH UINT8_C(14) -#define BMI160_FIFO_MG_LENGTH UINT8_C(14) -#define BMI160_FIFO_MGA_LENGTH UINT8_C(20) - -/** FIFO Header Data definitions */ -#define BMI160_FIFO_HEAD_SKIP_FRAME UINT8_C(0x40) -#define BMI160_FIFO_HEAD_SENSOR_TIME UINT8_C(0x44) -#define BMI160_FIFO_HEAD_INPUT_CONFIG UINT8_C(0x48) -#define BMI160_FIFO_HEAD_OVER_READ UINT8_C(0x80) -#define BMI160_FIFO_HEAD_A UINT8_C(0x84) -#define BMI160_FIFO_HEAD_G UINT8_C(0x88) -#define BMI160_FIFO_HEAD_G_A UINT8_C(0x8C) -#define BMI160_FIFO_HEAD_M UINT8_C(0x90) -#define BMI160_FIFO_HEAD_M_A UINT8_C(0x94) -#define BMI160_FIFO_HEAD_M_G UINT8_C(0x98) -#define BMI160_FIFO_HEAD_M_G_A UINT8_C(0x9C) - -/** FIFO sensor time length definitions */ -#define BMI160_SENSOR_TIME_LENGTH UINT8_C(3) - -/** FIFO DOWN selection */ -/* Accel fifo down-sampling values*/ -#define BMI160_ACCEL_FIFO_DOWN_ZERO UINT8_C(0x00) -#define BMI160_ACCEL_FIFO_DOWN_ONE UINT8_C(0x10) -#define BMI160_ACCEL_FIFO_DOWN_TWO UINT8_C(0x20) -#define BMI160_ACCEL_FIFO_DOWN_THREE UINT8_C(0x30) -#define BMI160_ACCEL_FIFO_DOWN_FOUR UINT8_C(0x40) -#define BMI160_ACCEL_FIFO_DOWN_FIVE UINT8_C(0x50) -#define BMI160_ACCEL_FIFO_DOWN_SIX UINT8_C(0x60) -#define BMI160_ACCEL_FIFO_DOWN_SEVEN UINT8_C(0x70) - -/* Gyro fifo down-smapling values*/ -#define BMI160_GYRO_FIFO_DOWN_ZERO UINT8_C(0x00) -#define BMI160_GYRO_FIFO_DOWN_ONE UINT8_C(0x01) -#define BMI160_GYRO_FIFO_DOWN_TWO UINT8_C(0x02) -#define BMI160_GYRO_FIFO_DOWN_THREE UINT8_C(0x03) -#define BMI160_GYRO_FIFO_DOWN_FOUR UINT8_C(0x04) -#define BMI160_GYRO_FIFO_DOWN_FIVE UINT8_C(0x05) -#define BMI160_GYRO_FIFO_DOWN_SIX UINT8_C(0x06) -#define BMI160_GYRO_FIFO_DOWN_SEVEN UINT8_C(0x07) - -/* Accel Fifo filter enable*/ -#define BMI160_ACCEL_FIFO_FILT_EN UINT8_C(0x80) - -/* Gyro Fifo filter enable*/ -#define BMI160_GYRO_FIFO_FILT_EN UINT8_C(0x08) - -/** Definitions to check validity of FIFO frames */ -#define FIFO_CONFIG_MSB_CHECK UINT8_C(0x80) -#define FIFO_CONFIG_LSB_CHECK UINT8_C(0x00) - -/*! BMI160 accel FOC configurations */ -#define BMI160_FOC_ACCEL_DISABLED UINT8_C(0x00) -#define BMI160_FOC_ACCEL_POSITIVE_G UINT8_C(0x01) -#define BMI160_FOC_ACCEL_NEGATIVE_G UINT8_C(0x02) -#define BMI160_FOC_ACCEL_0G UINT8_C(0x03) - -/** Array Parameter DefinItions */ -#define BMI160_SENSOR_TIME_LSB_BYTE UINT8_C(0) -#define BMI160_SENSOR_TIME_XLSB_BYTE UINT8_C(1) -#define BMI160_SENSOR_TIME_MSB_BYTE UINT8_C(2) - -/** Interface settings */ -#define BMI160_SPI_INTF UINT8_C(1) -#define BMI160_I2C_INTF UINT8_C(0) -#define BMI160_SPI_RD_MASK UINT8_C(0x80) -#define BMI160_SPI_WR_MASK UINT8_C(0x7F) - -/* Sensor & time select definition*/ -#define BMI160_ACCEL_SEL UINT8_C(0x01) -#define BMI160_GYRO_SEL UINT8_C(0x02) -#define BMI160_TIME_SEL UINT8_C(0x04) - -/* Sensor select mask*/ -#define BMI160_SEN_SEL_MASK UINT8_C(0x07) - -/* Error code mask */ -#define BMI160_ERR_REG_MASK UINT8_C(0x0F) - -/* BMI160 I2C address */ -#define BMI160_I2C_ADDR UINT8_C(0x68) - -/* BMI160 secondary IF address */ -#define BMI160_AUX_BMM150_I2C_ADDR UINT8_C(0x10) - -/** BMI160 Length definitions */ -#define BMI160_ONE UINT8_C(1) -#define BMI160_TWO UINT8_C(2) -#define BMI160_THREE UINT8_C(3) -#define BMI160_FOUR UINT8_C(4) -#define BMI160_FIVE UINT8_C(5) - -/** BMI160 fifo level Margin */ -#define BMI160_FIFO_LEVEL_MARGIN UINT8_C(16) - -/** BMI160 fifo flush Command */ -#define BMI160_FIFO_FLUSH_VALUE UINT8_C(0xB0) - -/** BMI160 offset values for xyz axes of accel */ -#define BMI160_ACCEL_MIN_OFFSET INT8_C(-128) -#define BMI160_ACCEL_MAX_OFFSET INT8_C(127) - -/** BMI160 offset values for xyz axes of gyro */ -#define BMI160_GYRO_MIN_OFFSET INT16_C(-512) -#define BMI160_GYRO_MAX_OFFSET INT16_C(511) - -/** BMI160 fifo full interrupt position and mask */ -#define BMI160_FIFO_FULL_INT_POS UINT8_C(5) -#define BMI160_FIFO_FULL_INT_MSK UINT8_C(0x20) -#define BMI160_FIFO_WTM_INT_POS UINT8_C(6) -#define BMI160_FIFO_WTM_INT_MSK UINT8_C(0x40) - -#define BMI160_FIFO_FULL_INT_PIN1_POS UINT8_C(5) -#define BMI160_FIFO_FULL_INT_PIN1_MSK UINT8_C(0x20) -#define BMI160_FIFO_FULL_INT_PIN2_POS UINT8_C(1) -#define BMI160_FIFO_FULL_INT_PIN2_MSK UINT8_C(0x02) - -#define BMI160_FIFO_WTM_INT_PIN1_POS UINT8_C(6) -#define BMI160_FIFO_WTM_INT_PIN1_MSK UINT8_C(0x40) -#define BMI160_FIFO_WTM_INT_PIN2_POS UINT8_C(2) -#define BMI160_FIFO_WTM_INT_PIN2_MSK UINT8_C(0x04) - -#define BMI160_MANUAL_MODE_EN_POS UINT8_C(7) -#define BMI160_MANUAL_MODE_EN_MSK UINT8_C(0x80) -#define BMI160_AUX_READ_BURST_POS UINT8_C(0) -#define BMI160_AUX_READ_BURST_MSK UINT8_C(0x03) - -#define BMI160_GYRO_SELF_TEST_POS UINT8_C(4) -#define BMI160_GYRO_SELF_TEST_MSK UINT8_C(0x10) -#define BMI160_GYRO_SELF_TEST_STATUS_POS UINT8_C(1) -#define BMI160_GYRO_SELF_TEST_STATUS_MSK UINT8_C(0x02) - -#define BMI160_GYRO_FOC_EN_POS UINT8_C(6) -#define BMI160_GYRO_FOC_EN_MSK UINT8_C(0x40) - -#define BMI160_ACCEL_FOC_X_CONF_POS UINT8_C(4) -#define BMI160_ACCEL_FOC_X_CONF_MSK UINT8_C(0x30) - -#define BMI160_ACCEL_FOC_Y_CONF_POS UINT8_C(2) -#define BMI160_ACCEL_FOC_Y_CONF_MSK UINT8_C(0x0C) - -#define BMI160_ACCEL_FOC_Z_CONF_MSK UINT8_C(0x03) - -#define BMI160_FOC_STATUS_POS UINT8_C(3) -#define BMI160_FOC_STATUS_MSK UINT8_C(0x08) - -#define BMI160_GYRO_OFFSET_X_MSK UINT8_C(0x03) - -#define BMI160_GYRO_OFFSET_Y_POS UINT8_C(2) -#define BMI160_GYRO_OFFSET_Y_MSK UINT8_C(0x0C) - -#define BMI160_GYRO_OFFSET_Z_POS UINT8_C(4) -#define BMI160_GYRO_OFFSET_Z_MSK UINT8_C(0x30) - -#define BMI160_GYRO_OFFSET_EN_POS UINT8_C(7) -#define BMI160_GYRO_OFFSET_EN_MSK UINT8_C(0x80) - -#define BMI160_ACCEL_OFFSET_EN_POS UINT8_C(6) -#define BMI160_ACCEL_OFFSET_EN_MSK UINT8_C(0x40) - -#define BMI160_GYRO_OFFSET_POS UINT16_C(8) -#define BMI160_GYRO_OFFSET_MSK UINT16_C(0x0300) - -#define BMI160_NVM_UPDATE_POS UINT8_C(1) -#define BMI160_NVM_UPDATE_MSK UINT8_C(0x02) - -#define BMI160_NVM_STATUS_POS UINT8_C(4) -#define BMI160_NVM_STATUS_MSK UINT8_C(0x10) - -#define BMI160_MAG_POWER_MODE_MSK UINT8_C(0x03) - -#define BMI160_ACCEL_POWER_MODE_MSK UINT8_C(0x30) -#define BMI160_ACCEL_POWER_MODE_POS UINT8_C(4) - -#define BMI160_GYRO_POWER_MODE_MSK UINT8_C(0x0C) -#define BMI160_GYRO_POWER_MODE_POS UINT8_C(2) - -/* BIT SLICE GET AND SET FUNCTIONS */ -#define BMI160_GET_BITS(regvar, bitname) ((regvar & bitname##_MSK) >> bitname##_POS) -#define BMI160_SET_BITS(regvar, bitname, val) \ - ((regvar & ~bitname##_MSK) | ((val << bitname##_POS) & bitname##_MSK)) - -#define BMI160_SET_BITS_POS_0(reg_data, bitname, data) \ - ((reg_data & ~(bitname##_MSK)) | (data & bitname##_MSK)) - -#define BMI160_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) - -/**\name UTILITY MACROS */ -#define BMI160_SET_LOW_BYTE UINT16_C(0x00FF) -#define BMI160_SET_HIGH_BYTE UINT16_C(0xFF00) - -#define BMI160_GET_LSB(var) (uint8_t)(var & BMI160_SET_LOW_BYTE) -#define BMI160_GET_MSB(var) (uint8_t)((var & BMI160_SET_HIGH_BYTE) >> 8) - -/*****************************************************************************/ -/* type definitions */ - -/*! - * @brief Bus communication function pointer which should be mapped to - * the platform specific read functions of the user - */ -typedef int8_t ( - *bmi160_read_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len); - -/*! - * @brief Bus communication function pointer which should be mapped to - * the platform specific write functions of the user - */ -typedef int8_t ( - *bmi160_write_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t* read_data, uint16_t len); -typedef void (*bmi160_delay_fptr_t)(uint32_t period); - -/*************************** Data structures *********************************/ - -/*! - * @brief bmi160 interrupt status selection enum. - */ -enum bmi160_int_status_sel { - BMI160_INT_STATUS_0 = 1, - BMI160_INT_STATUS_1 = 2, - BMI160_INT_STATUS_2 = 4, - BMI160_INT_STATUS_3 = 8, - BMI160_INT_STATUS_ALL = 15 -}; - -/*! - * @brief bmi160 interrupt status bits structure - */ -struct bmi160_int_status_bits { -#ifdef LITTLE_ENDIAN - - uint32_t step : 1; - uint32_t sigmot : 1; - uint32_t anym : 1; - - /* pmu trigger will be handled later */ - uint32_t pmu_trigger_reserved : 1; - uint32_t d_tap : 1; - uint32_t s_tap : 1; - uint32_t orient : 1; - uint32_t flat_int : 1; - uint32_t reserved : 2; - uint32_t high_g : 1; - uint32_t low_g : 1; - uint32_t drdy : 1; - uint32_t ffull : 1; - uint32_t fwm : 1; - uint32_t nomo : 1; - uint32_t anym_first_x : 1; - uint32_t anym_first_y : 1; - uint32_t anym_first_z : 1; - uint32_t anym_sign : 1; - uint32_t tap_first_x : 1; - uint32_t tap_first_y : 1; - uint32_t tap_first_z : 1; - uint32_t tap_sign : 1; - uint32_t high_first_x : 1; - uint32_t high_first_y : 1; - uint32_t high_first_z : 1; - uint32_t high_sign : 1; - uint32_t orient_1_0 : 2; - uint32_t orient_2 : 1; - uint32_t flat : 1; -#else - uint32_t high_first_x : 1; - uint32_t high_first_y : 1; - uint32_t high_first_z : 1; - uint32_t high_sign : 1; - uint32_t orient_1_0 : 2; - uint32_t orient_2 : 1; - uint32_t flat : 1; - uint32_t anym_first_x : 1; - uint32_t anym_first_y : 1; - uint32_t anym_first_z : 1; - uint32_t anym_sign : 1; - uint32_t tap_first_x : 1; - uint32_t tap_first_y : 1; - uint32_t tap_first_z : 1; - uint32_t tap_sign : 1; - uint32_t reserved : 2; - uint32_t high_g : 1; - uint32_t low_g : 1; - uint32_t drdy : 1; - uint32_t ffull : 1; - uint32_t fwm : 1; - uint32_t nomo : 1; - uint32_t step : 1; - uint32_t sigmot : 1; - uint32_t anym : 1; - - /* pmu trigger will be handled later */ - uint32_t pmu_trigger_reserved : 1; - uint32_t d_tap : 1; - uint32_t s_tap : 1; - uint32_t orient : 1; - uint32_t flat_int : 1; -#endif -}; - -/*! - * @brief bmi160 interrupt status structure - */ -union bmi160_int_status { - uint8_t data[4]; - struct bmi160_int_status_bits bit; -}; - -/*! - * @brief bmi160 sensor data structure which comprises of accel data - */ -struct bmi160_sensor_data { - /*! X-axis sensor data */ - int16_t x; - - /*! Y-axis sensor data */ - int16_t y; - - /*! Z-axis sensor data */ - int16_t z; - - /*! sensor time */ - uint32_t sensortime; -}; - -/*! - * @brief bmi160 aux data structure which comprises of 8 bytes of accel data - */ -struct bmi160_aux_data { - /*! Auxiliary data */ - uint8_t data[8]; -}; - -/*! - * @brief bmi160 FOC configuration structure - */ -struct bmi160_foc_conf { - /*! Enabling FOC in gyro - * Assignable macros : - * - BMI160_ENABLE - * - BMI160_DISABLE - */ - uint8_t foc_gyr_en; - - /*! Accel FOC configurations - * Assignable macros : - * - BMI160_FOC_ACCEL_DISABLED - * - BMI160_FOC_ACCEL_POSITIVE_G - * - BMI160_FOC_ACCEL_NEGATIVE_G - * - BMI160_FOC_ACCEL_0G - */ - uint8_t foc_acc_x; - uint8_t foc_acc_y; - uint8_t foc_acc_z; - - /*! Enabling offset compensation for accel in data registers - * Assignable macros : - * - BMI160_ENABLE - * - BMI160_DISABLE - */ - uint8_t acc_off_en; - - /*! Enabling offset compensation for gyro in data registers - * Assignable macros : - * - BMI160_ENABLE - * - BMI160_DISABLE - */ - uint8_t gyro_off_en; -}; - -/*! - * @brief bmi160 accel gyro offsets - */ -struct bmi160_offsets { - /*! Accel offset for x axis */ - int8_t off_acc_x; - - /*! Accel offset for y axis */ - int8_t off_acc_y; - - /*! Accel offset for z axis */ - int8_t off_acc_z; - - /*! Gyro offset for x axis */ - int16_t off_gyro_x; - - /*! Gyro offset for y axis */ - int16_t off_gyro_y; - - /*! Gyro offset for z axis */ - int16_t off_gyro_z; -}; - -/*! - * @brief FIFO aux. sensor data structure - */ -struct bmi160_aux_fifo_data { - /*! The value of aux. sensor x LSB data */ - uint8_t aux_x_lsb; - - /*! The value of aux. sensor x MSB data */ - uint8_t aux_x_msb; - - /*! The value of aux. sensor y LSB data */ - uint8_t aux_y_lsb; - - /*! The value of aux. sensor y MSB data */ - uint8_t aux_y_msb; - - /*! The value of aux. sensor z LSB data */ - uint8_t aux_z_lsb; - - /*! The value of aux. sensor z MSB data */ - uint8_t aux_z_msb; - - /*! The value of aux. sensor r for BMM150 LSB data */ - uint8_t aux_r_y2_lsb; - - /*! The value of aux. sensor r for BMM150 MSB data */ - uint8_t aux_r_y2_msb; -}; - -/*! - * @brief bmi160 sensor select structure - */ -enum bmi160_select_sensor { BMI160_ACCEL_ONLY = 1, BMI160_GYRO_ONLY, BMI160_BOTH_ACCEL_AND_GYRO }; - -/*! - * @brief bmi160 sensor step detector mode structure - */ -enum bmi160_step_detect_mode { - BMI160_STEP_DETECT_NORMAL, - BMI160_STEP_DETECT_SENSITIVE, - BMI160_STEP_DETECT_ROBUST, - - /*! Non recommended User defined setting */ - BMI160_STEP_DETECT_USER_DEFINE -}; - -/*! - * @brief enum for auxiliary burst read selection - */ -enum bmi160_aux_read_len { - BMI160_AUX_READ_LEN_0, - BMI160_AUX_READ_LEN_1, - BMI160_AUX_READ_LEN_2, - BMI160_AUX_READ_LEN_3 -}; - -/*! - * @brief bmi160 sensor configuration structure - */ -struct bmi160_cfg { - /*! power mode */ - uint8_t power; - - /*! output data rate */ - uint8_t odr; - - /*! range */ - uint8_t range; - - /*! bandwidth */ - uint8_t bw; -}; - -/*! - * @brief Aux sensor configuration structure - */ -struct bmi160_aux_cfg { - /*! Aux sensor, 1 - enable 0 - disable */ - uint8_t aux_sensor_enable : 1; - - /*! Aux manual/auto mode status */ - uint8_t manual_enable : 1; - - /*! Aux read burst length */ - uint8_t aux_rd_burst_len : 2; - - /*! output data rate */ - uint8_t aux_odr : 4; - - /*! i2c addr of auxiliary sensor */ - uint8_t aux_i2c_addr; -}; - -/*! - * @brief bmi160 interrupt channel selection structure - */ -enum bmi160_int_channel { - /*! Un-map both channels */ - BMI160_INT_CHANNEL_NONE, - - /*! interrupt Channel 1 */ - BMI160_INT_CHANNEL_1, - - /*! interrupt Channel 2 */ - BMI160_INT_CHANNEL_2, - - /*! Map both channels */ - BMI160_INT_CHANNEL_BOTH -}; -enum bmi160_int_types { - /*! Slope/Any-motion interrupt */ - BMI160_ACC_ANY_MOTION_INT, - - /*! Significant motion interrupt */ - BMI160_ACC_SIG_MOTION_INT, - - /*! Step detector interrupt */ - BMI160_STEP_DETECT_INT, - - /*! double tap interrupt */ - BMI160_ACC_DOUBLE_TAP_INT, - - /*! single tap interrupt */ - BMI160_ACC_SINGLE_TAP_INT, - - /*! orientation interrupt */ - BMI160_ACC_ORIENT_INT, - - /*! flat interrupt */ - BMI160_ACC_FLAT_INT, - - /*! high-g interrupt */ - BMI160_ACC_HIGH_G_INT, - - /*! low-g interrupt */ - BMI160_ACC_LOW_G_INT, - - /*! slow/no-motion interrupt */ - BMI160_ACC_SLOW_NO_MOTION_INT, - - /*! data ready interrupt */ - BMI160_ACC_GYRO_DATA_RDY_INT, - - /*! fifo full interrupt */ - BMI160_ACC_GYRO_FIFO_FULL_INT, - - /*! fifo watermark interrupt */ - BMI160_ACC_GYRO_FIFO_WATERMARK_INT, - - /*! fifo tagging feature support */ - BMI160_FIFO_TAG_INT_PIN -}; - -/*! - * @brief bmi160 active state of any & sig motion interrupt. - */ -enum bmi160_any_sig_motion_active_interrupt_state { - /*! Both any & sig motion are disabled */ - BMI160_BOTH_ANY_SIG_MOTION_DISABLED = -1, - - /*! Any-motion selected */ - BMI160_ANY_MOTION_ENABLED, - - /*! Sig-motion selected */ - BMI160_SIG_MOTION_ENABLED -}; -struct bmi160_acc_tap_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! tap threshold */ - uint16_t tap_thr : 5; - - /*! tap shock */ - uint16_t tap_shock : 1; - - /*! tap quiet */ - uint16_t tap_quiet : 1; - - /*! tap duration */ - uint16_t tap_dur : 3; - - /*! data source 0- filter & 1 pre-filter*/ - uint16_t tap_data_src : 1; - - /*! tap enable, 1 - enable, 0 - disable */ - uint16_t tap_en : 1; -#else - - /*! tap enable, 1 - enable, 0 - disable */ - uint16_t tap_en : 1; - - /*! data source 0- filter & 1 pre-filter*/ - uint16_t tap_data_src : 1; - - /*! tap duration */ - uint16_t tap_dur : 3; - - /*! tap quiet */ - uint16_t tap_quiet : 1; - - /*! tap shock */ - uint16_t tap_shock : 1; - - /*! tap threshold */ - uint16_t tap_thr : 5; -#endif -}; -struct bmi160_acc_any_mot_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! 1 any-motion enable, 0 - any-motion disable */ - uint8_t anymotion_en : 1; - - /*! slope interrupt x, 1 - enable, 0 - disable */ - uint8_t anymotion_x : 1; - - /*! slope interrupt y, 1 - enable, 0 - disable */ - uint8_t anymotion_y : 1; - - /*! slope interrupt z, 1 - enable, 0 - disable */ - uint8_t anymotion_z : 1; - - /*! slope duration */ - uint8_t anymotion_dur : 2; - - /*! data source 0- filter & 1 pre-filter*/ - uint8_t anymotion_data_src : 1; - - /*! slope threshold */ - uint8_t anymotion_thr; -#else - - /*! slope threshold */ - uint8_t anymotion_thr; - - /*! data source 0- filter & 1 pre-filter*/ - uint8_t anymotion_data_src : 1; - - /*! slope duration */ - uint8_t anymotion_dur : 2; - - /*! slope interrupt z, 1 - enable, 0 - disable */ - uint8_t anymotion_z : 1; - - /*! slope interrupt y, 1 - enable, 0 - disable */ - uint8_t anymotion_y : 1; - - /*! slope interrupt x, 1 - enable, 0 - disable */ - uint8_t anymotion_x : 1; - - /*! 1 any-motion enable, 0 - any-motion disable */ - uint8_t anymotion_en : 1; -#endif -}; -struct bmi160_acc_sig_mot_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! skip time of sig-motion interrupt */ - uint8_t sig_mot_skip : 2; - - /*! proof time of sig-motion interrupt */ - uint8_t sig_mot_proof : 2; - - /*! data source 0- filter & 1 pre-filter*/ - uint8_t sig_data_src : 1; - - /*! 1 - enable sig, 0 - disable sig & enable anymotion */ - uint8_t sig_en : 1; - - /*! sig-motion threshold */ - uint8_t sig_mot_thres; -#else - - /*! sig-motion threshold */ - uint8_t sig_mot_thres; - - /*! 1 - enable sig, 0 - disable sig & enable anymotion */ - uint8_t sig_en : 1; - - /*! data source 0- filter & 1 pre-filter*/ - uint8_t sig_data_src : 1; - - /*! proof time of sig-motion interrupt */ - uint8_t sig_mot_proof : 2; - - /*! skip time of sig-motion interrupt */ - uint8_t sig_mot_skip : 2; -#endif -}; -struct bmi160_acc_step_detect_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! 1- step detector enable, 0- step detector disable */ - uint16_t step_detector_en : 1; - - /*! minimum threshold */ - uint16_t min_threshold : 2; - - /*! minimal detectable step time */ - uint16_t steptime_min : 3; - - /*! enable step counter mode setting */ - uint16_t step_detector_mode : 2; - - /*! minimum step buffer size*/ - uint16_t step_min_buf : 3; -#else - - /*! minimum step buffer size*/ - uint16_t step_min_buf : 3; - - /*! enable step counter mode setting */ - uint16_t step_detector_mode : 2; - - /*! minimal detectable step time */ - uint16_t steptime_min : 3; - - /*! minimum threshold */ - uint16_t min_threshold : 2; - - /*! 1- step detector enable, 0- step detector disable */ - uint16_t step_detector_en : 1; -#endif -}; -struct bmi160_acc_no_motion_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! no motion interrupt x */ - uint16_t no_motion_x : 1; - - /*! no motion interrupt y */ - uint16_t no_motion_y : 1; - - /*! no motion interrupt z */ - uint16_t no_motion_z : 1; - - /*! no motion duration */ - uint16_t no_motion_dur : 6; - - /*! no motion sel , 1 - enable no-motion ,0- enable slow-motion */ - uint16_t no_motion_sel : 1; - - /*! data source 0- filter & 1 pre-filter*/ - uint16_t no_motion_src : 1; - - /*! no motion threshold */ - uint8_t no_motion_thres; -#else - - /*! no motion threshold */ - uint8_t no_motion_thres; - - /*! data source 0- filter & 1 pre-filter*/ - uint16_t no_motion_src : 1; - - /*! no motion sel , 1 - enable no-motion ,0- enable slow-motion */ - uint16_t no_motion_sel : 1; - - /*! no motion duration */ - uint16_t no_motion_dur : 6; - - /* no motion interrupt z */ - uint16_t no_motion_z : 1; - - /*! no motion interrupt y */ - uint16_t no_motion_y : 1; - - /*! no motion interrupt x */ - uint16_t no_motion_x : 1; -#endif -}; -struct bmi160_acc_orient_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! thresholds for switching between the different orientations */ - uint16_t orient_mode : 2; - - /*! blocking_mode */ - uint16_t orient_blocking : 2; - - /*! Orientation interrupt hysteresis */ - uint16_t orient_hyst : 4; - - /*! Orientation interrupt theta */ - uint16_t orient_theta : 6; - - /*! Enable/disable Orientation interrupt */ - uint16_t orient_ud_en : 1; - - /*! exchange x- and z-axis in algorithm ,0 - z, 1 - x */ - uint16_t axes_ex : 1; - - /*! 1 - orient enable, 0 - orient disable */ - uint8_t orient_en : 1; -#else - - /*! 1 - orient enable, 0 - orient disable */ - uint8_t orient_en : 1; - - /*! exchange x- and z-axis in algorithm ,0 - z, 1 - x */ - uint16_t axes_ex : 1; - - /*! Enable/disable Orientation interrupt */ - uint16_t orient_ud_en : 1; - - /*! Orientation interrupt theta */ - uint16_t orient_theta : 6; - - /*! Orientation interrupt hysteresis */ - uint16_t orient_hyst : 4; - - /*! blocking_mode */ - uint16_t orient_blocking : 2; - - /*! thresholds for switching between the different orientations */ - uint16_t orient_mode : 2; -#endif -}; -struct bmi160_acc_flat_detect_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! flat threshold */ - uint16_t flat_theta : 6; - - /*! flat interrupt hysteresis */ - uint16_t flat_hy : 3; - - /*! delay time for which the flat value must remain stable for the - * flat interrupt to be generated */ - uint16_t flat_hold_time : 2; - - /*! 1 - flat enable, 0 - flat disable */ - uint16_t flat_en : 1; -#else - - /*! 1 - flat enable, 0 - flat disable */ - uint16_t flat_en : 1; - - /*! delay time for which the flat value must remain stable for the - * flat interrupt to be generated */ - uint16_t flat_hold_time : 2; - - /*! flat interrupt hysteresis */ - uint16_t flat_hy : 3; - - /*! flat threshold */ - uint16_t flat_theta : 6; -#endif -}; -struct bmi160_acc_low_g_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! low-g interrupt trigger delay */ - uint8_t low_dur; - - /*! low-g interrupt trigger threshold */ - uint8_t low_thres; - - /*! hysteresis of low-g interrupt */ - uint8_t low_hyst : 2; - - /*! 0 - single-axis mode ,1 - axis-summing mode */ - uint8_t low_mode : 1; - - /*! data source 0- filter & 1 pre-filter */ - uint8_t low_data_src : 1; - - /*! 1 - enable low-g, 0 - disable low-g */ - uint8_t low_en : 1; -#else - - /*! 1 - enable low-g, 0 - disable low-g */ - uint8_t low_en : 1; - - /*! data source 0- filter & 1 pre-filter */ - uint8_t low_data_src : 1; - - /*! 0 - single-axis mode ,1 - axis-summing mode */ - uint8_t low_mode : 1; - - /*! hysteresis of low-g interrupt */ - uint8_t low_hyst : 2; - - /*! low-g interrupt trigger threshold */ - uint8_t low_thres; - - /*! low-g interrupt trigger delay */ - uint8_t low_dur; -#endif -}; -struct bmi160_acc_high_g_int_cfg { -#ifdef LITTLE_ENDIAN - - /*! High-g interrupt x, 1 - enable, 0 - disable */ - uint8_t high_g_x : 1; - - /*! High-g interrupt y, 1 - enable, 0 - disable */ - uint8_t high_g_y : 1; - - /*! High-g interrupt z, 1 - enable, 0 - disable */ - uint8_t high_g_z : 1; - - /*! High-g hysteresis */ - uint8_t high_hy : 2; - - /*! data source 0- filter & 1 pre-filter */ - uint8_t high_data_src : 1; - - /*! High-g threshold */ - uint8_t high_thres; - - /*! High-g duration */ - uint8_t high_dur; -#else - - /*! High-g duration */ - uint8_t high_dur; - - /*! High-g threshold */ - uint8_t high_thres; - - /*! data source 0- filter & 1 pre-filter */ - uint8_t high_data_src : 1; - - /*! High-g hysteresis */ - uint8_t high_hy : 2; - - /*! High-g interrupt z, 1 - enable, 0 - disable */ - uint8_t high_g_z : 1; - - /*! High-g interrupt y, 1 - enable, 0 - disable */ - uint8_t high_g_y : 1; - - /*! High-g interrupt x, 1 - enable, 0 - disable */ - uint8_t high_g_x : 1; -#endif -}; -struct bmi160_int_pin_settg { -#ifdef LITTLE_ENDIAN - - /*! To enable either INT1 or INT2 pin as output. - * 0- output disabled ,1- output enabled */ - uint16_t output_en : 1; - - /*! 0 - push-pull 1- open drain,only valid if output_en is set 1 */ - uint16_t output_mode : 1; - - /*! 0 - active low , 1 - active high level. - * if output_en is 1,this applies to interrupts,else PMU_trigger */ - uint16_t output_type : 1; - - /*! 0 - level trigger , 1 - edge trigger */ - uint16_t edge_ctrl : 1; - - /*! To enable either INT1 or INT2 pin as input. - * 0 - input disabled ,1 - input enabled */ - uint16_t input_en : 1; - - /*! latch duration*/ - uint16_t latch_dur : 4; -#else - - /*! latch duration*/ - uint16_t latch_dur : 4; - - /*! Latched,non-latched or temporary interrupt modes */ - uint16_t input_en : 1; - - /*! 1 - edge trigger, 0 - level trigger */ - uint16_t edge_ctrl : 1; - - /*! 0 - active low , 1 - active high level. - * if output_en is 1,this applies to interrupts,else PMU_trigger */ - uint16_t output_type : 1; - - /*! 0 - push-pull , 1 - open drain,only valid if output_en is set 1 */ - uint16_t output_mode : 1; - - /*! To enable either INT1 or INT2 pin as output. - * 0 - output disabled , 1 - output enabled */ - uint16_t output_en : 1; -#endif -}; -union bmi160_int_type_cfg { - /*! Tap interrupt structure */ - struct bmi160_acc_tap_int_cfg acc_tap_int; - - /*! Slope interrupt structure */ - struct bmi160_acc_any_mot_int_cfg acc_any_motion_int; - - /*! Significant motion interrupt structure */ - struct bmi160_acc_sig_mot_int_cfg acc_sig_motion_int; - - /*! Step detector interrupt structure */ - struct bmi160_acc_step_detect_int_cfg acc_step_detect_int; - - /*! No motion interrupt structure */ - struct bmi160_acc_no_motion_int_cfg acc_no_motion_int; - - /*! Orientation interrupt structure */ - struct bmi160_acc_orient_int_cfg acc_orient_int; - - /*! Flat interrupt structure */ - struct bmi160_acc_flat_detect_int_cfg acc_flat_int; - - /*! Low-g interrupt structure */ - struct bmi160_acc_low_g_int_cfg acc_low_g_int; - - /*! High-g interrupt structure */ - struct bmi160_acc_high_g_int_cfg acc_high_g_int; -}; -struct bmi160_int_settg { - /*! Interrupt channel */ - enum bmi160_int_channel int_channel; - - /*! Select Interrupt */ - enum bmi160_int_types int_type; - - /*! Structure configuring Interrupt pins */ - struct bmi160_int_pin_settg int_pin_settg; - - /*! Union configures required interrupt */ - union bmi160_int_type_cfg int_type_cfg; - - /*! FIFO FULL INT 1-enable, 0-disable */ - uint8_t fifo_full_int_en : 1; - - /*! FIFO WTM INT 1-enable, 0-disable */ - uint8_t fifo_wtm_int_en : 1; -}; - -/*! - * @brief This structure holds the information for usage of - * FIFO by the user. - */ -struct bmi160_fifo_frame { - /*! Data buffer of user defined length is to be mapped here */ - uint8_t* data; - - /*! While calling the API "bmi160_get_fifo_data" , length stores - * number of bytes in FIFO to be read (specified by user as input) - * and after execution of the API ,number of FIFO data bytes - * available is provided as an output to user - */ - uint16_t length; - - /*! FIFO time enable */ - uint8_t fifo_time_enable; - - /*! Enabling of the FIFO header to stream in header mode */ - uint8_t fifo_header_enable; - - /*! Streaming of the Accelerometer, Gyroscope - * sensor data or both in FIFO */ - uint8_t fifo_data_enable; - - /*! Will be equal to length when no more frames are there to parse */ - uint16_t accel_byte_start_idx; - - /*! Will be equal to length when no more frames are there to parse */ - uint16_t gyro_byte_start_idx; - - /*! Will be equal to length when no more frames are there to parse */ - uint16_t aux_byte_start_idx; - - /*! Value of FIFO sensor time time */ - uint32_t sensor_time; - - /*! Value of Skipped frame counts */ - uint8_t skipped_frame_count; -}; -struct bmi160_dev { - /*! Chip Id */ - uint8_t chip_id; - - /*! Device Id */ - uint8_t id; - - /*! 0 - I2C , 1 - SPI Interface */ - uint8_t intf; - - /*! Hold active interrupts status for any and sig motion - * 0 - Any-motion enable, 1 - Sig-motion enable, - * -1 neither any-motion nor sig-motion selected */ - enum bmi160_any_sig_motion_active_interrupt_state any_sig_sel; - - /*! Structure to configure Accel sensor */ - struct bmi160_cfg accel_cfg; - - /*! Structure to hold previous/old accel config parameters. - * This is used at driver level to prevent overwriting of same - * data, hence user does not change it in the code */ - struct bmi160_cfg prev_accel_cfg; - - /*! Structure to configure Gyro sensor */ - struct bmi160_cfg gyro_cfg; - - /*! Structure to hold previous/old gyro config parameters. - * This is used at driver level to prevent overwriting of same - * data, hence user does not change it in the code */ - struct bmi160_cfg prev_gyro_cfg; - - /*! Structure to configure the auxiliary sensor */ - struct bmi160_aux_cfg aux_cfg; - - /*! Structure to hold previous/old aux config parameters. - * This is used at driver level to prevent overwriting of same - * data, hence user does not change it in the code */ - struct bmi160_aux_cfg prev_aux_cfg; - - /*! FIFO related configurations */ - struct bmi160_fifo_frame* fifo; - - /*! Read function pointer */ - bmi160_read_fptr_t read; - - /*! Write function pointer */ - bmi160_write_fptr_t write; - - /*! Delay function pointer */ - bmi160_delay_fptr_t delay_ms; - - /*! User set read/write length */ - uint16_t read_write_len; -}; - -#endif /* BMI160_DEFS_H_ */ diff --git a/non_catalog_apps/airmouse/tracking/imu/imu.c b/non_catalog_apps/airmouse/tracking/imu/imu.c index 5e89c9504d7..8c4cd6486ca 100644 --- a/non_catalog_apps/airmouse/tracking/imu/imu.c +++ b/non_catalog_apps/airmouse/tracking/imu/imu.c @@ -1,29 +1,54 @@ #include "imu.h" -#include -bool bmi160_begin(); -int bmi160_read(double* vec); +#define IMU_TAG "IMU_H" -bool lsm6ds3trc_begin(); -void lsm6ds3trc_end(); -int lsm6ds3trc_read(double* vec); +extern struct imu_t imu_bmi160; +extern struct imu_t imu_lsm6ds3trc; +extern struct imu_t imu_lsm6dso; + +struct imu_t* imu_types[] = {&imu_bmi160, &imu_lsm6ds3trc, &imu_lsm6dso}; + +static const int imu_count = sizeof(imu_types) / sizeof(struct imu_t*); + +static struct imu_t* imu_found; + +struct imu_t* find_imu() { + unsigned int i; + for(i = 0; i < imu_count; i++) { + if(furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, imu_types[i]->address, 50)) { + FURI_LOG_E(IMU_TAG, "found i2c device address 0x%X", imu_types[i]->address); + return imu_types[i]; + } + } + return NULL; +} bool imu_begin() { + bool ret = false; furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); - bool ret = bmi160_begin(); // lsm6ds3trc_begin(); + + if(imu_found == NULL) { + imu_found = find_imu(); + if(imu_found != NULL) FURI_LOG_E(IMU_TAG, "Found Device %s", imu_found->name); + } + + if(imu_found != NULL) ret = imu_found->begin(); + furi_hal_i2c_release(&furi_hal_i2c_handle_external); return ret; } void imu_end() { - // furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); - // lsm6ds3trc_end(); - // furi_hal_i2c_release(&furi_hal_i2c_handle_external); + if(imu_found == NULL) return; + furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); + imu_found->end(); + furi_hal_i2c_release(&furi_hal_i2c_handle_external); } int imu_read(double* vec) { + if(imu_found == NULL) return 0; furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); - int ret = bmi160_read(vec); // lsm6ds3trc_read(vec); + int ret = imu_found->read(vec); furi_hal_i2c_release(&furi_hal_i2c_handle_external); return ret; } diff --git a/non_catalog_apps/airmouse/tracking/imu/imu.h b/non_catalog_apps/airmouse/tracking/imu/imu.h index f4c5e4b1da6..9b416d2e2c9 100644 --- a/non_catalog_apps/airmouse/tracking/imu/imu.h +++ b/non_catalog_apps/airmouse/tracking/imu/imu.h @@ -1,14 +1,27 @@ -#pragma once +#ifndef IMU_H +#define IMU_H #include +#include #ifdef __cplusplus extern "C" { #endif +struct imu_t { + unsigned int address; + bool (*begin)(void); + void (*end)(void); + int (*read)(double* vec); + char* name; +}; + #define ACC_DATA_READY (1 << 0) #define GYR_DATA_READY (1 << 1) +static const double DEG_TO_RAD = 0.017453292519943295769236907684886; +static const double GRAVITY = 9.81; + bool imu_begin(); void imu_end(); int imu_read(double* vec); @@ -16,3 +29,4 @@ int imu_read(double* vec); #ifdef __cplusplus } #endif +#endif // IMU_H diff --git a/non_catalog_apps/airmouse/tracking/imu/imu_bmi160.c b/non_catalog_apps/airmouse/tracking/imu/imu_bmi160.c deleted file mode 100644 index af771302f40..00000000000 --- a/non_catalog_apps/airmouse/tracking/imu/imu_bmi160.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "bmi160.h" - -#include - -#include "imu.h" - -#define TAG "BMI160" - -#define BMI160_DEV_ADDR (0x69 << 1) - -static const double DEG_TO_RAD = 0.017453292519943295769236907684886; -static const double G = 9.81; - -struct bmi160_dev bmi160dev; -struct bmi160_sensor_data bmi160_accel; -struct bmi160_sensor_data bmi160_gyro; - -int8_t bmi160_write_i2c(uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t len) { - if(furi_hal_i2c_write_mem(&furi_hal_i2c_handle_external, dev_addr, reg_addr, data, len, 50)) - return BMI160_OK; - return BMI160_E_COM_FAIL; -} - -int8_t bmi160_read_i2c(uint8_t dev_addr, uint8_t reg_addr, uint8_t* read_data, uint16_t len) { - if(furi_hal_i2c_read_mem(&furi_hal_i2c_handle_external, dev_addr, reg_addr, read_data, len, 50)) - return BMI160_OK; - return BMI160_E_COM_FAIL; -} - -bool bmi160_begin() { - FURI_LOG_I(TAG, "Init BMI160"); - - if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, BMI160_DEV_ADDR, 50)) { - FURI_LOG_E(TAG, "Device not ready!"); - return false; - } - - FURI_LOG_I(TAG, "Device ready!"); - - bmi160dev.id = BMI160_DEV_ADDR; - bmi160dev.intf = BMI160_I2C_INTF; - bmi160dev.read = bmi160_read_i2c; - bmi160dev.write = bmi160_write_i2c; - bmi160dev.delay_ms = furi_delay_ms; - - if(bmi160_init(&bmi160dev) != BMI160_OK) { - FURI_LOG_E(TAG, "Initialization failure!"); - FURI_LOG_E(TAG, "Chip ID 0x%X", bmi160dev.chip_id); - return false; - } - - bmi160dev.accel_cfg.odr = BMI160_ACCEL_ODR_400HZ; - bmi160dev.accel_cfg.range = BMI160_ACCEL_RANGE_4G; - bmi160dev.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; - bmi160dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; - bmi160dev.gyro_cfg.odr = BMI160_GYRO_ODR_400HZ; - bmi160dev.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS; - bmi160dev.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; - bmi160dev.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; - - if(bmi160_set_sens_conf(&bmi160dev) != BMI160_OK) { - FURI_LOG_E(TAG, "Initialization failure!"); - FURI_LOG_E(TAG, "Chip ID 0x%X", bmi160dev.chip_id); - return false; - } - - FURI_LOG_I(TAG, "Initialization success!"); - FURI_LOG_I(TAG, "Chip ID 0x%X", bmi160dev.chip_id); - - return true; -} - -int bmi160_read(double* vec) { - if(bmi160_get_sensor_data( - (BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &bmi160_accel, &bmi160_gyro, &bmi160dev) != - BMI160_OK) { - return 0; - } - - vec[0] = ((double)bmi160_accel.x * 4 / 32768) * G; - vec[1] = ((double)bmi160_accel.y * 4 / 32768) * G; - vec[2] = ((double)bmi160_accel.z * 4 / 32768) * G; - vec[3] = ((double)bmi160_gyro.x * 2000 / 32768) * DEG_TO_RAD; - vec[4] = ((double)bmi160_gyro.y * 2000 / 32768) * DEG_TO_RAD; - vec[5] = ((double)bmi160_gyro.z * 2000 / 32768) * DEG_TO_RAD; - - return ACC_DATA_READY | GYR_DATA_READY; -} diff --git a/non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.c b/non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.c deleted file mode 100644 index 9f1890d2cad..00000000000 --- a/non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.c +++ /dev/null @@ -1,7105 +0,0 @@ -/** - ****************************************************************************** - * @file lsm6ds3tr_c_reg.c - * @author Sensors Software Solution Team - * @brief LSM6DS3TR_C driver file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -#include "lsm6ds3tr_c_reg.h" - -/** - * @defgroup LSM6DS3TR_C - * @brief This file provides a set of functions needed to drive the - * lsm6ds3tr_c enanced inertial module. - * @{ - * - */ - -/** - * @defgroup LSM6DS3TR_C_interfaces_functions - * @brief This section provide a set of functions used to read and - * write a generic register of the device. - * MANDATORY: return 0 -> no Error. - * @{ - * - */ - -/** - * @brief Read generic device register - * - * @param ctx read / write interface definitions(ptr) - * @param reg register to read - * @param data pointer to buffer that store the data read(ptr) - * @param len number of consecutive register to read - * @retval interface status (MANDATORY: return 0 -> no Error) - * - */ -int32_t lsm6ds3tr_c_read_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len) { - int32_t ret; - - ret = ctx->read_reg(ctx->handle, reg, data, len); - - return ret; -} - -/** - * @brief Write generic device register - * - * @param ctx read / write interface definitions(ptr) - * @param reg register to write - * @param data pointer to data to write in register reg(ptr) - * @param len number of consecutive register to write - * @retval interface status (MANDATORY: return 0 -> no Error) - * - */ -int32_t lsm6ds3tr_c_write_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len) { - int32_t ret; - - ret = ctx->write_reg(ctx->handle, reg, data, len); - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Sensitivity - * @brief These functions convert raw-data into engineering units. - * @{ - * - */ - -float_t lsm6ds3tr_c_from_fs2g_to_mg(int16_t lsb) { - return ((float_t)lsb * 0.061f); -} - -float_t lsm6ds3tr_c_from_fs4g_to_mg(int16_t lsb) { - return ((float_t)lsb * 0.122f); -} - -float_t lsm6ds3tr_c_from_fs8g_to_mg(int16_t lsb) { - return ((float_t)lsb * 0.244f); -} - -float_t lsm6ds3tr_c_from_fs16g_to_mg(int16_t lsb) { - return ((float_t)lsb * 0.488f); -} - -float_t lsm6ds3tr_c_from_fs125dps_to_mdps(int16_t lsb) { - return ((float_t)lsb * 4.375f); -} - -float_t lsm6ds3tr_c_from_fs250dps_to_mdps(int16_t lsb) { - return ((float_t)lsb * 8.750f); -} - -float_t lsm6ds3tr_c_from_fs500dps_to_mdps(int16_t lsb) { - return ((float_t)lsb * 17.50f); -} - -float_t lsm6ds3tr_c_from_fs1000dps_to_mdps(int16_t lsb) { - return ((float_t)lsb * 35.0f); -} - -float_t lsm6ds3tr_c_from_fs2000dps_to_mdps(int16_t lsb) { - return ((float_t)lsb * 70.0f); -} - -float_t lsm6ds3tr_c_from_lsb_to_celsius(int16_t lsb) { - return (((float_t)lsb / 256.0f) + 25.0f); -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_data_generation - * @brief This section groups all the functions concerning data - * generation - * @{ - * - */ - -/** - * @brief Accelerometer full-scale selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fs_xl in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - if(ret == 0) { - ctrl1_xl.fs_xl = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - } - - return ret; -} - -/** - * @brief Accelerometer full-scale selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of fs_xl in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t* val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - switch(ctrl1_xl.fs_xl) { - case LSM6DS3TR_C_2g: - *val = LSM6DS3TR_C_2g; - break; - - case LSM6DS3TR_C_16g: - *val = LSM6DS3TR_C_16g; - break; - - case LSM6DS3TR_C_4g: - *val = LSM6DS3TR_C_4g; - break; - - case LSM6DS3TR_C_8g: - *val = LSM6DS3TR_C_8g; - break; - - default: - *val = LSM6DS3TR_C_XL_FS_ND; - break; - } - - return ret; -} - -/** - * @brief Accelerometer data rate selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of odr_xl in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - if(ret == 0) { - ctrl1_xl.odr_xl = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - } - - return ret; -} - -/** - * @brief Accelerometer data rate selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of odr_xl in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t* val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - switch(ctrl1_xl.odr_xl) { - case LSM6DS3TR_C_XL_ODR_OFF: - *val = LSM6DS3TR_C_XL_ODR_OFF; - break; - - case LSM6DS3TR_C_XL_ODR_12Hz5: - *val = LSM6DS3TR_C_XL_ODR_12Hz5; - break; - - case LSM6DS3TR_C_XL_ODR_26Hz: - *val = LSM6DS3TR_C_XL_ODR_26Hz; - break; - - case LSM6DS3TR_C_XL_ODR_52Hz: - *val = LSM6DS3TR_C_XL_ODR_52Hz; - break; - - case LSM6DS3TR_C_XL_ODR_104Hz: - *val = LSM6DS3TR_C_XL_ODR_104Hz; - break; - - case LSM6DS3TR_C_XL_ODR_208Hz: - *val = LSM6DS3TR_C_XL_ODR_208Hz; - break; - - case LSM6DS3TR_C_XL_ODR_416Hz: - *val = LSM6DS3TR_C_XL_ODR_416Hz; - break; - - case LSM6DS3TR_C_XL_ODR_833Hz: - *val = LSM6DS3TR_C_XL_ODR_833Hz; - break; - - case LSM6DS3TR_C_XL_ODR_1k66Hz: - *val = LSM6DS3TR_C_XL_ODR_1k66Hz; - break; - - case LSM6DS3TR_C_XL_ODR_3k33Hz: - *val = LSM6DS3TR_C_XL_ODR_3k33Hz; - break; - - case LSM6DS3TR_C_XL_ODR_6k66Hz: - *val = LSM6DS3TR_C_XL_ODR_6k66Hz; - break; - - case LSM6DS3TR_C_XL_ODR_1Hz6: - *val = LSM6DS3TR_C_XL_ODR_1Hz6; - break; - - default: - *val = LSM6DS3TR_C_XL_ODR_ND; - break; - } - - return ret; -} - -/** - * @brief Gyroscope chain full-scale selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fs_g in reg CTRL2_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t val) { - lsm6ds3tr_c_ctrl2_g_t ctrl2_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); - - if(ret == 0) { - ctrl2_g.fs_g = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); - } - - return ret; -} - -/** - * @brief Gyroscope chain full-scale selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of fs_g in reg CTRL2_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t* val) { - lsm6ds3tr_c_ctrl2_g_t ctrl2_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); - - switch(ctrl2_g.fs_g) { - case LSM6DS3TR_C_250dps: - *val = LSM6DS3TR_C_250dps; - break; - - case LSM6DS3TR_C_125dps: - *val = LSM6DS3TR_C_125dps; - break; - - case LSM6DS3TR_C_500dps: - *val = LSM6DS3TR_C_500dps; - break; - - case LSM6DS3TR_C_1000dps: - *val = LSM6DS3TR_C_1000dps; - break; - - case LSM6DS3TR_C_2000dps: - *val = LSM6DS3TR_C_2000dps; - break; - - default: - *val = LSM6DS3TR_C_GY_FS_ND; - break; - } - - return ret; -} - -/** - * @brief Gyroscope data rate selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of odr_g in reg CTRL2_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t val) { - lsm6ds3tr_c_ctrl2_g_t ctrl2_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); - - if(ret == 0) { - ctrl2_g.odr_g = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); - } - - return ret; -} - -/** - * @brief Gyroscope data rate selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of odr_g in reg CTRL2_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t* val) { - lsm6ds3tr_c_ctrl2_g_t ctrl2_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL2_G, (uint8_t*)&ctrl2_g, 1); - - switch(ctrl2_g.odr_g) { - case LSM6DS3TR_C_GY_ODR_OFF: - *val = LSM6DS3TR_C_GY_ODR_OFF; - break; - - case LSM6DS3TR_C_GY_ODR_12Hz5: - *val = LSM6DS3TR_C_GY_ODR_12Hz5; - break; - - case LSM6DS3TR_C_GY_ODR_26Hz: - *val = LSM6DS3TR_C_GY_ODR_26Hz; - break; - - case LSM6DS3TR_C_GY_ODR_52Hz: - *val = LSM6DS3TR_C_GY_ODR_52Hz; - break; - - case LSM6DS3TR_C_GY_ODR_104Hz: - *val = LSM6DS3TR_C_GY_ODR_104Hz; - break; - - case LSM6DS3TR_C_GY_ODR_208Hz: - *val = LSM6DS3TR_C_GY_ODR_208Hz; - break; - - case LSM6DS3TR_C_GY_ODR_416Hz: - *val = LSM6DS3TR_C_GY_ODR_416Hz; - break; - - case LSM6DS3TR_C_GY_ODR_833Hz: - *val = LSM6DS3TR_C_GY_ODR_833Hz; - break; - - case LSM6DS3TR_C_GY_ODR_1k66Hz: - *val = LSM6DS3TR_C_GY_ODR_1k66Hz; - break; - - case LSM6DS3TR_C_GY_ODR_3k33Hz: - *val = LSM6DS3TR_C_GY_ODR_3k33Hz; - break; - - case LSM6DS3TR_C_GY_ODR_6k66Hz: - *val = LSM6DS3TR_C_GY_ODR_6k66Hz; - break; - - default: - *val = LSM6DS3TR_C_GY_ODR_ND; - break; - } - - return ret; -} - -/** - * @brief Block data update.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of bdu in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_block_data_update_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.bdu = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Block data update.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of bdu in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_block_data_update_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - *val = ctrl3_c.bdu; - - return ret; -} - -/** - * @brief Weight of XL user offset bits of registers - * X_OFS_USR(73h), Y_OFS_USR(74h), Z_OFS_USR(75h).[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of usr_off_w in reg CTRL6_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_offset_weight_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t val) { - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - if(ret == 0) { - ctrl6_c.usr_off_w = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - } - - return ret; -} - -/** - * @brief Weight of XL user offset bits of registers - * X_OFS_USR(73h), Y_OFS_USR(74h), Z_OFS_USR(75h).[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of usr_off_w in reg CTRL6_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_offset_weight_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t* val) { - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - switch(ctrl6_c.usr_off_w) { - case LSM6DS3TR_C_LSb_1mg: - *val = LSM6DS3TR_C_LSb_1mg; - break; - - case LSM6DS3TR_C_LSb_16mg: - *val = LSM6DS3TR_C_LSb_16mg; - break; - - default: - *val = LSM6DS3TR_C_WEIGHT_ND; - break; - } - - return ret; -} - -/** - * @brief High-performance operating mode for accelerometer[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of xl_hm_mode in reg CTRL6_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t val) { - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - if(ret == 0) { - ctrl6_c.xl_hm_mode = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - } - - return ret; -} - -/** - * @brief High-performance operating mode for accelerometer.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of xl_hm_mode in reg CTRL6_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t* val) { - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - switch(ctrl6_c.xl_hm_mode) { - case LSM6DS3TR_C_XL_HIGH_PERFORMANCE: - *val = LSM6DS3TR_C_XL_HIGH_PERFORMANCE; - break; - - case LSM6DS3TR_C_XL_NORMAL: - *val = LSM6DS3TR_C_XL_NORMAL; - break; - - default: - *val = LSM6DS3TR_C_XL_PW_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief Source register rounding function on WAKE_UP_SRC (1Bh), - * TAP_SRC (1Ch), D6D_SRC (1Dh), STATUS_REG (1Eh) and - * FUNC_SRC1 (53h) registers in the primary interface.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of rounding_status in reg CTRL7_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_rounding_on_status_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t val) { - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - if(ret == 0) { - ctrl7_g.rounding_status = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - } - - return ret; -} - -/** - * @brief Source register rounding function on WAKE_UP_SRC (1Bh), - * TAP_SRC (1Ch), D6D_SRC (1Dh), STATUS_REG (1Eh) and - * FUNC_SRC1 (53h) registers in the primary interface.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of rounding_status in reg CTRL7_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_rounding_on_status_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t* val) { - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - switch(ctrl7_g.rounding_status) { - case LSM6DS3TR_C_STAT_RND_DISABLE: - *val = LSM6DS3TR_C_STAT_RND_DISABLE; - break; - - case LSM6DS3TR_C_STAT_RND_ENABLE: - *val = LSM6DS3TR_C_STAT_RND_ENABLE; - break; - - default: - *val = LSM6DS3TR_C_STAT_RND_ND; - break; - } - - return ret; -} - -/** - * @brief High-performance operating mode disable for gyroscope.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of g_hm_mode in reg CTRL7_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t val) { - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - if(ret == 0) { - ctrl7_g.g_hm_mode = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - } - - return ret; -} - -/** - * @brief High-performance operating mode disable for gyroscope.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of g_hm_mode in reg CTRL7_G - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t* val) { - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - switch(ctrl7_g.g_hm_mode) { - case LSM6DS3TR_C_GY_HIGH_PERFORMANCE: - *val = LSM6DS3TR_C_GY_HIGH_PERFORMANCE; - break; - - case LSM6DS3TR_C_GY_NORMAL: - *val = LSM6DS3TR_C_GY_NORMAL; - break; - - default: - *val = LSM6DS3TR_C_GY_PW_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief Read all the interrupt/status flag of the device.[get] - * - * @param ctx Read / write interface definitions - * @param val WAKE_UP_SRC, TAP_SRC, D6D_SRC, STATUS_REG, - * FUNC_SRC1, FUNC_SRC2, WRIST_TILT_IA, A_WRIST_TILT_Mask - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_all_sources_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_all_sources_t* val) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_SRC, (uint8_t*)&(val->wake_up_src), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_SRC, (uint8_t*)&(val->tap_src), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_D6D_SRC, (uint8_t*)&(val->d6d_src), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&(val->status_reg), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_SRC1, (uint8_t*)&(val->func_src1), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_SRC2, (uint8_t*)&(val->func_src2), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_WRIST_TILT_IA, (uint8_t*)&(val->wrist_tilt_ia), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, (uint8_t*)&(val->a_wrist_tilt_mask), 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - - return ret; -} -/** - * @brief The STATUS_REG register is read by the primary interface[get] - * - * @param ctx Read / write interface definitions - * @param val Registers STATUS_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_status_reg_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_status_reg_t* val) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)val, 1); - - return ret; -} - -/** - * @brief Accelerometer new data available.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of xlda in reg STATUS_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_status_reg_t status_reg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&status_reg, 1); - *val = status_reg.xlda; - - return ret; -} - -/** - * @brief Gyroscope new data available.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of gda in reg STATUS_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_status_reg_t status_reg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&status_reg, 1); - *val = status_reg.gda; - - return ret; -} - -/** - * @brief Temperature new data available.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tda in reg STATUS_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_temp_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_status_reg_t status_reg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STATUS_REG, (uint8_t*)&status_reg, 1); - *val = status_reg.tda; - - return ret; -} - -/** - * @brief Accelerometer axis user offset correction expressed in two’s - * complement, weight depends on USR_OFF_W in CTRL6_C. - * The value must be in the range [-127 127].[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that contains data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_usr_offset_set(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_X_OFS_USR, buff, 3); - - return ret; -} - -/** - * @brief Accelerometer axis user offset correction xpressed in two’s - * complement, weight depends on USR_OFF_W in CTRL6_C. - * The value must be in the range [-127 127].[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_usr_offset_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_X_OFS_USR, buff, 3); - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Timestamp - * @brief This section groups all the functions that manage the - * timestamp generation. - * @{ - * - */ - -/** - * @brief Enable timestamp count. The count is saved in TIMESTAMP0_REG (40h), - * TIMESTAMP1_REG (41h) and TIMESTAMP2_REG (42h).[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of timer_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_timestamp_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.timer_en = val; - - if(val != 0x00U) { - ctrl10_c.func_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - } - - return ret; -} - -/** - * @brief Enable timestamp count. The count is saved in TIMESTAMP0_REG (40h), - * TIMESTAMP1_REG (41h) and TIMESTAMP2_REG (42h).[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of timer_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_timestamp_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - *val = ctrl10_c.timer_en; - - return ret; -} - -/** - * @brief Timestamp register resolution setting. - * Configuration of this bit affects - * TIMESTAMP0_REG(40h), TIMESTAMP1_REG(41h), - * TIMESTAMP2_REG(42h), STEP_TIMESTAMP_L(49h), - * STEP_TIMESTAMP_H(4Ah) and - * STEP_COUNT_DELTA(15h) registers.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of timer_hr in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_timestamp_res_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - - if(ret == 0) { - wake_up_dur.timer_hr = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - } - - return ret; -} - -/** - * @brief Timestamp register resolution setting. - * Configuration of this bit affects - * TIMESTAMP0_REG(40h), TIMESTAMP1_REG(41h), - * TIMESTAMP2_REG(42h), STEP_TIMESTAMP_L(49h), - * STEP_TIMESTAMP_H(4Ah) and - * STEP_COUNT_DELTA(15h) registers.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of timer_hr in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_timestamp_res_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t* val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - - switch(wake_up_dur.timer_hr) { - case LSM6DS3TR_C_LSB_6ms4: - *val = LSM6DS3TR_C_LSB_6ms4; - break; - - case LSM6DS3TR_C_LSB_25us: - *val = LSM6DS3TR_C_LSB_25us; - break; - - default: - *val = LSM6DS3TR_C_TS_RES_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Dataoutput - * @brief This section groups all the data output functions. - * @{ - * - */ - -/** - * @brief Circular burst-mode (rounding) read from output registers - * through the primary interface.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of rounding in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_rounding_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - if(ret == 0) { - ctrl5_c.rounding = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - } - - return ret; -} - -/** - * @brief Circular burst-mode (rounding) read from output registers - * through the primary interface.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of rounding in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_rounding_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t* val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - switch(ctrl5_c.rounding) { - case LSM6DS3TR_C_ROUND_DISABLE: - *val = LSM6DS3TR_C_ROUND_DISABLE; - break; - - case LSM6DS3TR_C_ROUND_XL: - *val = LSM6DS3TR_C_ROUND_XL; - break; - - case LSM6DS3TR_C_ROUND_GY: - *val = LSM6DS3TR_C_ROUND_GY; - break; - - case LSM6DS3TR_C_ROUND_GY_XL: - *val = LSM6DS3TR_C_ROUND_GY_XL; - break; - - case LSM6DS3TR_C_ROUND_SH1_TO_SH6: - *val = LSM6DS3TR_C_ROUND_SH1_TO_SH6; - break; - - case LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6: - *val = LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6; - break; - - case LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12: - *val = LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12; - break; - - case LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6: - *val = LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6; - break; - - default: - *val = LSM6DS3TR_C_ROUND_OUT_ND; - break; - } - - return ret; -} - -/** - * @brief Temperature data output register (r). L and H registers together - * express a 16-bit word in two’s complement.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_temperature_raw_get(stmdev_ctx_t* ctx, int16_t* val) { - uint8_t buff[2]; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUT_TEMP_L, buff, 2); - *val = (int16_t)buff[1]; - *val = (*val * 256) + (int16_t)buff[0]; - - return ret; -} - -/** - * @brief Angular rate sensor. The value is expressed as a 16-bit word in - * two’s complement.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_angular_rate_raw_get(stmdev_ctx_t* ctx, int16_t* val) { - uint8_t buff[6]; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUTX_L_G, buff, 6); - val[0] = (int16_t)buff[1]; - val[0] = (val[0] * 256) + (int16_t)buff[0]; - val[1] = (int16_t)buff[3]; - val[1] = (val[1] * 256) + (int16_t)buff[2]; - val[2] = (int16_t)buff[5]; - val[2] = (val[2] * 256) + (int16_t)buff[4]; - - return ret; -} - -/** - * @brief Linear acceleration output register. The value is expressed - * as a 16-bit word in two’s complement.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_acceleration_raw_get(stmdev_ctx_t* ctx, int16_t* val) { - uint8_t buff[6]; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUTX_L_XL, buff, 6); - val[0] = (int16_t)buff[1]; - val[0] = (val[0] * 256) + (int16_t)buff[0]; - val[1] = (int16_t)buff[3]; - val[1] = (val[1] * 256) + (int16_t)buff[2]; - val[2] = (int16_t)buff[5]; - val[2] = (val[2] * 256) + (int16_t)buff[4]; - - return ret; -} - -/** - * @brief External magnetometer raw data.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_calibrated_raw_get(stmdev_ctx_t* ctx, int16_t* val) { - uint8_t buff[6]; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_OUT_MAG_RAW_X_L, buff, 6); - val[0] = (int16_t)buff[1]; - val[0] = (val[0] * 256) + (int16_t)buff[0]; - val[1] = (int16_t)buff[3]; - val[1] = (val[1] * 256) + (int16_t)buff[2]; - val[2] = (int16_t)buff[5]; - val[2] = (val[2] * 256) + (int16_t)buff[4]; - - return ret; -} - -/** - * @brief Read data in FIFO.[get] - * - * @param ctx Read / write interface definitions - * @param buffer Data buffer to store FIFO data. - * @param len Number of data to read from FIFO. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_raw_data_get(stmdev_ctx_t* ctx, uint8_t* buffer, uint8_t len) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_DATA_OUT_L, buffer, len); - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_common - * @brief This section groups common useful functions. - * @{ - * - */ - -/** - * @brief Enable access to the embedded functions/sensor hub - * configuration registers[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of func_cfg_en in reg FUNC_CFG_ACCESS - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mem_bank_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t val) { - lsm6ds3tr_c_func_cfg_access_t func_cfg_access; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, (uint8_t*)&func_cfg_access, 1); - - if(ret == 0) { - func_cfg_access.func_cfg_en = (uint8_t)val; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, (uint8_t*)&func_cfg_access, 1); - } - - return ret; -} - -/** - * @brief Enable access to the embedded functions/sensor hub configuration - * registers[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of func_cfg_en in reg FUNC_CFG_ACCESS - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mem_bank_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t* val) { - lsm6ds3tr_c_func_cfg_access_t func_cfg_access; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FUNC_CFG_ACCESS, (uint8_t*)&func_cfg_access, 1); - - switch(func_cfg_access.func_cfg_en) { - case LSM6DS3TR_C_USER_BANK: - *val = LSM6DS3TR_C_USER_BANK; - break; - - case LSM6DS3TR_C_BANK_B: - *val = LSM6DS3TR_C_BANK_B; - break; - - default: - *val = LSM6DS3TR_C_BANK_ND; - break; - } - - return ret; -} - -/** - * @brief Data-ready pulsed / letched mode[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of drdy_pulsed in reg DRDY_PULSE_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_data_ready_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t val) { - lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); - - if(ret == 0) { - drdy_pulse_cfg_g.drdy_pulsed = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); - } - - return ret; -} - -/** - * @brief Data-ready pulsed / letched mode[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of drdy_pulsed in reg DRDY_PULSE_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_data_ready_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t* val) { - lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); - - switch(drdy_pulse_cfg_g.drdy_pulsed) { - case LSM6DS3TR_C_DRDY_LATCHED: - *val = LSM6DS3TR_C_DRDY_LATCHED; - break; - - case LSM6DS3TR_C_DRDY_PULSED: - *val = LSM6DS3TR_C_DRDY_PULSED; - break; - - default: - *val = LSM6DS3TR_C_DRDY_ND; - break; - } - - return ret; -} - -/** - * @brief DeviceWhoamI.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_device_id_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WHO_AM_I, buff, 1); - - return ret; -} - -/** - * @brief Software reset. Restore the default values in user registers[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sw_reset in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_reset_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.sw_reset = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Software reset. Restore the default values in user registers[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sw_reset in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_reset_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - *val = ctrl3_c.sw_reset; - - return ret; -} - -/** - * @brief Big/Little Endian Data selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of ble in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_data_format_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.ble = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Big/Little Endian Data selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of ble in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_data_format_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - switch(ctrl3_c.ble) { - case LSM6DS3TR_C_LSB_AT_LOW_ADD: - *val = LSM6DS3TR_C_LSB_AT_LOW_ADD; - break; - - case LSM6DS3TR_C_MSB_AT_LOW_ADD: - *val = LSM6DS3TR_C_MSB_AT_LOW_ADD; - break; - - default: - *val = LSM6DS3TR_C_DATA_FMT_ND; - break; - } - - return ret; -} - -/** - * @brief Register address automatically incremented during a multiple byte - * access with a serial interface.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of if_inc in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_auto_increment_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.if_inc = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Register address automatically incremented during a multiple byte - * access with a serial interface.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of if_inc in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_auto_increment_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - *val = ctrl3_c.if_inc; - - return ret; -} - -/** - * @brief Reboot memory content. Reload the calibration parameters.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of boot in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_boot_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.boot = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Reboot memory content. Reload the calibration parameters.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of boot in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_boot_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - *val = ctrl3_c.boot; - - return ret; -} - -/** - * @brief Linear acceleration sensor self-test enable.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of st_xl in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - if(ret == 0) { - ctrl5_c.st_xl = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - } - - return ret; -} - -/** - * @brief Linear acceleration sensor self-test enable.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of st_xl in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t* val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - switch(ctrl5_c.st_xl) { - case LSM6DS3TR_C_XL_ST_DISABLE: - *val = LSM6DS3TR_C_XL_ST_DISABLE; - break; - - case LSM6DS3TR_C_XL_ST_POSITIVE: - *val = LSM6DS3TR_C_XL_ST_POSITIVE; - break; - - case LSM6DS3TR_C_XL_ST_NEGATIVE: - *val = LSM6DS3TR_C_XL_ST_NEGATIVE; - break; - - default: - *val = LSM6DS3TR_C_XL_ST_ND; - break; - } - - return ret; -} - -/** - * @brief Angular rate sensor self-test enable.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of st_g in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - if(ret == 0) { - ctrl5_c.st_g = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - } - - return ret; -} - -/** - * @brief Angular rate sensor self-test enable.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of st_g in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t* val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - switch(ctrl5_c.st_g) { - case LSM6DS3TR_C_GY_ST_DISABLE: - *val = LSM6DS3TR_C_GY_ST_DISABLE; - break; - - case LSM6DS3TR_C_GY_ST_POSITIVE: - *val = LSM6DS3TR_C_GY_ST_POSITIVE; - break; - - case LSM6DS3TR_C_GY_ST_NEGATIVE: - *val = LSM6DS3TR_C_GY_ST_NEGATIVE; - break; - - default: - *val = LSM6DS3TR_C_GY_ST_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_filters - * @brief This section group all the functions concerning the filters - * configuration that impact both accelerometer and gyro. - * @{ - * - */ - -/** - * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends - * (XL and Gyro independently masked).[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of drdy_mask in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_filter_settling_mask_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ctrl4_c.drdy_mask = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - - return ret; -} - -/** - * @brief Mask DRDY on pin (both XL & Gyro) until filter settling ends - * (XL and Gyro independently masked).[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of drdy_mask in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_filter_settling_mask_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - *val = ctrl4_c.drdy_mask; - - return ret; -} - -/** - * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity - * functions.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of slope_fds in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_hp_path_internal_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if(ret == 0) { - tap_cfg.slope_fds = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief HPF or SLOPE filter selection on wake-up and Activity/Inactivity - * functions.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of slope_fds in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_hp_path_internal_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t* val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - switch(tap_cfg.slope_fds) { - case LSM6DS3TR_C_USE_SLOPE: - *val = LSM6DS3TR_C_USE_SLOPE; - break; - - case LSM6DS3TR_C_USE_HPF: - *val = LSM6DS3TR_C_USE_HPF; - break; - - default: - *val = LSM6DS3TR_C_HP_PATH_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_accelerometer_filters - * @brief This section group all the functions concerning the filters - * configuration that impact accelerometer in every mode. - * @{ - * - */ - -/** - * @brief Accelerometer analog chain bandwidth selection (only for - * accelerometer ODR ≥ 1.67 kHz).[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of bw0_xl in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_filter_analog_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - if(ret == 0) { - ctrl1_xl.bw0_xl = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - } - - return ret; -} - -/** - * @brief Accelerometer analog chain bandwidth selection (only for - * accelerometer ODR ≥ 1.67 kHz).[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of bw0_xl in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_filter_analog_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t* val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - switch(ctrl1_xl.bw0_xl) { - case LSM6DS3TR_C_XL_ANA_BW_1k5Hz: - *val = LSM6DS3TR_C_XL_ANA_BW_1k5Hz; - break; - - case LSM6DS3TR_C_XL_ANA_BW_400Hz: - *val = LSM6DS3TR_C_XL_ANA_BW_400Hz; - break; - - default: - *val = LSM6DS3TR_C_XL_ANA_BW_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_accelerometer_filters - * @brief This section group all the functions concerning the filters - * configuration that impact accelerometer. - * @{ - * - */ - -/** - * @brief Accelerometer digital LPF (LPF1) bandwidth selection LPF2 is - * not used.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of lpf1_bw_sel in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_lp1_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - if(ret == 0) { - ctrl1_xl.lpf1_bw_sel = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - ctrl8_xl.lpf2_xl_en = 0; - ctrl8_xl.hp_slope_xl_en = 0; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - } - } - } - - return ret; -} - -/** - * @brief Accelerometer digital LPF (LPF1) bandwidth selection LPF2 - * is not used.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of lpf1_bw_sel in reg CTRL1_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_lp1_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t* val) { - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - if((ctrl8_xl.lpf2_xl_en != 0x00U) || (ctrl8_xl.hp_slope_xl_en != 0x00U)) { - *val = LSM6DS3TR_C_XL_LP1_NA; - } - - else { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL1_XL, (uint8_t*)&ctrl1_xl, 1); - - switch(ctrl1_xl.lpf1_bw_sel) { - case LSM6DS3TR_C_XL_LP1_ODR_DIV_2: - *val = LSM6DS3TR_C_XL_LP1_ODR_DIV_2; - break; - - case LSM6DS3TR_C_XL_LP1_ODR_DIV_4: - *val = LSM6DS3TR_C_XL_LP1_ODR_DIV_4; - break; - - default: - *val = LSM6DS3TR_C_XL_LP1_NA; - break; - } - } - } - - return ret; -} - -/** - * @brief LPF2 on outputs[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of input_composite in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_lp2_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - ctrl8_xl.input_composite = ((uint8_t)val & 0x10U) >> 4; - ctrl8_xl.hpcf_xl = (uint8_t)val & 0x03U; - ctrl8_xl.lpf2_xl_en = 1; - ctrl8_xl.hp_slope_xl_en = 0; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - } - - return ret; -} - -/** - * @brief LPF2 on outputs[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of input_composite in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_lp2_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t* val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - if((ctrl8_xl.lpf2_xl_en == 0x00U) || (ctrl8_xl.hp_slope_xl_en != 0x00U)) { - *val = LSM6DS3TR_C_XL_LP_NA; - } - - else { - switch((ctrl8_xl.input_composite << 4) + ctrl8_xl.hpcf_xl) { - case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50: - *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50; - break; - - case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100: - *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100; - break; - - case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9: - *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9; - break; - - case LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400: - *val = LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400; - break; - - case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50: - *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50; - break; - - case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100: - *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100; - break; - - case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9: - *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9; - break; - - case LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400: - *val = LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400; - break; - - default: - *val = LSM6DS3TR_C_XL_LP_NA; - break; - } - } - } - - return ret; -} - -/** - * @brief Enable HP filter reference mode.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of hp_ref_mode in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_reference_mode_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - ctrl8_xl.hp_ref_mode = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - } - - return ret; -} - -/** - * @brief Enable HP filter reference mode.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of hp_ref_mode in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_reference_mode_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - *val = ctrl8_xl.hp_ref_mode; - - return ret; -} - -/** - * @brief High pass/Slope on outputs.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of hpcf_xl in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_hp_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - ctrl8_xl.input_composite = 0; - ctrl8_xl.hpcf_xl = (uint8_t)val & 0x03U; - ctrl8_xl.hp_slope_xl_en = 1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - } - - return ret; -} - -/** - * @brief High pass/Slope on outputs.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of hpcf_xl in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_xl_hp_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t* val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ctrl8_xl.hp_slope_xl_en == 0x00U) { - *val = LSM6DS3TR_C_XL_HP_NA; - } - - switch(ctrl8_xl.hpcf_xl) { - case LSM6DS3TR_C_XL_HP_ODR_DIV_4: - *val = LSM6DS3TR_C_XL_HP_ODR_DIV_4; - break; - - case LSM6DS3TR_C_XL_HP_ODR_DIV_100: - *val = LSM6DS3TR_C_XL_HP_ODR_DIV_100; - break; - - case LSM6DS3TR_C_XL_HP_ODR_DIV_9: - *val = LSM6DS3TR_C_XL_HP_ODR_DIV_9; - break; - - case LSM6DS3TR_C_XL_HP_ODR_DIV_400: - *val = LSM6DS3TR_C_XL_HP_ODR_DIV_400; - break; - - default: - *val = LSM6DS3TR_C_XL_HP_NA; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_gyroscope_filters - * @brief This section group all the functions concerning the filters - * configuration that impact gyroscope. - * @{ - * - */ - -/** - * @brief Gyroscope low pass path bandwidth.[set] - * - * @param ctx Read / write interface definitions - * @param val gyroscope filtering chain configuration. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_band_pass_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - if(ret == 0) { - ctrl7_g.hpm_g = ((uint8_t)val & 0x30U) >> 4; - ctrl7_g.hp_en_g = ((uint8_t)val & 0x80U) >> 7; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - if(ret == 0) { - ctrl6_c.ftype = (uint8_t)val & 0x03U; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ctrl4_c.lpf1_sel_g = ((uint8_t)val & 0x08U) >> 3; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - } - } - } - } - - return ret; -} - -/** - * @brief Gyroscope low pass path bandwidth.[get] - * - * @param ctx Read / write interface definitions - * @param val gyroscope filtering chain - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_band_pass_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t* val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL7_G, (uint8_t*)&ctrl7_g, 1); - - switch((ctrl7_g.hp_en_g << 7) + (ctrl7_g.hpm_g << 4) + (ctrl4_c.lpf1_sel_g << 3) + - ctrl6_c.ftype) { - case LSM6DS3TR_C_HP_16mHz_LP2: - *val = LSM6DS3TR_C_HP_16mHz_LP2; - break; - - case LSM6DS3TR_C_HP_65mHz_LP2: - *val = LSM6DS3TR_C_HP_65mHz_LP2; - break; - - case LSM6DS3TR_C_HP_260mHz_LP2: - *val = LSM6DS3TR_C_HP_260mHz_LP2; - break; - - case LSM6DS3TR_C_HP_1Hz04_LP2: - *val = LSM6DS3TR_C_HP_1Hz04_LP2; - break; - - case LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT: - *val = LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT; - break; - - case LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL: - *val = LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL; - break; - - case LSM6DS3TR_C_HP_DISABLE_LP_STRONG: - *val = LSM6DS3TR_C_HP_DISABLE_LP_STRONG; - break; - - case LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE: - *val = LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE; - break; - - case LSM6DS3TR_C_HP_16mHz_LP1_LIGHT: - *val = LSM6DS3TR_C_HP_16mHz_LP1_LIGHT; - break; - - case LSM6DS3TR_C_HP_65mHz_LP1_NORMAL: - *val = LSM6DS3TR_C_HP_65mHz_LP1_NORMAL; - break; - - case LSM6DS3TR_C_HP_260mHz_LP1_STRONG: - *val = LSM6DS3TR_C_HP_260mHz_LP1_STRONG; - break; - - case LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE: - *val = LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE; - break; - - default: - *val = LSM6DS3TR_C_HP_GY_BAND_NA; - break; - } - } - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_serial_interface - * @brief This section groups all the functions concerning serial - * interface management - * @{ - * - */ - -/** - * @brief SPI Serial Interface Mode selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sim in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_spi_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.sim = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief SPI Serial Interface Mode selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of sim in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_spi_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - switch(ctrl3_c.sim) { - case LSM6DS3TR_C_SPI_4_WIRE: - *val = LSM6DS3TR_C_SPI_4_WIRE; - break; - - case LSM6DS3TR_C_SPI_3_WIRE: - *val = LSM6DS3TR_C_SPI_3_WIRE; - break; - - default: - *val = LSM6DS3TR_C_SPI_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief Disable / Enable I2C interface.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of i2c_disable in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_i2c_interface_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ctrl4_c.i2c_disable = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - - return ret; -} - -/** - * @brief Disable / Enable I2C interface.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of i2c_disable in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_i2c_interface_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t* val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - switch(ctrl4_c.i2c_disable) { - case LSM6DS3TR_C_I2C_ENABLE: - *val = LSM6DS3TR_C_I2C_ENABLE; - break; - - case LSM6DS3TR_C_I2C_DISABLE: - *val = LSM6DS3TR_C_I2C_DISABLE; - break; - - default: - *val = LSM6DS3TR_C_I2C_MODE_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_interrupt_pins - * @brief This section groups all the functions that manage - * interrupt pins - * @{ - * - */ - -/** - * @brief Select the signal that need to route on int1 pad[set] - * - * @param ctx Read / write interface definitions - * @param val configure INT1_CTRL, MD1_CFG, CTRL4_C(den_drdy_int1), - * MASTER_CONFIG(drdy_on_int1) - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_int1_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t val) { - lsm6ds3tr_c_master_config_t master_config; - lsm6ds3tr_c_int1_ctrl_t int1_ctrl; - lsm6ds3tr_c_md1_cfg_t md1_cfg; - lsm6ds3tr_c_md2_cfg_t md2_cfg; - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT1_CTRL, (uint8_t*)&int1_ctrl, 1); - - if(ret == 0) { - int1_ctrl.int1_drdy_xl = val.int1_drdy_xl; - int1_ctrl.int1_drdy_g = val.int1_drdy_g; - int1_ctrl.int1_boot = val.int1_boot; - int1_ctrl.int1_fth = val.int1_fth; - int1_ctrl.int1_fifo_ovr = val.int1_fifo_ovr; - int1_ctrl.int1_full_flag = val.int1_full_flag; - int1_ctrl.int1_sign_mot = val.int1_sign_mot; - int1_ctrl.int1_step_detector = val.int1_step_detector; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT1_CTRL, (uint8_t*)&int1_ctrl, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); - } - - if(ret == 0) { - md1_cfg.int1_timer = val.int1_timer; - md1_cfg.int1_tilt = val.int1_tilt; - md1_cfg.int1_6d = val.int1_6d; - md1_cfg.int1_double_tap = val.int1_double_tap; - md1_cfg.int1_ff = val.int1_ff; - md1_cfg.int1_wu = val.int1_wu; - md1_cfg.int1_single_tap = val.int1_single_tap; - md1_cfg.int1_inact_state = val.int1_inact_state; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - - if(ret == 0) { - ctrl4_c.den_drdy_int1 = val.den_drdy_int1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - if(ret == 0) { - master_config.drdy_on_int1 = val.den_drdy_int1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if((val.int1_6d != 0x00U) || (val.int1_ff != 0x00U) || (val.int1_wu != 0x00U) || - (val.int1_single_tap != 0x00U) || (val.int1_double_tap != 0x00U) || - (val.int1_inact_state != 0x00U) || (md2_cfg.int2_6d != 0x00U) || - (md2_cfg.int2_ff != 0x00U) || (md2_cfg.int2_wu != 0x00U) || - (md2_cfg.int2_single_tap != 0x00U) || (md2_cfg.int2_double_tap != 0x00U) || - (md2_cfg.int2_inact_state != 0x00U)) { - tap_cfg.interrupts_enable = PROPERTY_ENABLE; - } - - else { - tap_cfg.interrupts_enable = PROPERTY_DISABLE; - } - } - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Select the signal that need to route on int1 pad[get] - * - * @param ctx Read / write interface definitions - * @param val read INT1_CTRL, MD1_CFG, CTRL4_C(den_drdy_int1), - * MASTER_CONFIG(drdy_on_int1) - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_int1_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t* val) { - lsm6ds3tr_c_master_config_t master_config; - lsm6ds3tr_c_int1_ctrl_t int1_ctrl; - lsm6ds3tr_c_md1_cfg_t md1_cfg; - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT1_CTRL, (uint8_t*)&int1_ctrl, 1); - - if(ret == 0) { - val->int1_drdy_xl = int1_ctrl.int1_drdy_xl; - val->int1_drdy_g = int1_ctrl.int1_drdy_g; - val->int1_boot = int1_ctrl.int1_boot; - val->int1_fth = int1_ctrl.int1_fth; - val->int1_fifo_ovr = int1_ctrl.int1_fifo_ovr; - val->int1_full_flag = int1_ctrl.int1_full_flag; - val->int1_sign_mot = int1_ctrl.int1_sign_mot; - val->int1_step_detector = int1_ctrl.int1_step_detector; - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); - - if(ret == 0) { - val->int1_timer = md1_cfg.int1_timer; - val->int1_tilt = md1_cfg.int1_tilt; - val->int1_6d = md1_cfg.int1_6d; - val->int1_double_tap = md1_cfg.int1_double_tap; - val->int1_ff = md1_cfg.int1_ff; - val->int1_wu = md1_cfg.int1_wu; - val->int1_single_tap = md1_cfg.int1_single_tap; - val->int1_inact_state = md1_cfg.int1_inact_state; - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - val->den_drdy_int1 = ctrl4_c.den_drdy_int1; - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - val->den_drdy_int1 = master_config.drdy_on_int1; - } - } - } - - return ret; -} - -/** - * @brief Select the signal that need to route on int2 pad[set] - * - * @param ctx Read / write interface definitions - * @param val INT2_CTRL, DRDY_PULSE_CFG(int2_wrist_tilt), MD2_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_int2_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t val) { - lsm6ds3tr_c_int2_ctrl_t int2_ctrl; - lsm6ds3tr_c_md1_cfg_t md1_cfg; - lsm6ds3tr_c_md2_cfg_t md2_cfg; - lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT2_CTRL, (uint8_t*)&int2_ctrl, 1); - - if(ret == 0) { - int2_ctrl.int2_drdy_xl = val.int2_drdy_xl; - int2_ctrl.int2_drdy_g = val.int2_drdy_g; - int2_ctrl.int2_drdy_temp = val.int2_drdy_temp; - int2_ctrl.int2_fth = val.int2_fth; - int2_ctrl.int2_fifo_ovr = val.int2_fifo_ovr; - int2_ctrl.int2_full_flag = val.int2_full_flag; - int2_ctrl.int2_step_count_ov = val.int2_step_count_ov; - int2_ctrl.int2_step_delta = val.int2_step_delta; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT2_CTRL, (uint8_t*)&int2_ctrl, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD1_CFG, (uint8_t*)&md1_cfg, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); - } - - if(ret == 0) { - md2_cfg.int2_iron = val.int2_iron; - md2_cfg.int2_tilt = val.int2_tilt; - md2_cfg.int2_6d = val.int2_6d; - md2_cfg.int2_double_tap = val.int2_double_tap; - md2_cfg.int2_ff = val.int2_ff; - md2_cfg.int2_wu = val.int2_wu; - md2_cfg.int2_single_tap = val.int2_single_tap; - md2_cfg.int2_inact_state = val.int2_inact_state; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); - } - - if(ret == 0) { - drdy_pulse_cfg_g.int2_wrist_tilt = val.int2_wrist_tilt; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); - } - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if((md1_cfg.int1_6d != 0x00U) || (md1_cfg.int1_ff != 0x00U) || - (md1_cfg.int1_wu != 0x00U) || (md1_cfg.int1_single_tap != 0x00U) || - (md1_cfg.int1_double_tap != 0x00U) || (md1_cfg.int1_inact_state != 0x00U) || - (val.int2_6d != 0x00U) || (val.int2_ff != 0x00U) || (val.int2_wu != 0x00U) || - (val.int2_single_tap != 0x00U) || (val.int2_double_tap != 0x00U) || - (val.int2_inact_state != 0x00U)) { - tap_cfg.interrupts_enable = PROPERTY_ENABLE; - } - - else { - tap_cfg.interrupts_enable = PROPERTY_DISABLE; - } - } - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Select the signal that need to route on int2 pad[get] - * - * @param ctx Read / write interface definitions - * @param val INT2_CTRL, DRDY_PULSE_CFG(int2_wrist_tilt), MD2_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_int2_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t* val) { - lsm6ds3tr_c_int2_ctrl_t int2_ctrl; - lsm6ds3tr_c_md2_cfg_t md2_cfg; - lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT2_CTRL, (uint8_t*)&int2_ctrl, 1); - - if(ret == 0) { - val->int2_drdy_xl = int2_ctrl.int2_drdy_xl; - val->int2_drdy_g = int2_ctrl.int2_drdy_g; - val->int2_drdy_temp = int2_ctrl.int2_drdy_temp; - val->int2_fth = int2_ctrl.int2_fth; - val->int2_fifo_ovr = int2_ctrl.int2_fifo_ovr; - val->int2_full_flag = int2_ctrl.int2_full_flag; - val->int2_step_count_ov = int2_ctrl.int2_step_count_ov; - val->int2_step_delta = int2_ctrl.int2_step_delta; - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MD2_CFG, (uint8_t*)&md2_cfg, 1); - - if(ret == 0) { - val->int2_iron = md2_cfg.int2_iron; - val->int2_tilt = md2_cfg.int2_tilt; - val->int2_6d = md2_cfg.int2_6d; - val->int2_double_tap = md2_cfg.int2_double_tap; - val->int2_ff = md2_cfg.int2_ff; - val->int2_wu = md2_cfg.int2_wu; - val->int2_single_tap = md2_cfg.int2_single_tap; - val->int2_inact_state = md2_cfg.int2_inact_state; - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_DRDY_PULSE_CFG_G, (uint8_t*)&drdy_pulse_cfg_g, 1); - val->int2_wrist_tilt = drdy_pulse_cfg_g.int2_wrist_tilt; - } - } - - return ret; -} - -/** - * @brief Push-pull/open drain selection on interrupt pads.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pp_od in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.pp_od = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Push-pull/open drain selection on interrupt pads.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of pp_od in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - switch(ctrl3_c.pp_od) { - case LSM6DS3TR_C_PUSH_PULL: - *val = LSM6DS3TR_C_PUSH_PULL; - break; - - case LSM6DS3TR_C_OPEN_DRAIN: - *val = LSM6DS3TR_C_OPEN_DRAIN; - break; - - default: - *val = LSM6DS3TR_C_PIN_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief Interrupt active-high/low.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of h_lactive in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - if(ret == 0) { - ctrl3_c.h_lactive = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - } - - return ret; -} - -/** - * @brief Interrupt active-high/low.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of h_lactive in reg CTRL3_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pin_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t* val) { - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL3_C, (uint8_t*)&ctrl3_c, 1); - - switch(ctrl3_c.h_lactive) { - case LSM6DS3TR_C_ACTIVE_HIGH: - *val = LSM6DS3TR_C_ACTIVE_HIGH; - break; - - case LSM6DS3TR_C_ACTIVE_LOW: - *val = LSM6DS3TR_C_ACTIVE_LOW; - break; - - default: - *val = LSM6DS3TR_C_POLARITY_ND; - break; - } - - return ret; -} - -/** - * @brief All interrupt signals become available on INT1 pin.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of int2_on_int1 in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_all_on_int1_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ctrl4_c.int2_on_int1 = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - - return ret; -} - -/** - * @brief All interrupt signals become available on INT1 pin.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of int2_on_int1 in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_all_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - *val = ctrl4_c.int2_on_int1; - - return ret; -} - -/** - * @brief Latched/pulsed interrupt.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of lir in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_int_notification_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if(ret == 0) { - tap_cfg.lir = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Latched/pulsed interrupt.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of lir in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_int_notification_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t* val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - switch(tap_cfg.lir) { - case LSM6DS3TR_C_INT_PULSED: - *val = LSM6DS3TR_C_INT_PULSED; - break; - - case LSM6DS3TR_C_INT_LATCHED: - *val = LSM6DS3TR_C_INT_LATCHED; - break; - - default: - *val = LSM6DS3TR_C_INT_MODE; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Wake_Up_event - * @brief This section groups all the functions that manage the - * Wake Up event generation. - * @{ - * - */ - -/** - * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of wk_ths in reg WAKE_UP_THS - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_wkup_threshold_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_wake_up_ths_t wake_up_ths; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); - - if(ret == 0) { - wake_up_ths.wk_ths = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); - } - - return ret; -} - -/** - * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of wk_ths in reg WAKE_UP_THS - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_wkup_threshold_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_wake_up_ths_t wake_up_ths; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); - *val = wake_up_ths.wk_ths; - - return ret; -} - -/** - * @brief Wake up duration event.1LSb = 1 / ODR[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of wake_dur in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_wkup_dur_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - - if(ret == 0) { - wake_up_dur.wake_dur = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - } - - return ret; -} - -/** - * @brief Wake up duration event.1LSb = 1 / ODR[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of wake_dur in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_wkup_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - *val = wake_up_dur.wake_dur; - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Activity/Inactivity_detection - * @brief This section groups all the functions concerning - * activity/inactivity detection. - * @{ - * - */ - -/** - * @brief Enables gyroscope Sleep mode.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sleep in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_sleep_mode_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ctrl4_c.sleep = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - - return ret; -} - -/** - * @brief Enables gyroscope Sleep mode.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sleep in reg CTRL4_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_gy_sleep_mode_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - *val = ctrl4_c.sleep; - - return ret; -} - -/** - * @brief Enable inactivity function.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of inact_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_act_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if(ret == 0) { - tap_cfg.inact_en = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Enable inactivity function.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of inact_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_act_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t* val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - switch(tap_cfg.inact_en) { - case LSM6DS3TR_C_PROPERTY_DISABLE: - *val = LSM6DS3TR_C_PROPERTY_DISABLE; - break; - - case LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED: - *val = LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED; - break; - - case LSM6DS3TR_C_XL_12Hz5_GY_SLEEP: - *val = LSM6DS3TR_C_XL_12Hz5_GY_SLEEP; - break; - - case LSM6DS3TR_C_XL_12Hz5_GY_PD: - *val = LSM6DS3TR_C_XL_12Hz5_GY_PD; - break; - - default: - *val = LSM6DS3TR_C_ACT_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief Duration to go in sleep mode.1 LSb = 512 / ODR[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sleep_dur in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_act_sleep_dur_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - - if(ret == 0) { - wake_up_dur.sleep_dur = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - } - - return ret; -} - -/** - * @brief Duration to go in sleep mode. 1 LSb = 512 / ODR[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sleep_dur in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_act_sleep_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - *val = wake_up_dur.sleep_dur; - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_tap_generator - * @brief This section groups all the functions that manage the - * tap and double tap event generation. - * @{ - * - */ - -/** - * @brief Read the tap / double tap source register.[get] - * - * @param ctx Read / write interface definitions - * @param val Structure of registers from TAP_SRC - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_tap_src_t* val) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_SRC, (uint8_t*)val, 1); - - return ret; -} - -/** - * @brief Enable Z direction in tap recognition.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_z_en in reg TAP_CFG - * - */ -int32_t lsm6ds3tr_c_tap_detection_on_z_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if(ret == 0) { - tap_cfg.tap_z_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Enable Z direction in tap recognition.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_z_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_detection_on_z_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - *val = tap_cfg.tap_z_en; - - return ret; -} - -/** - * @brief Enable Y direction in tap recognition.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_y_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_detection_on_y_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if(ret == 0) { - tap_cfg.tap_y_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Enable Y direction in tap recognition.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_y_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_detection_on_y_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - *val = tap_cfg.tap_y_en; - - return ret; -} - -/** - * @brief Enable X direction in tap recognition.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_x_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_detection_on_x_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - - if(ret == 0) { - tap_cfg.tap_x_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - } - - return ret; -} - -/** - * @brief Enable X direction in tap recognition.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_x_en in reg TAP_CFG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_detection_on_x_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_tap_cfg_t tap_cfg; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_CFG, (uint8_t*)&tap_cfg, 1); - *val = tap_cfg.tap_x_en; - - return ret; -} - -/** - * @brief Threshold for tap recognition.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_ths in reg TAP_THS_6D - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_threshold_x_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - - if(ret == 0) { - tap_ths_6d.tap_ths = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - } - - return ret; -} - -/** - * @brief Threshold for tap recognition.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tap_ths in reg TAP_THS_6D - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_threshold_x_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - *val = tap_ths_6d.tap_ths; - - return ret; -} - -/** - * @brief Maximum duration is the maximum time of an overthreshold signal - * detection to be recognized as a tap event. - * The default value of these bits is 00b which corresponds to - * 4*ODR_XL time. - * If the SHOCK[1:0] bits are set to a different - * value, 1LSB corresponds to 8*ODR_XL time.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of shock in reg INT_DUR2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_shock_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_int_dur2_t int_dur2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - - if(ret == 0) { - int_dur2.shock = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - } - - return ret; -} - -/** - * @brief Maximum duration is the maximum time of an overthreshold signal - * detection to be recognized as a tap event. - * The default value of these bits is 00b which corresponds to - * 4*ODR_XL time. - * If the SHOCK[1:0] bits are set to a different value, 1LSB - * corresponds to 8*ODR_XL time.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of shock in reg INT_DUR2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_shock_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_int_dur2_t int_dur2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - *val = int_dur2.shock; - - return ret; -} - -/** - * @brief Quiet time is the time after the first detected tap in which there - * must not be any overthreshold event. - * The default value of these bits is 00b which corresponds to - * 2*ODR_XL time. - * If the QUIET[1:0] bits are set to a different value, 1LSB - * corresponds to 4*ODR_XL time.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of quiet in reg INT_DUR2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_quiet_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_int_dur2_t int_dur2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - - if(ret == 0) { - int_dur2.quiet = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - } - - return ret; -} - -/** - * @brief Quiet time is the time after the first detected tap in which there - * must not be any overthreshold event. - * The default value of these bits is 00b which corresponds to - * 2*ODR_XL time. - * If the QUIET[1:0] bits are set to a different value, 1LSB - * corresponds to 4*ODR_XL time.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of quiet in reg INT_DUR2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_quiet_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_int_dur2_t int_dur2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - *val = int_dur2.quiet; - - return ret; -} - -/** - * @brief When double tap recognition is enabled, this register expresses the - * maximum time between two consecutive detected taps to determine a - * double tap event. - * The default value of these bits is 0000b which corresponds to - * 16*ODR_XL time. - * If the DUR[3:0] bits are set to a different value,1LSB corresponds - * to 32*ODR_XL time.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of dur in reg INT_DUR2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_dur_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_int_dur2_t int_dur2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - - if(ret == 0) { - int_dur2.dur = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - } - - return ret; -} - -/** - * @brief When double tap recognition is enabled, this register expresses the - * maximum time between two consecutive detected taps to determine a - * double tap event. - * The default value of these bits is 0000b which corresponds to - * 16*ODR_XL time. - * If the DUR[3:0] bits are set to a different value,1LSB corresponds - * to 32*ODR_XL time.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of dur in reg INT_DUR2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_int_dur2_t int_dur2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_INT_DUR2, (uint8_t*)&int_dur2, 1); - *val = int_dur2.dur; - - return ret; -} - -/** - * @brief Single/double-tap event enable/disable.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of - * single_double_tap in reg WAKE_UP_THS - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t val) { - lsm6ds3tr_c_wake_up_ths_t wake_up_ths; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); - - if(ret == 0) { - wake_up_ths.single_double_tap = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); - } - - return ret; -} - -/** - * @brief Single/double-tap event enable/disable.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of single_double_tap - * in reg WAKE_UP_THS - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tap_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t* val) { - lsm6ds3tr_c_wake_up_ths_t wake_up_ths; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_THS, (uint8_t*)&wake_up_ths, 1); - - switch(wake_up_ths.single_double_tap) { - case LSM6DS3TR_C_ONLY_SINGLE: - *val = LSM6DS3TR_C_ONLY_SINGLE; - break; - - case LSM6DS3TR_C_BOTH_SINGLE_DOUBLE: - *val = LSM6DS3TR_C_BOTH_SINGLE_DOUBLE; - break; - - default: - *val = LSM6DS3TR_C_TAP_MODE_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_ Six_position_detection(6D/4D) - * @brief This section groups all the functions concerning six - * position detection (6D). - * @{ - * - */ - -/** - * @brief LPF2 feed 6D function selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of low_pass_on_6d in - * reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_6d_feed_data_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - if(ret == 0) { - ctrl8_xl.low_pass_on_6d = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - } - - return ret; -} - -/** - * @brief LPF2 feed 6D function selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of low_pass_on_6d in reg CTRL8_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_6d_feed_data_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t* val) { - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL8_XL, (uint8_t*)&ctrl8_xl, 1); - - switch(ctrl8_xl.low_pass_on_6d) { - case LSM6DS3TR_C_ODR_DIV_2_FEED: - *val = LSM6DS3TR_C_ODR_DIV_2_FEED; - break; - - case LSM6DS3TR_C_LPF2_FEED: - *val = LSM6DS3TR_C_LPF2_FEED; - break; - - default: - *val = LSM6DS3TR_C_6D_FEED_ND; - break; - } - - return ret; -} - -/** - * @brief Threshold for 4D/6D function.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sixd_ths in reg TAP_THS_6D - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_6d_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t val) { - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - - if(ret == 0) { - tap_ths_6d.sixd_ths = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - } - - return ret; -} - -/** - * @brief Threshold for 4D/6D function.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of sixd_ths in reg TAP_THS_6D - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_6d_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t* val) { - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - - switch(tap_ths_6d.sixd_ths) { - case LSM6DS3TR_C_DEG_80: - *val = LSM6DS3TR_C_DEG_80; - break; - - case LSM6DS3TR_C_DEG_70: - *val = LSM6DS3TR_C_DEG_70; - break; - - case LSM6DS3TR_C_DEG_60: - *val = LSM6DS3TR_C_DEG_60; - break; - - case LSM6DS3TR_C_DEG_50: - *val = LSM6DS3TR_C_DEG_50; - break; - - default: - *val = LSM6DS3TR_C_6D_TH_ND; - break; - } - - return ret; -} - -/** - * @brief 4D orientation detection enable.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of d4d_en in reg TAP_THS_6D - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_4d_mode_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - - if(ret == 0) { - tap_ths_6d.d4d_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - } - - return ret; -} - -/** - * @brief 4D orientation detection enable.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of d4d_en in reg TAP_THS_6D - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_4d_mode_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_TAP_THS_6D, (uint8_t*)&tap_ths_6d, 1); - *val = tap_ths_6d.d4d_en; - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_free_fall - * @brief This section group all the functions concerning the free - * fall detection. - * @{ - * - */ - -/** - * @brief Free-fall duration event. 1LSb = 1 / ODR[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of ff_dur in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_ff_dur_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - lsm6ds3tr_c_free_fall_t free_fall; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); - - if(ret == 0) { - free_fall.ff_dur = (val & 0x1FU); - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - - if(ret == 0) { - wake_up_dur.ff_dur = (val & 0x20U) >> 5; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - } - } - } - - return ret; -} - -/** - * @brief Free-fall duration event. 1LSb = 1 / ODR[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of ff_dur in reg WAKE_UP_DUR - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_ff_dur_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - lsm6ds3tr_c_free_fall_t free_fall; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_WAKE_UP_DUR, (uint8_t*)&wake_up_dur, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); - } - - *val = (wake_up_dur.ff_dur << 5) + free_fall.ff_dur; - - return ret; -} - -/** - * @brief Free fall threshold setting.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of ff_ths in reg FREE_FALL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_ff_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t val) { - lsm6ds3tr_c_free_fall_t free_fall; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); - - if(ret == 0) { - free_fall.ff_ths = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); - } - - return ret; -} - -/** - * @brief Free fall threshold setting.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of ff_ths in reg FREE_FALL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_ff_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t* val) { - lsm6ds3tr_c_free_fall_t free_fall; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FREE_FALL, (uint8_t*)&free_fall, 1); - - switch(free_fall.ff_ths) { - case LSM6DS3TR_C_FF_TSH_156mg: - *val = LSM6DS3TR_C_FF_TSH_156mg; - break; - - case LSM6DS3TR_C_FF_TSH_219mg: - *val = LSM6DS3TR_C_FF_TSH_219mg; - break; - - case LSM6DS3TR_C_FF_TSH_250mg: - *val = LSM6DS3TR_C_FF_TSH_250mg; - break; - - case LSM6DS3TR_C_FF_TSH_312mg: - *val = LSM6DS3TR_C_FF_TSH_312mg; - break; - - case LSM6DS3TR_C_FF_TSH_344mg: - *val = LSM6DS3TR_C_FF_TSH_344mg; - break; - - case LSM6DS3TR_C_FF_TSH_406mg: - *val = LSM6DS3TR_C_FF_TSH_406mg; - break; - - case LSM6DS3TR_C_FF_TSH_469mg: - *val = LSM6DS3TR_C_FF_TSH_469mg; - break; - - case LSM6DS3TR_C_FF_TSH_500mg: - *val = LSM6DS3TR_C_FF_TSH_500mg; - break; - - default: - *val = LSM6DS3TR_C_FF_TSH_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_fifo - * @brief This section group all the functions concerning the - * fifo usage - * @{ - * - */ - -/** - * @brief FIFO watermark level selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fth in reg FIFO_CTRL1 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_watermark_set(stmdev_ctx_t* ctx, uint16_t val) { - lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - - if(ret == 0) { - fifo_ctrl1.fth = (uint8_t)(0x00FFU & val); - fifo_ctrl2.fth = (uint8_t)((0x0700U & val) >> 8); - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL1, (uint8_t*)&fifo_ctrl1, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - } - } - - return ret; -} - -/** - * @brief FIFO watermark level selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fth in reg FIFO_CTRL1 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_watermark_get(stmdev_ctx_t* ctx, uint16_t* val) { - lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL1, (uint8_t*)&fifo_ctrl1, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - } - - *val = ((uint16_t)fifo_ctrl2.fth << 8) + (uint16_t)fifo_ctrl1.fth; - - return ret; -} - -/** - * @brief FIFO data level.[get] - * - * @param ctx Read / write interface definitions - * @param val get the values of diff_fifo in reg FIFO_STATUS1 and - * FIFO_STATUS2(diff_fifo), it is recommended to set the - * BDU bit. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_data_level_get(stmdev_ctx_t* ctx, uint16_t* val) { - lsm6ds3tr_c_fifo_status1_t fifo_status1; - lsm6ds3tr_c_fifo_status2_t fifo_status2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS1, (uint8_t*)&fifo_status1, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS2, (uint8_t*)&fifo_status2, 1); - *val = ((uint16_t)fifo_status2.diff_fifo << 8) + (uint16_t)fifo_status1.diff_fifo; - } - - return ret; -} - -/** - * @brief FIFO watermark.[get] - * - * @param ctx Read / write interface definitions - * @param val get the values of watermark in reg FIFO_STATUS2 and - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_wtm_flag_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_fifo_status2_t fifo_status2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS2, (uint8_t*)&fifo_status2, 1); - *val = fifo_status2.waterm; - - return ret; -} - -/** - * @brief FIFO pattern.[get] - * - * @param ctx Read / write interface definitions - * @param val get the values of fifo_pattern in reg FIFO_STATUS3 and - * FIFO_STATUS4, it is recommended to set the BDU bit - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_pattern_get(stmdev_ctx_t* ctx, uint16_t* val) { - lsm6ds3tr_c_fifo_status3_t fifo_status3; - lsm6ds3tr_c_fifo_status4_t fifo_status4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS3, (uint8_t*)&fifo_status3, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_STATUS4, (uint8_t*)&fifo_status4, 1); - *val = ((uint16_t)fifo_status4.fifo_pattern << 8) + fifo_status3.fifo_pattern; - } - - return ret; -} - -/** - * @brief Batching of temperature data[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fifo_temp_en in reg FIFO_CTRL2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_temp_batch_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - - if(ret == 0) { - fifo_ctrl2.fifo_temp_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - } - - return ret; -} - -/** - * @brief Batching of temperature data[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fifo_temp_en in reg FIFO_CTRL2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_temp_batch_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - *val = fifo_ctrl2.fifo_temp_en; - - return ret; -} - -/** - * @brief Trigger signal for FIFO write operation.[set] - * - * @param ctx Read / write interface definitions - * @param val act on FIFO_CTRL2(timer_pedo_fifo_drdy) - * and MASTER_CONFIG(data_valid_sel_fifo) - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_write_trigger_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t val) { - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - - if(ret == 0) { - fifo_ctrl2.timer_pedo_fifo_drdy = (uint8_t)val & 0x01U; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - - if(ret == 0) { - ret = - lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.data_valid_sel_fifo = (((uint8_t)val & 0x02U) >> 1); - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - } - } - - return ret; -} - -/** - * @brief Trigger signal for FIFO write operation.[get] - * - * @param ctx Read / write interface definitions - * @param val act on FIFO_CTRL2(timer_pedo_fifo_drdy) - * and MASTER_CONFIG(data_valid_sel_fifo) - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_write_trigger_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t* val) { - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - switch((fifo_ctrl2.timer_pedo_fifo_drdy << 1) + fifo_ctrl2.timer_pedo_fifo_drdy) { - case LSM6DS3TR_C_TRG_XL_GY_DRDY: - *val = LSM6DS3TR_C_TRG_XL_GY_DRDY; - break; - - case LSM6DS3TR_C_TRG_STEP_DETECT: - *val = LSM6DS3TR_C_TRG_STEP_DETECT; - break; - - case LSM6DS3TR_C_TRG_SH_DRDY: - *val = LSM6DS3TR_C_TRG_SH_DRDY; - break; - - default: - *val = LSM6DS3TR_C_TRG_SH_ND; - break; - } - } - - return ret; -} - -/** - * @brief Enable pedometer step counter and timestamp as 4th - * FIFO data set.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of timer_pedo_fifo_en in reg FIFO_CTRL2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - - if(ret == 0) { - fifo_ctrl2.timer_pedo_fifo_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - } - - return ret; -} - -/** - * @brief Enable pedometer step counter and timestamp as 4th - * FIFO data set.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of timer_pedo_fifo_en in reg FIFO_CTRL2 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL2, (uint8_t*)&fifo_ctrl2, 1); - *val = fifo_ctrl2.timer_pedo_fifo_en; - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) for - * accelerometer data.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of dec_fifo_xl in reg FIFO_CTRL3 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_xl_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t val) { - lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); - - if(ret == 0) { - fifo_ctrl3.dec_fifo_xl = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) for - * accelerometer data.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of dec_fifo_xl in reg FIFO_CTRL3 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_xl_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t* val) { - lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); - - switch(fifo_ctrl3.dec_fifo_xl) { - case LSM6DS3TR_C_FIFO_XL_DISABLE: - *val = LSM6DS3TR_C_FIFO_XL_DISABLE; - break; - - case LSM6DS3TR_C_FIFO_XL_NO_DEC: - *val = LSM6DS3TR_C_FIFO_XL_NO_DEC; - break; - - case LSM6DS3TR_C_FIFO_XL_DEC_2: - *val = LSM6DS3TR_C_FIFO_XL_DEC_2; - break; - - case LSM6DS3TR_C_FIFO_XL_DEC_3: - *val = LSM6DS3TR_C_FIFO_XL_DEC_3; - break; - - case LSM6DS3TR_C_FIFO_XL_DEC_4: - *val = LSM6DS3TR_C_FIFO_XL_DEC_4; - break; - - case LSM6DS3TR_C_FIFO_XL_DEC_8: - *val = LSM6DS3TR_C_FIFO_XL_DEC_8; - break; - - case LSM6DS3TR_C_FIFO_XL_DEC_16: - *val = LSM6DS3TR_C_FIFO_XL_DEC_16; - break; - - case LSM6DS3TR_C_FIFO_XL_DEC_32: - *val = LSM6DS3TR_C_FIFO_XL_DEC_32; - break; - - default: - *val = LSM6DS3TR_C_FIFO_XL_DEC_ND; - break; - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) - * for gyroscope data.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of dec_fifo_gyro in reg FIFO_CTRL3 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_gy_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t val) { - lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); - - if(ret == 0) { - fifo_ctrl3.dec_fifo_gyro = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) - * for gyroscope data.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of dec_fifo_gyro in reg FIFO_CTRL3 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_gy_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t* val) { - lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL3, (uint8_t*)&fifo_ctrl3, 1); - - switch(fifo_ctrl3.dec_fifo_gyro) { - case LSM6DS3TR_C_FIFO_GY_DISABLE: - *val = LSM6DS3TR_C_FIFO_GY_DISABLE; - break; - - case LSM6DS3TR_C_FIFO_GY_NO_DEC: - *val = LSM6DS3TR_C_FIFO_GY_NO_DEC; - break; - - case LSM6DS3TR_C_FIFO_GY_DEC_2: - *val = LSM6DS3TR_C_FIFO_GY_DEC_2; - break; - - case LSM6DS3TR_C_FIFO_GY_DEC_3: - *val = LSM6DS3TR_C_FIFO_GY_DEC_3; - break; - - case LSM6DS3TR_C_FIFO_GY_DEC_4: - *val = LSM6DS3TR_C_FIFO_GY_DEC_4; - break; - - case LSM6DS3TR_C_FIFO_GY_DEC_8: - *val = LSM6DS3TR_C_FIFO_GY_DEC_8; - break; - - case LSM6DS3TR_C_FIFO_GY_DEC_16: - *val = LSM6DS3TR_C_FIFO_GY_DEC_16; - break; - - case LSM6DS3TR_C_FIFO_GY_DEC_32: - *val = LSM6DS3TR_C_FIFO_GY_DEC_32; - break; - - default: - *val = LSM6DS3TR_C_FIFO_GY_DEC_ND; - break; - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) - * for third data set.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of dec_ds3_fifo in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_dataset_3_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - - if(ret == 0) { - fifo_ctrl4.dec_ds3_fifo = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) - * for third data set.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of dec_ds3_fifo in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_dataset_3_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t* val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - - switch(fifo_ctrl4.dec_ds3_fifo) { - case LSM6DS3TR_C_FIFO_DS3_DISABLE: - *val = LSM6DS3TR_C_FIFO_DS3_DISABLE; - break; - - case LSM6DS3TR_C_FIFO_DS3_NO_DEC: - *val = LSM6DS3TR_C_FIFO_DS3_NO_DEC; - break; - - case LSM6DS3TR_C_FIFO_DS3_DEC_2: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_2; - break; - - case LSM6DS3TR_C_FIFO_DS3_DEC_3: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_3; - break; - - case LSM6DS3TR_C_FIFO_DS3_DEC_4: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_4; - break; - - case LSM6DS3TR_C_FIFO_DS3_DEC_8: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_8; - break; - - case LSM6DS3TR_C_FIFO_DS3_DEC_16: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_16; - break; - - case LSM6DS3TR_C_FIFO_DS3_DEC_32: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_32; - break; - - default: - *val = LSM6DS3TR_C_FIFO_DS3_DEC_ND; - break; - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) - * for fourth data set.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of dec_ds4_fifo in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_dataset_4_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - - if(ret == 0) { - fifo_ctrl4.dec_ds4_fifo = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - } - - return ret; -} - -/** - * @brief Selects Batching Data Rate (writing frequency in FIFO) for - * fourth data set.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of dec_ds4_fifo in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_dataset_4_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t* val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - - switch(fifo_ctrl4.dec_ds4_fifo) { - case LSM6DS3TR_C_FIFO_DS4_DISABLE: - *val = LSM6DS3TR_C_FIFO_DS4_DISABLE; - break; - - case LSM6DS3TR_C_FIFO_DS4_NO_DEC: - *val = LSM6DS3TR_C_FIFO_DS4_NO_DEC; - break; - - case LSM6DS3TR_C_FIFO_DS4_DEC_2: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_2; - break; - - case LSM6DS3TR_C_FIFO_DS4_DEC_3: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_3; - break; - - case LSM6DS3TR_C_FIFO_DS4_DEC_4: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_4; - break; - - case LSM6DS3TR_C_FIFO_DS4_DEC_8: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_8; - break; - - case LSM6DS3TR_C_FIFO_DS4_DEC_16: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_16; - break; - - case LSM6DS3TR_C_FIFO_DS4_DEC_32: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_32; - break; - - default: - *val = LSM6DS3TR_C_FIFO_DS4_DEC_ND; - break; - } - - return ret; -} - -/** - * @brief 8-bit data storage in FIFO.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of only_high_data in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - - if(ret == 0) { - fifo_ctrl4.only_high_data = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - } - - return ret; -} - -/** - * @brief 8-bit data storage in FIFO.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of only_high_data in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - *val = fifo_ctrl4.only_high_data; - - return ret; -} - -/** - * @brief Sensing chain FIFO stop values memorization at threshold - * level.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of stop_on_fth in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_stop_on_wtm_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - - if(ret == 0) { - fifo_ctrl4.stop_on_fth = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - } - - return ret; -} - -/** - * @brief Sensing chain FIFO stop values memorization at threshold - * level.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of stop_on_fth in reg FIFO_CTRL4 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_stop_on_wtm_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL4, (uint8_t*)&fifo_ctrl4, 1); - *val = fifo_ctrl4.stop_on_fth; - - return ret; -} - -/** - * @brief FIFO mode selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of fifo_mode in reg FIFO_CTRL5 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t val) { - lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); - - if(ret == 0) { - fifo_ctrl5.fifo_mode = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); - } - - return ret; -} - -/** - * @brief FIFO mode selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of fifo_mode in reg FIFO_CTRL5 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t* val) { - lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); - - switch(fifo_ctrl5.fifo_mode) { - case LSM6DS3TR_C_BYPASS_MODE: - *val = LSM6DS3TR_C_BYPASS_MODE; - break; - - case LSM6DS3TR_C_FIFO_MODE: - *val = LSM6DS3TR_C_FIFO_MODE; - break; - - case LSM6DS3TR_C_STREAM_TO_FIFO_MODE: - *val = LSM6DS3TR_C_STREAM_TO_FIFO_MODE; - break; - - case LSM6DS3TR_C_BYPASS_TO_STREAM_MODE: - *val = LSM6DS3TR_C_BYPASS_TO_STREAM_MODE; - break; - - case LSM6DS3TR_C_STREAM_MODE: - *val = LSM6DS3TR_C_STREAM_MODE; - break; - - default: - *val = LSM6DS3TR_C_FIFO_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief FIFO ODR selection, setting FIFO_MODE also.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of odr_fifo in reg FIFO_CTRL5 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t val) { - lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); - - if(ret == 0) { - fifo_ctrl5.odr_fifo = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); - } - - return ret; -} - -/** - * @brief FIFO ODR selection, setting FIFO_MODE also.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of odr_fifo in reg FIFO_CTRL5 - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_fifo_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t* val) { - lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_FIFO_CTRL5, (uint8_t*)&fifo_ctrl5, 1); - - switch(fifo_ctrl5.odr_fifo) { - case LSM6DS3TR_C_FIFO_DISABLE: - *val = LSM6DS3TR_C_FIFO_DISABLE; - break; - - case LSM6DS3TR_C_FIFO_12Hz5: - *val = LSM6DS3TR_C_FIFO_12Hz5; - break; - - case LSM6DS3TR_C_FIFO_26Hz: - *val = LSM6DS3TR_C_FIFO_26Hz; - break; - - case LSM6DS3TR_C_FIFO_52Hz: - *val = LSM6DS3TR_C_FIFO_52Hz; - break; - - case LSM6DS3TR_C_FIFO_104Hz: - *val = LSM6DS3TR_C_FIFO_104Hz; - break; - - case LSM6DS3TR_C_FIFO_208Hz: - *val = LSM6DS3TR_C_FIFO_208Hz; - break; - - case LSM6DS3TR_C_FIFO_416Hz: - *val = LSM6DS3TR_C_FIFO_416Hz; - break; - - case LSM6DS3TR_C_FIFO_833Hz: - *val = LSM6DS3TR_C_FIFO_833Hz; - break; - - case LSM6DS3TR_C_FIFO_1k66Hz: - *val = LSM6DS3TR_C_FIFO_1k66Hz; - break; - - case LSM6DS3TR_C_FIFO_3k33Hz: - *val = LSM6DS3TR_C_FIFO_3k33Hz; - break; - - case LSM6DS3TR_C_FIFO_6k66Hz: - *val = LSM6DS3TR_C_FIFO_6k66Hz; - break; - - default: - *val = LSM6DS3TR_C_FIFO_RATE_ND; - break; - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_DEN_functionality - * @brief This section groups all the functions concerning DEN - * functionality. - * @{ - * - */ - -/** - * @brief DEN active level configuration.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_lh in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - if(ret == 0) { - ctrl5_c.den_lh = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - } - - return ret; -} - -/** - * @brief DEN active level configuration.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of den_lh in reg CTRL5_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t* val) { - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL5_C, (uint8_t*)&ctrl5_c, 1); - - switch(ctrl5_c.den_lh) { - case LSM6DS3TR_C_DEN_ACT_LOW: - *val = LSM6DS3TR_C_DEN_ACT_LOW; - break; - - case LSM6DS3TR_C_DEN_ACT_HIGH: - *val = LSM6DS3TR_C_DEN_ACT_HIGH; - break; - - default: - *val = LSM6DS3TR_C_DEN_POL_ND; - break; - } - - return ret; -} - -/** - * @brief DEN functionality marking mode[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_mode in reg CTRL6_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t val) { - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - if(ret == 0) { - ctrl6_c.den_mode = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - } - - return ret; -} - -/** - * @brief DEN functionality marking mode[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_mode in reg CTRL6_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t* val) { - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL6_C, (uint8_t*)&ctrl6_c, 1); - - switch(ctrl6_c.den_mode) { - case LSM6DS3TR_C_DEN_DISABLE: - *val = LSM6DS3TR_C_DEN_DISABLE; - break; - - case LSM6DS3TR_C_LEVEL_LETCHED: - *val = LSM6DS3TR_C_LEVEL_LETCHED; - break; - - case LSM6DS3TR_C_LEVEL_TRIGGER: - *val = LSM6DS3TR_C_LEVEL_TRIGGER; - break; - - case LSM6DS3TR_C_EDGE_TRIGGER: - *val = LSM6DS3TR_C_EDGE_TRIGGER; - break; - - default: - *val = LSM6DS3TR_C_DEN_MODE_ND; - break; - } - - return ret; -} - -/** - * @brief Extend DEN functionality to accelerometer sensor.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_xl_g in reg CTRL9_XL - * and den_xl_en in CTRL4_C. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_enable_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - if(ret == 0) { - ctrl9_xl.den_xl_g = (uint8_t)val & 0x01U; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ctrl4_c.den_xl_en = (uint8_t)val & 0x02U; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - } - } - } - - return ret; -} - -/** - * @brief Extend DEN functionality to accelerometer sensor. [get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of den_xl_g in reg CTRL9_XL - * and den_xl_en in CTRL4_C. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_enable_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t* val) { - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL4_C, (uint8_t*)&ctrl4_c, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - switch((ctrl4_c.den_xl_en << 1) + ctrl9_xl.den_xl_g) { - case LSM6DS3TR_C_STAMP_IN_GY_DATA: - *val = LSM6DS3TR_C_STAMP_IN_GY_DATA; - break; - - case LSM6DS3TR_C_STAMP_IN_XL_DATA: - *val = LSM6DS3TR_C_STAMP_IN_XL_DATA; - break; - - case LSM6DS3TR_C_STAMP_IN_GY_XL_DATA: - *val = LSM6DS3TR_C_STAMP_IN_GY_XL_DATA; - break; - - default: - *val = LSM6DS3TR_C_DEN_STAMP_ND; - break; - } - } - - return ret; -} - -/** - * @brief DEN value stored in LSB of Z-axis.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_z in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mark_axis_z_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - if(ret == 0) { - ctrl9_xl.den_z = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - } - - return ret; -} - -/** - * @brief DEN value stored in LSB of Z-axis.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_z in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mark_axis_z_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - *val = ctrl9_xl.den_z; - - return ret; -} - -/** - * @brief DEN value stored in LSB of Y-axis.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_y in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mark_axis_y_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - if(ret == 0) { - ctrl9_xl.den_y = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - } - - return ret; -} - -/** - * @brief DEN value stored in LSB of Y-axis.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_y in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mark_axis_y_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - *val = ctrl9_xl.den_y; - - return ret; -} - -/** - * @brief DEN value stored in LSB of X-axis.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_x in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mark_axis_x_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - if(ret == 0) { - ctrl9_xl.den_x = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - } - - return ret; -} - -/** - * @brief DEN value stored in LSB of X-axis.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of den_x in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_den_mark_axis_x_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - *val = ctrl9_xl.den_x; - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Pedometer - * @brief This section groups all the functions that manage pedometer. - * @{ - * - */ - -/** - * @brief Reset pedometer step counter.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pedo_rst_step in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_step_reset_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.pedo_rst_step = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - - return ret; -} - -/** - * @brief Reset pedometer step counter.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pedo_rst_step in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_step_reset_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - *val = ctrl10_c.pedo_rst_step; - - return ret; -} - -/** - * @brief Enable pedometer algorithm.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pedo_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_sens_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.pedo_en = val; - - if(val != 0x00U) { - ctrl10_c.func_en = val; - } - - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - - return ret; -} - -/** - * @brief pedo_sens: Enable pedometer algorithm.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pedo_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - *val = ctrl10_c.pedo_en; - - return ret; -} - -/** - * @brief Minimum threshold to detect a peak. Default is 10h.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of ths_min in reg - * CONFIG_PEDO_THS_MIN - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_threshold_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); - - if(ret == 0) { - config_pedo_ths_min.ths_min = val; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Minimum threshold to detect a peak. Default is 10h.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of ths_min in reg CONFIG_PEDO_THS_MIN - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_threshold_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); - - if(ret == 0) { - *val = config_pedo_ths_min.ths_min; - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief pedo_full_scale: Pedometer data range.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pedo_fs in - * reg CONFIG_PEDO_THS_MIN - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t val) { - lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); - - if(ret == 0) { - config_pedo_ths_min.pedo_fs = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Pedometer data range.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of pedo_fs in - * reg CONFIG_PEDO_THS_MIN - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t* val) { - lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_CONFIG_PEDO_THS_MIN, (uint8_t*)&config_pedo_ths_min, 1); - - if(ret == 0) { - switch(config_pedo_ths_min.pedo_fs) { - case LSM6DS3TR_C_PEDO_AT_2g: - *val = LSM6DS3TR_C_PEDO_AT_2g; - break; - - case LSM6DS3TR_C_PEDO_AT_4g: - *val = LSM6DS3TR_C_PEDO_AT_4g; - break; - - default: - *val = LSM6DS3TR_C_PEDO_FS_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Pedometer debounce configuration register (r/w).[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of deb_step in reg PEDO_DEB_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_debounce_steps_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); - - if(ret == 0) { - pedo_deb_reg.deb_step = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Pedometer debounce configuration register (r/w).[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of deb_step in reg PEDO_DEB_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_debounce_steps_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); - - if(ret == 0) { - *val = pedo_deb_reg.deb_step; - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Debounce time. If the time between two consecutive steps is - * greater than DEB_TIME*80ms, the debouncer is reactivated. - * Default value: 01101[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of deb_time in reg PEDO_DEB_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_timeout_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); - - if(ret == 0) { - pedo_deb_reg.deb_time = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Debounce time. If the time between two consecutive steps is - * greater than DEB_TIME*80ms, the debouncer is reactivated. - * Default value: 01101[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of deb_time in reg PEDO_DEB_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_timeout_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_PEDO_DEB_REG, (uint8_t*)&pedo_deb_reg, 1); - - if(ret == 0) { - *val = pedo_deb_reg.deb_time; - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Time period register for step detection on delta time (r/w).[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that contains data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_steps_period_set(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_STEP_COUNT_DELTA, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Time period register for step detection on delta time (r/w).[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_pedo_steps_period_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_STEP_COUNT_DELTA, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_significant_motion - * @brief This section groups all the functions that manage the - * significant motion detection. - * @{ - * - */ - -/** - * @brief Enable significant motion detection function.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sign_motion_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_motion_sens_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.sign_motion_en = val; - - if(val != 0x00U) { - ctrl10_c.func_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - } - - return ret; -} - -/** - * @brief Enable significant motion detection function.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of sign_motion_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_motion_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - *val = ctrl10_c.sign_motion_en; - - return ret; -} - -/** - * @brief Significant motion threshold.[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that store significant motion threshold. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_motion_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SM_THS, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Significant motion threshold.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that store significant motion threshold. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_motion_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SM_THS, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_tilt_detection - * @brief This section groups all the functions that manage the tilt - * event detection. - * @{ - * - */ - -/** - * @brief Enable tilt calculation.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tilt_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.tilt_en = val; - - if(val != 0x00U) { - ctrl10_c.func_en = val; - } - - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - - return ret; -} - -/** - * @brief Enable tilt calculation.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tilt_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - *val = ctrl10_c.tilt_en; - - return ret; -} - -/** - * @brief Enable tilt calculation.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tilt_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_wrist_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.wrist_tilt_en = val; - - if(val != 0x00U) { - ctrl10_c.func_en = val; - } - - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - - return ret; -} - -/** - * @brief Enable tilt calculation.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tilt_en in reg CTRL10_C - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_wrist_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - *val = ctrl10_c.wrist_tilt_en; - - return ret; -} - -/** - * @brief Absolute Wrist Tilt latency register (r/w). - * Absolute wrist tilt latency parameters. - * 1 LSB = 40 ms. Default value: 0Fh (600 ms).[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that contains data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_latency_set(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_LAT, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Absolute Wrist Tilt latency register (r/w). - * Absolute wrist tilt latency parameters. - * 1 LSB = 40 ms. Default value: 0Fh (600 ms).[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_latency_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_LAT, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Absolute Wrist Tilt threshold register(r/w). - * Absolute wrist tilt threshold parameters. - * 1 LSB = 15.625 mg.Default value: 20h (500 mg).[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that contains data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_THS, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Absolute Wrist Tilt threshold register(r/w). - * Absolute wrist tilt threshold parameters. - * 1 LSB = 15.625 mg.Default value: 20h (500 mg).[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_THS, buff, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Absolute Wrist Tilt mask register (r/w).[set] - * - * @param ctx Read / write interface definitions - * @param val Registers A_WRIST_TILT_MASK - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_src_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, (uint8_t*)val, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Absolute Wrist Tilt mask register (r/w).[get] - * - * @param ctx Read / write interface definitions - * @param val Registers A_WRIST_TILT_MASK - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_tilt_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_B); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_A_WRIST_TILT_MASK, (uint8_t*)val, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_ magnetometer_sensor - * @brief This section groups all the functions that manage additional - * magnetometer sensor. - * @{ - * - */ - -/** - * @brief Enable soft-iron correction algorithm for magnetometer.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of soft_en in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_soft_iron_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - - if(ret == 0) { - ctrl9_xl.soft_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - } - - return ret; -} - -/** - * @brief Enable soft-iron correction algorithm for magnetometer.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of soft_en in reg CTRL9_XL - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_soft_iron_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL9_XL, (uint8_t*)&ctrl9_xl, 1); - *val = ctrl9_xl.soft_en; - - return ret; -} - -/** - * @brief Enable hard-iron correction algorithm for magnetometer.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of iron_en in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_hard_iron_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_master_config_t master_config; - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.iron_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - if(val != 0x00U) { - ctrl10_c.func_en = val; - } - - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - } - } - - return ret; -} - -/** - * @brief Enable hard-iron correction algorithm for magnetometer.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of iron_en in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_hard_iron_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - *val = master_config.iron_en; - - return ret; -} - -/** - * @brief Soft iron 3x3 matrix. Value are expressed in sign-module format. - * (Es. SVVVVVVVb where S is the sign 0/+1/- and V is the value).[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that contains data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_soft_iron_mat_set(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MAG_SI_XX, buff, 9); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Soft iron 3x3 matrix. Value are expressed in sign-module format. - * (Es. SVVVVVVVb where S is the sign 0/+1/- and V is the value).[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_soft_iron_mat_get(stmdev_ctx_t* ctx, uint8_t* buff) { - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MAG_SI_XX, buff, 9); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Offset for hard-iron compensation register (r/w). The value is - * expressed as a 16-bit word in two’s complement.[set] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that contains data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_offset_set(stmdev_ctx_t* ctx, int16_t* val) { - uint8_t buff[6]; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - buff[1] = (uint8_t)((uint16_t)val[0] / 256U); - buff[0] = (uint8_t)((uint16_t)val[0] - (buff[1] * 256U)); - buff[3] = (uint8_t)((uint16_t)val[1] / 256U); - buff[2] = (uint8_t)((uint16_t)val[1] - (buff[3] * 256U)); - buff[5] = (uint8_t)((uint16_t)val[2] / 256U); - buff[4] = (uint8_t)((uint16_t)val[2] - (buff[5] * 256U)); - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MAG_OFFX_L, buff, 6); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Offset for hard-iron compensation register(r/w). - * The value is expressed as a 16-bit word in two’s complement.[get] - * - * @param ctx Read / write interface definitions - * @param buff Buffer that stores data read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_mag_offset_get(stmdev_ctx_t* ctx, int16_t* val) { - uint8_t buff[6]; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MAG_OFFX_L, buff, 6); - - if(ret == 0) { - val[0] = (int16_t)buff[1]; - val[0] = (val[0] * 256) + (int16_t)buff[0]; - val[1] = (int16_t)buff[3]; - val[1] = (val[1] * 256) + (int16_t)buff[2]; - val[2] = (int16_t)buff[5]; - val[2] = (val[2] * 256) + (int16_t)buff[4]; - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @defgroup LSM6DS3TR_C_Sensor_hub - * @brief This section groups all the functions that manage the sensor - * hub functionality. - * @{ - * - */ - -/** - * @brief Enable function.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values func_en - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_func_en_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - - if(ret == 0) { - ctrl10_c.func_en = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_CTRL10_C, (uint8_t*)&ctrl10_c, 1); - } - - return ret; -} - -/** - * @brief Sensor synchronization time frame with the step of 500 ms and - * full range of 5s. Unsigned 8-bit.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tph in reg SENSOR_SYNC_TIME_FRAME - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_sync_sens_frame_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, (uint8_t*)&sensor_sync_time_frame, 1); - - if(ret == 0) { - sensor_sync_time_frame.tph = val; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, (uint8_t*)&sensor_sync_time_frame, 1); - } - - return ret; -} - -/** - * @brief Sensor synchronization time frame with the step of 500 ms and - * full range of 5s. Unsigned 8-bit.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of tph in reg SENSOR_SYNC_TIME_FRAME - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_sync_sens_frame_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME, (uint8_t*)&sensor_sync_time_frame, 1); - *val = sensor_sync_time_frame.tph; - - return ret; -} - -/** - * @brief Resolution ratio of error code for sensor synchronization.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of rr in reg SENSOR_SYNC_RES_RATIO - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_sync_sens_ratio_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t val) { - lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, (uint8_t*)&sensor_sync_res_ratio, 1); - - if(ret == 0) { - sensor_sync_res_ratio.rr = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, (uint8_t*)&sensor_sync_res_ratio, 1); - } - - return ret; -} - -/** - * @brief Resolution ratio of error code for sensor synchronization.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of rr in reg SENSOR_SYNC_RES_RATIO - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_sync_sens_ratio_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t* val) { - lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO, (uint8_t*)&sensor_sync_res_ratio, 1); - - switch(sensor_sync_res_ratio.rr) { - case LSM6DS3TR_C_RES_RATIO_2_11: - *val = LSM6DS3TR_C_RES_RATIO_2_11; - break; - - case LSM6DS3TR_C_RES_RATIO_2_12: - *val = LSM6DS3TR_C_RES_RATIO_2_12; - break; - - case LSM6DS3TR_C_RES_RATIO_2_13: - *val = LSM6DS3TR_C_RES_RATIO_2_13; - break; - - case LSM6DS3TR_C_RES_RATIO_2_14: - *val = LSM6DS3TR_C_RES_RATIO_2_14; - break; - - default: - *val = LSM6DS3TR_C_RES_RATIO_ND; - break; - } - - return ret; -} - -/** - * @brief Sensor hub I2C master enable.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of master_on in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_master_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.master_on = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - return ret; -} - -/** - * @brief Sensor hub I2C master enable.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of master_on in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_master_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - *val = master_config.master_on; - - return ret; -} - -/** - * @brief I2C interface pass-through.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pass_through_mode in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_pass_through_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.pass_through_mode = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - return ret; -} - -/** - * @brief I2C interface pass-through.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pass_through_mode in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_pass_through_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - *val = master_config.pass_through_mode; - - return ret; -} - -/** - * @brief Master I2C pull-up enable/disable.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of pull_up_en in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.pull_up_en = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - return ret; -} - -/** - * @brief Master I2C pull-up enable/disable.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of pull_up_en in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t* val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - switch(master_config.pull_up_en) { - case LSM6DS3TR_C_EXT_PULL_UP: - *val = LSM6DS3TR_C_EXT_PULL_UP; - break; - - case LSM6DS3TR_C_INTERNAL_PULL_UP: - *val = LSM6DS3TR_C_INTERNAL_PULL_UP; - break; - - default: - *val = LSM6DS3TR_C_SH_PIN_MODE; - break; - } - - return ret; -} - -/** - * @brief Sensor hub trigger signal selection.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of start_config in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_syncro_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.start_config = (uint8_t)val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - return ret; -} - -/** - * @brief Sensor hub trigger signal selection.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of start_config in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_syncro_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t* val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - switch(master_config.start_config) { - case LSM6DS3TR_C_XL_GY_DRDY: - *val = LSM6DS3TR_C_XL_GY_DRDY; - break; - - case LSM6DS3TR_C_EXT_ON_INT2_PIN: - *val = LSM6DS3TR_C_EXT_ON_INT2_PIN; - break; - - default: - *val = LSM6DS3TR_C_SH_SYNCRO_ND; - break; - } - - return ret; -} - -/** - * @brief Manage the Master DRDY signal on INT1 pad.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of drdy_on_int1 in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_drdy_on_int1_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - - if(ret == 0) { - master_config.drdy_on_int1 = val; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - } - - return ret; -} - -/** - * @brief Manage the Master DRDY signal on INT1 pad.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of drdy_on_int1 in reg MASTER_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_drdy_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_master_config_t master_config; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CONFIG, (uint8_t*)&master_config, 1); - *val = master_config.drdy_on_int1; - - return ret; -} - -/** - * @brief Sensor hub output registers.[get] - * - * @param ctx Read / write interface definitions - * @param val Structure of registers from SENSORHUB1_REG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_read_data_raw_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_emb_sh_read_t* val) { - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SENSORHUB1_REG, (uint8_t*)&(val->sh_byte_1), 12); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENSORHUB13_REG, (uint8_t*)&(val->sh_byte_13), 6); - } - - return ret; -} - -/** - * @brief Master command code used for stamping for sensor sync.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of master_cmd_code in - * reg MASTER_CMD_CODE - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_cmd_sens_sync_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_master_cmd_code_t master_cmd_code; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, (uint8_t*)&master_cmd_code, 1); - - if(ret == 0) { - master_cmd_code.master_cmd_code = val; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, (uint8_t*)&master_cmd_code, 1); - } - - return ret; -} - -/** - * @brief Master command code used for stamping for sensor sync.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of master_cmd_code in - * reg MASTER_CMD_CODE - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_cmd_sens_sync_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_master_cmd_code_t master_cmd_code; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_MASTER_CMD_CODE, (uint8_t*)&master_cmd_code, 1); - *val = master_cmd_code.master_cmd_code; - - return ret; -} - -/** - * @brief Error code used for sensor synchronization.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of error_code in - * reg SENS_SYNC_SPI_ERROR_CODE. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_spi_sync_error_set(stmdev_ctx_t* ctx, uint8_t val) { - lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, (uint8_t*)&sens_sync_spi_error_code, 1); - - if(ret == 0) { - sens_sync_spi_error_code.error_code = val; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, (uint8_t*)&sens_sync_spi_error_code, 1); - } - - return ret; -} - -/** - * @brief Error code used for sensor synchronization.[get] - * - * @param ctx Read / write interface definitions - * @param val Change the values of error_code in - * reg SENS_SYNC_SPI_ERROR_CODE. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_spi_sync_error_get(stmdev_ctx_t* ctx, uint8_t* val) { - lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; - int32_t ret; - - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE, (uint8_t*)&sens_sync_spi_error_code, 1); - *val = sens_sync_spi_error_code.error_code; - - return ret; -} - -/** - * @brief Number of external sensors to be read by the sensor hub.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of aux_sens_on in reg SLAVE0_CONFIG. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_num_of_dev_connected_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t val) { - lsm6ds3tr_c_slave0_config_t slave0_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - slave0_config.aux_sens_on = (uint8_t)val; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Number of external sensors to be read by the sensor hub.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of aux_sens_on in reg SLAVE0_CONFIG. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t - lsm6ds3tr_c_sh_num_of_dev_connected_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t* val) { - lsm6ds3tr_c_slave0_config_t slave0_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - switch(slave0_config.aux_sens_on) { - case LSM6DS3TR_C_SLV_0: - *val = LSM6DS3TR_C_SLV_0; - break; - - case LSM6DS3TR_C_SLV_0_1: - *val = LSM6DS3TR_C_SLV_0_1; - break; - - case LSM6DS3TR_C_SLV_0_1_2: - *val = LSM6DS3TR_C_SLV_0_1_2; - break; - - case LSM6DS3TR_C_SLV_0_1_2_3: - *val = LSM6DS3TR_C_SLV_0_1_2_3; - break; - - default: - *val = LSM6DS3TR_C_SLV_EN_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Configure slave 0 for perform a write.[set] - * - * @param ctx Read / write interface definitions - * @param val Structure that contain: - * - uint8_t slv_add; 8 bit i2c device address - * - uint8_t slv_subadd; 8 bit register device address - * - uint8_t slv_data; 8 bit data to write - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_cfg_write(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_write_t* val) { - lsm6ds3tr_c_slv0_add_t slv0_add; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - slv0_add.slave0_add = val->slv0_add; - slv0_add.rw_0 = 0; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_ADD, (uint8_t*)&slv0_add, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_SUBADD, &(val->slv0_subadd), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_DATAWRITE_SRC_MODE_SUB_SLV0, &(val->slv0_data), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - } - - return ret; -} - -/** - * @brief Configure slave 0 for perform a read.[get] - * - * @param ctx Read / write interface definitions - * @param val Structure that contain: - * - uint8_t slv_add; 8 bit i2c device address - * - uint8_t slv_subadd; 8 bit register device address - * - uint8_t slv_len; num of bit to read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slv0_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { - lsm6ds3tr_c_slave0_config_t slave0_config; - lsm6ds3tr_c_slv0_add_t slv0_add; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - slv0_add.slave0_add = val->slv_add; - slv0_add.rw_0 = 1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_ADD, (uint8_t*)&slv0_add, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV0_SUBADD, &(val->slv_subadd), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - slave0_config.slave0_numop = val->slv_len; - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - } - } - - return ret; -} - -/** - * @brief Configure slave 1 for perform a read.[get] - * - * @param ctx Read / write interface definitions - * @param val Structure that contain: - * - uint8_t slv_add; 8 bit i2c device address - * - uint8_t slv_subadd; 8 bit register device address - * - uint8_t slv_len; num of bit to read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slv1_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { - lsm6ds3tr_c_slave1_config_t slave1_config; - lsm6ds3tr_c_slv1_add_t slv1_add; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - slv1_add.slave1_add = val->slv_add; - slv1_add.r_1 = 1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV1_ADD, (uint8_t*)&slv1_add, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV1_SUBADD, &(val->slv_subadd), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - slave1_config.slave1_numop = val->slv_len; - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - } - } - - return ret; -} - -/** - * @brief Configure slave 2 for perform a read.[get] - * - * @param ctx Read / write interface definitions - * @param val Structure that contain: - * - uint8_t slv_add; 8 bit i2c device address - * - uint8_t slv_subadd; 8 bit register device address - * - uint8_t slv_len; num of bit to read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slv2_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { - lsm6ds3tr_c_slv2_add_t slv2_add; - lsm6ds3tr_c_slave2_config_t slave2_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - slv2_add.slave2_add = val->slv_add; - slv2_add.r_2 = 1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV2_ADD, (uint8_t*)&slv2_add, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV2_SUBADD, &(val->slv_subadd), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); - - if(ret == 0) { - slave2_config.slave2_numop = val->slv_len; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - } - } - - return ret; -} - -/** - * @brief Configure slave 3 for perform a read.[get] - * - * @param ctx Read / write interface definitions - * @param val Structure that contain: - * - uint8_t slv_add; 8 bit i2c device address - * - uint8_t slv_subadd; 8 bit register device address - * - uint8_t slv_len; num of bit to read - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slv3_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val) { - lsm6ds3tr_c_slave3_config_t slave3_config; - lsm6ds3tr_c_slv3_add_t slv3_add; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - slv3_add.slave3_add = val->slv_add; - slv3_add.r_3 = 1; - ret = lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLV3_ADD, (uint8_t*)&slv3_add, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SLV3_SUBADD, (uint8_t*)&(val->slv_subadd), 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg( - ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); - - if(ret == 0) { - slave3_config.slave3_numop = val->slv_len; - ret = lsm6ds3tr_c_write_reg( - ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 0 starting from the - * sensor hub trigger.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of slave0_rate in reg SLAVE0_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_0_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t val) { - lsm6ds3tr_c_slave0_config_t slave0_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - slave0_config.slave0_rate = (uint8_t)val; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 0 starting from the - * sensor hub trigger.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of slave0_rate in reg SLAVE0_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_0_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t* val) { - lsm6ds3tr_c_slave0_config_t slave0_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE0_CONFIG, (uint8_t*)&slave0_config, 1); - - if(ret == 0) { - switch(slave0_config.slave0_rate) { - case LSM6DS3TR_C_SL0_NO_DEC: - *val = LSM6DS3TR_C_SL0_NO_DEC; - break; - - case LSM6DS3TR_C_SL0_DEC_2: - *val = LSM6DS3TR_C_SL0_DEC_2; - break; - - case LSM6DS3TR_C_SL0_DEC_4: - *val = LSM6DS3TR_C_SL0_DEC_4; - break; - - case LSM6DS3TR_C_SL0_DEC_8: - *val = LSM6DS3TR_C_SL0_DEC_8; - break; - - default: - *val = LSM6DS3TR_C_SL0_DEC_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Slave 0 write operation is performed only at the first sensor - * hub cycle. - * This is effective if the Aux_sens_on[1:0] field in - * SLAVE0_CONFIG(04h) is set to a value other than 00.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of write_once in reg SLAVE1_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_write_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t val) { - lsm6ds3tr_c_slave1_config_t slave1_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - slave1_config.write_once = (uint8_t)val; - - if(ret == 0) { - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Slave 0 write operation is performed only at the first sensor - * hub cycle. - * This is effective if the Aux_sens_on[1:0] field in - * SLAVE0_CONFIG(04h) is set to a value other than 00.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of write_once in reg SLAVE1_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_write_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t* val) { - lsm6ds3tr_c_slave1_config_t slave1_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - - if(ret == 0) { - switch(slave1_config.write_once) { - case LSM6DS3TR_C_EACH_SH_CYCLE: - *val = LSM6DS3TR_C_EACH_SH_CYCLE; - break; - - case LSM6DS3TR_C_ONLY_FIRST_CYCLE: - *val = LSM6DS3TR_C_ONLY_FIRST_CYCLE; - break; - - default: - *val = LSM6DS3TR_C_SH_WR_MODE_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 1 starting from the - * sensor hub trigger.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of slave1_rate in reg SLAVE1_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_1_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t val) { - lsm6ds3tr_c_slave1_config_t slave1_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - - if(ret == 0) { - slave1_config.slave1_rate = (uint8_t)val; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 1 starting from the - * sensor hub trigger.[get] - * - * @param ctx Read / write interface definitions reg SLAVE1_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_1_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t* val) { - lsm6ds3tr_c_slave1_config_t slave1_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE1_CONFIG, (uint8_t*)&slave1_config, 1); - - if(ret == 0) { - switch(slave1_config.slave1_rate) { - case LSM6DS3TR_C_SL1_NO_DEC: - *val = LSM6DS3TR_C_SL1_NO_DEC; - break; - - case LSM6DS3TR_C_SL1_DEC_2: - *val = LSM6DS3TR_C_SL1_DEC_2; - break; - - case LSM6DS3TR_C_SL1_DEC_4: - *val = LSM6DS3TR_C_SL1_DEC_4; - break; - - case LSM6DS3TR_C_SL1_DEC_8: - *val = LSM6DS3TR_C_SL1_DEC_8; - break; - - default: - *val = LSM6DS3TR_C_SL1_DEC_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 2 starting from the - * sensor hub trigger.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of slave2_rate in reg SLAVE2_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_2_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t val) { - lsm6ds3tr_c_slave2_config_t slave2_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); - - if(ret == 0) { - slave2_config.slave2_rate = (uint8_t)val; - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 2 starting from the - * sensor hub trigger.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of slave2_rate in reg SLAVE2_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_2_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t* val) { - lsm6ds3tr_c_slave2_config_t slave2_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE2_CONFIG, (uint8_t*)&slave2_config, 1); - - if(ret == 0) { - switch(slave2_config.slave2_rate) { - case LSM6DS3TR_C_SL2_NO_DEC: - *val = LSM6DS3TR_C_SL2_NO_DEC; - break; - - case LSM6DS3TR_C_SL2_DEC_2: - *val = LSM6DS3TR_C_SL2_DEC_2; - break; - - case LSM6DS3TR_C_SL2_DEC_4: - *val = LSM6DS3TR_C_SL2_DEC_4; - break; - - case LSM6DS3TR_C_SL2_DEC_8: - *val = LSM6DS3TR_C_SL2_DEC_8; - break; - - default: - *val = LSM6DS3TR_C_SL2_DEC_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 3 starting from the - * sensor hub trigger.[set] - * - * @param ctx Read / write interface definitions - * @param val Change the values of slave3_rate in reg SLAVE3_CONFIG - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_3_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t val) { - lsm6ds3tr_c_slave3_config_t slave3_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); - slave3_config.slave3_rate = (uint8_t)val; - - if(ret == 0) { - ret = - lsm6ds3tr_c_write_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); - - if(ret == 0) { - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - } - - return ret; -} - -/** - * @brief Decimation of read operation on Slave 3 starting from the - * sensor hub trigger.[get] - * - * @param ctx Read / write interface definitions - * @param val Get the values of slave3_rate in reg SLAVE3_CONFIG. - * @retval Interface status (MANDATORY: return 0 -> no Error). - * - */ -int32_t lsm6ds3tr_c_sh_slave_3_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t* val) { - lsm6ds3tr_c_slave3_config_t slave3_config; - int32_t ret; - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_BANK_A); - - if(ret == 0) { - ret = lsm6ds3tr_c_read_reg(ctx, LSM6DS3TR_C_SLAVE3_CONFIG, (uint8_t*)&slave3_config, 1); - - if(ret == 0) { - switch(slave3_config.slave3_rate) { - case LSM6DS3TR_C_SL3_NO_DEC: - *val = LSM6DS3TR_C_SL3_NO_DEC; - break; - - case LSM6DS3TR_C_SL3_DEC_2: - *val = LSM6DS3TR_C_SL3_DEC_2; - break; - - case LSM6DS3TR_C_SL3_DEC_4: - *val = LSM6DS3TR_C_SL3_DEC_4; - break; - - case LSM6DS3TR_C_SL3_DEC_8: - *val = LSM6DS3TR_C_SL3_DEC_8; - break; - - default: - *val = LSM6DS3TR_C_SL3_DEC_ND; - break; - } - - ret = lsm6ds3tr_c_mem_bank_set(ctx, LSM6DS3TR_C_USER_BANK); - } - } - - return ret; -} - -/** - * @} - * - */ - -/** - * @} - * - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.h b/non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.h deleted file mode 100644 index 8cb592c0da3..00000000000 --- a/non_catalog_apps/airmouse/tracking/imu/lsm6ds3tr_c_reg.h +++ /dev/null @@ -1,2448 +0,0 @@ -/** - ****************************************************************************** - * @file lsm6ds3tr_c_reg.h - * @author Sensors Software Solution Team - * @brief This file contains all the functions prototypes for the - * lsm6ds3tr_c_reg.c driver. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef LSM6DS3TR_C_DRIVER_H -#define LSM6DS3TR_C_DRIVER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include -#include -#include - -/** @addtogroup LSM6DS3TR_C - * @{ - * - */ - -/** @defgroup Endianness definitions - * @{ - * - */ - -#ifndef DRV_BYTE_ORDER -#ifndef __BYTE_ORDER__ - -#define DRV_LITTLE_ENDIAN 1234 -#define DRV_BIG_ENDIAN 4321 - -/** if _BYTE_ORDER is not defined, choose the endianness of your architecture - * by uncommenting the define which fits your platform endianness - */ -//#define DRV_BYTE_ORDER DRV_BIG_ENDIAN -#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN - -#else /* defined __BYTE_ORDER__ */ - -#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ -#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__ -#define DRV_BYTE_ORDER __BYTE_ORDER__ - -#endif /* __BYTE_ORDER__*/ -#endif /* DRV_BYTE_ORDER */ - -/** - * @} - * - */ - -/** @defgroup STMicroelectronics sensors common types - * @{ - * - */ - -#ifndef MEMS_SHARED_TYPES -#define MEMS_SHARED_TYPES - -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} bitwise_t; - -#define PROPERTY_DISABLE (0U) -#define PROPERTY_ENABLE (1U) - -/** @addtogroup Interfaces_Functions - * @brief This section provide a set of functions used to read and - * write a generic register of the device. - * MANDATORY: return 0 -> no Error. - * @{ - * - */ - -typedef int32_t (*stmdev_write_ptr)(void*, uint8_t, const uint8_t*, uint16_t); -typedef int32_t (*stmdev_read_ptr)(void*, uint8_t, uint8_t*, uint16_t); -typedef void (*stmdev_mdelay_ptr)(uint32_t millisec); - -typedef struct { - /** Component mandatory fields **/ - stmdev_write_ptr write_reg; - stmdev_read_ptr read_reg; - /** Component optional fields **/ - stmdev_mdelay_ptr mdelay; - /** Customizable optional pointer **/ - void* handle; -} stmdev_ctx_t; - -/** - * @} - * - */ - -#endif /* MEMS_SHARED_TYPES */ - -#ifndef MEMS_UCF_SHARED_TYPES -#define MEMS_UCF_SHARED_TYPES - -/** @defgroup Generic address-data structure definition - * @brief This structure is useful to load a predefined configuration - * of a sensor. - * You can create a sensor configuration by your own or using - * Unico / Unicleo tools available on STMicroelectronics - * web site. - * - * @{ - * - */ - -typedef struct { - uint8_t address; - uint8_t data; -} ucf_line_t; - -/** - * @} - * - */ - -#endif /* MEMS_UCF_SHARED_TYPES */ - -/** - * @} - * - */ - -/** @defgroup LSM6DS3TR_C_Infos - * @{ - * - */ - -/** I2C Device Address 8 bit format if SA0=0 -> D5 if SA0=1 -> D7 **/ -#define LSM6DS3TR_C_I2C_ADD_L 0xD5U -#define LSM6DS3TR_C_I2C_ADD_H 0xD7U - -/** Device Identification (Who am I) **/ -#define LSM6DS3TR_C_ID 0x6AU - -/** - * @} - * - */ - -#define LSM6DS3TR_C_FUNC_CFG_ACCESS 0x01U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 5; - uint8_t func_cfg_en : 3; /* func_cfg_en + func_cfg_en_b */ -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t func_cfg_en : 3; /* func_cfg_en + func_cfg_en_b */ - uint8_t not_used_01 : 5; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_func_cfg_access_t; - -#define LSM6DS3TR_C_SENSOR_SYNC_TIME_FRAME 0x04U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t tph : 4; - uint8_t not_used_01 : 4; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 4; - uint8_t tph : 4; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensor_sync_time_frame_t; - -#define LSM6DS3TR_C_SENSOR_SYNC_RES_RATIO 0x05U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t rr : 2; - uint8_t not_used_01 : 6; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 6; - uint8_t rr : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensor_sync_res_ratio_t; - -#define LSM6DS3TR_C_FIFO_CTRL1 0x06U -typedef struct { - uint8_t fth : 8; /* + FIFO_CTRL2(fth) */ -} lsm6ds3tr_c_fifo_ctrl1_t; - -#define LSM6DS3TR_C_FIFO_CTRL2 0x07U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t fth : 3; /* + FIFO_CTRL1(fth) */ - uint8_t fifo_temp_en : 1; - uint8_t not_used_01 : 2; - uint8_t timer_pedo_fifo_drdy : 1; - uint8_t timer_pedo_fifo_en : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t timer_pedo_fifo_en : 1; - uint8_t timer_pedo_fifo_drdy : 1; - uint8_t not_used_01 : 2; - uint8_t fifo_temp_en : 1; - uint8_t fth : 3; /* + FIFO_CTRL1(fth) */ -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_fifo_ctrl2_t; - -#define LSM6DS3TR_C_FIFO_CTRL3 0x08U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t dec_fifo_xl : 3; - uint8_t dec_fifo_gyro : 3; - uint8_t not_used_01 : 2; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 2; - uint8_t dec_fifo_gyro : 3; - uint8_t dec_fifo_xl : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_fifo_ctrl3_t; - -#define LSM6DS3TR_C_FIFO_CTRL4 0x09U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t dec_ds3_fifo : 3; - uint8_t dec_ds4_fifo : 3; - uint8_t only_high_data : 1; - uint8_t stop_on_fth : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t stop_on_fth : 1; - uint8_t only_high_data : 1; - uint8_t dec_ds4_fifo : 3; - uint8_t dec_ds3_fifo : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_fifo_ctrl4_t; - -#define LSM6DS3TR_C_FIFO_CTRL5 0x0AU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t fifo_mode : 3; - uint8_t odr_fifo : 4; - uint8_t not_used_01 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 1; - uint8_t odr_fifo : 4; - uint8_t fifo_mode : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_fifo_ctrl5_t; - -#define LSM6DS3TR_C_DRDY_PULSE_CFG_G 0x0BU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t int2_wrist_tilt : 1; - uint8_t not_used_01 : 6; - uint8_t drdy_pulsed : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t drdy_pulsed : 1; - uint8_t not_used_01 : 6; - uint8_t int2_wrist_tilt : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_drdy_pulse_cfg_g_t; - -#define LSM6DS3TR_C_INT1_CTRL 0x0DU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t int1_drdy_xl : 1; - uint8_t int1_drdy_g : 1; - uint8_t int1_boot : 1; - uint8_t int1_fth : 1; - uint8_t int1_fifo_ovr : 1; - uint8_t int1_full_flag : 1; - uint8_t int1_sign_mot : 1; - uint8_t int1_step_detector : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t int1_step_detector : 1; - uint8_t int1_sign_mot : 1; - uint8_t int1_full_flag : 1; - uint8_t int1_fifo_ovr : 1; - uint8_t int1_fth : 1; - uint8_t int1_boot : 1; - uint8_t int1_drdy_g : 1; - uint8_t int1_drdy_xl : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_int1_ctrl_t; - -#define LSM6DS3TR_C_INT2_CTRL 0x0EU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t int2_drdy_xl : 1; - uint8_t int2_drdy_g : 1; - uint8_t int2_drdy_temp : 1; - uint8_t int2_fth : 1; - uint8_t int2_fifo_ovr : 1; - uint8_t int2_full_flag : 1; - uint8_t int2_step_count_ov : 1; - uint8_t int2_step_delta : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t int2_step_delta : 1; - uint8_t int2_step_count_ov : 1; - uint8_t int2_full_flag : 1; - uint8_t int2_fifo_ovr : 1; - uint8_t int2_fth : 1; - uint8_t int2_drdy_temp : 1; - uint8_t int2_drdy_g : 1; - uint8_t int2_drdy_xl : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_int2_ctrl_t; - -#define LSM6DS3TR_C_WHO_AM_I 0x0FU -#define LSM6DS3TR_C_CTRL1_XL 0x10U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bw0_xl : 1; - uint8_t lpf1_bw_sel : 1; - uint8_t fs_xl : 2; - uint8_t odr_xl : 4; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t odr_xl : 4; - uint8_t fs_xl : 2; - uint8_t lpf1_bw_sel : 1; - uint8_t bw0_xl : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl1_xl_t; - -#define LSM6DS3TR_C_CTRL2_G 0x11U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 1; - uint8_t fs_g : 3; /* fs_g + fs_125 */ - uint8_t odr_g : 4; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t odr_g : 4; - uint8_t fs_g : 3; /* fs_g + fs_125 */ - uint8_t not_used_01 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl2_g_t; - -#define LSM6DS3TR_C_CTRL3_C 0x12U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t sw_reset : 1; - uint8_t ble : 1; - uint8_t if_inc : 1; - uint8_t sim : 1; - uint8_t pp_od : 1; - uint8_t h_lactive : 1; - uint8_t bdu : 1; - uint8_t boot : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t boot : 1; - uint8_t bdu : 1; - uint8_t h_lactive : 1; - uint8_t pp_od : 1; - uint8_t sim : 1; - uint8_t if_inc : 1; - uint8_t ble : 1; - uint8_t sw_reset : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl3_c_t; - -#define LSM6DS3TR_C_CTRL4_C 0x13U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 1; - uint8_t lpf1_sel_g : 1; - uint8_t i2c_disable : 1; - uint8_t drdy_mask : 1; - uint8_t den_drdy_int1 : 1; - uint8_t int2_on_int1 : 1; - uint8_t sleep : 1; - uint8_t den_xl_en : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t den_xl_en : 1; - uint8_t sleep : 1; - uint8_t int2_on_int1 : 1; - uint8_t den_drdy_int1 : 1; - uint8_t drdy_mask : 1; - uint8_t i2c_disable : 1; - uint8_t lpf1_sel_g : 1; - uint8_t not_used_01 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl4_c_t; - -#define LSM6DS3TR_C_CTRL5_C 0x14U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t st_xl : 2; - uint8_t st_g : 2; - uint8_t den_lh : 1; - uint8_t rounding : 3; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t rounding : 3; - uint8_t den_lh : 1; - uint8_t st_g : 2; - uint8_t st_xl : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl5_c_t; - -#define LSM6DS3TR_C_CTRL6_C 0x15U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t ftype : 2; - uint8_t not_used_01 : 1; - uint8_t usr_off_w : 1; - uint8_t xl_hm_mode : 1; - uint8_t den_mode : 3; /* trig_en + lvl_en + lvl2_en */ -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t den_mode : 3; /* trig_en + lvl_en + lvl2_en */ - uint8_t xl_hm_mode : 1; - uint8_t usr_off_w : 1; - uint8_t not_used_01 : 1; - uint8_t ftype : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl6_c_t; - -#define LSM6DS3TR_C_CTRL7_G 0x16U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 2; - uint8_t rounding_status : 1; - uint8_t not_used_02 : 1; - uint8_t hpm_g : 2; - uint8_t hp_en_g : 1; - uint8_t g_hm_mode : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t g_hm_mode : 1; - uint8_t hp_en_g : 1; - uint8_t hpm_g : 2; - uint8_t not_used_02 : 1; - uint8_t rounding_status : 1; - uint8_t not_used_01 : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl7_g_t; - -#define LSM6DS3TR_C_CTRL8_XL 0x17U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t low_pass_on_6d : 1; - uint8_t not_used_01 : 1; - uint8_t hp_slope_xl_en : 1; - uint8_t input_composite : 1; - uint8_t hp_ref_mode : 1; - uint8_t hpcf_xl : 2; - uint8_t lpf2_xl_en : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t lpf2_xl_en : 1; - uint8_t hpcf_xl : 2; - uint8_t hp_ref_mode : 1; - uint8_t input_composite : 1; - uint8_t hp_slope_xl_en : 1; - uint8_t not_used_01 : 1; - uint8_t low_pass_on_6d : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl8_xl_t; - -#define LSM6DS3TR_C_CTRL9_XL 0x18U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 2; - uint8_t soft_en : 1; - uint8_t not_used_02 : 1; - uint8_t den_xl_g : 1; - uint8_t den_z : 1; - uint8_t den_y : 1; - uint8_t den_x : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t den_x : 1; - uint8_t den_y : 1; - uint8_t den_z : 1; - uint8_t den_xl_g : 1; - uint8_t not_used_02 : 1; - uint8_t soft_en : 1; - uint8_t not_used_01 : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl9_xl_t; - -#define LSM6DS3TR_C_CTRL10_C 0x19U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t sign_motion_en : 1; - uint8_t pedo_rst_step : 1; - uint8_t func_en : 1; - uint8_t tilt_en : 1; - uint8_t pedo_en : 1; - uint8_t timer_en : 1; - uint8_t not_used_01 : 1; - uint8_t wrist_tilt_en : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t wrist_tilt_en : 1; - uint8_t not_used_01 : 1; - uint8_t timer_en : 1; - uint8_t pedo_en : 1; - uint8_t tilt_en : 1; - uint8_t func_en : 1; - uint8_t pedo_rst_step : 1; - uint8_t sign_motion_en : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_ctrl10_c_t; - -#define LSM6DS3TR_C_MASTER_CONFIG 0x1AU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t master_on : 1; - uint8_t iron_en : 1; - uint8_t pass_through_mode : 1; - uint8_t pull_up_en : 1; - uint8_t start_config : 1; - uint8_t not_used_01 : 1; - uint8_t data_valid_sel_fifo : 1; - uint8_t drdy_on_int1 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t drdy_on_int1 : 1; - uint8_t data_valid_sel_fifo : 1; - uint8_t not_used_01 : 1; - uint8_t start_config : 1; - uint8_t pull_up_en : 1; - uint8_t pass_through_mode : 1; - uint8_t iron_en : 1; - uint8_t master_on : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_master_config_t; - -#define LSM6DS3TR_C_WAKE_UP_SRC 0x1BU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t z_wu : 1; - uint8_t y_wu : 1; - uint8_t x_wu : 1; - uint8_t wu_ia : 1; - uint8_t sleep_state_ia : 1; - uint8_t ff_ia : 1; - uint8_t not_used_01 : 2; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 2; - uint8_t ff_ia : 1; - uint8_t sleep_state_ia : 1; - uint8_t wu_ia : 1; - uint8_t x_wu : 1; - uint8_t y_wu : 1; - uint8_t z_wu : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_wake_up_src_t; - -#define LSM6DS3TR_C_TAP_SRC 0x1CU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t z_tap : 1; - uint8_t y_tap : 1; - uint8_t x_tap : 1; - uint8_t tap_sign : 1; - uint8_t double_tap : 1; - uint8_t single_tap : 1; - uint8_t tap_ia : 1; - uint8_t not_used_01 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 1; - uint8_t tap_ia : 1; - uint8_t single_tap : 1; - uint8_t double_tap : 1; - uint8_t tap_sign : 1; - uint8_t x_tap : 1; - uint8_t y_tap : 1; - uint8_t z_tap : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_tap_src_t; - -#define LSM6DS3TR_C_D6D_SRC 0x1DU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t xl : 1; - uint8_t xh : 1; - uint8_t yl : 1; - uint8_t yh : 1; - uint8_t zl : 1; - uint8_t zh : 1; - uint8_t d6d_ia : 1; - uint8_t den_drdy : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t den_drdy : 1; - uint8_t d6d_ia : 1; - uint8_t zh : 1; - uint8_t zl : 1; - uint8_t yh : 1; - uint8_t yl : 1; - uint8_t xh : 1; - uint8_t xl : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_d6d_src_t; - -#define LSM6DS3TR_C_STATUS_REG 0x1EU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t xlda : 1; - uint8_t gda : 1; - uint8_t tda : 1; - uint8_t not_used_01 : 5; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 5; - uint8_t tda : 1; - uint8_t gda : 1; - uint8_t xlda : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_status_reg_t; - -#define LSM6DS3TR_C_OUT_TEMP_L 0x20U -#define LSM6DS3TR_C_OUT_TEMP_H 0x21U -#define LSM6DS3TR_C_OUTX_L_G 0x22U -#define LSM6DS3TR_C_OUTX_H_G 0x23U -#define LSM6DS3TR_C_OUTY_L_G 0x24U -#define LSM6DS3TR_C_OUTY_H_G 0x25U -#define LSM6DS3TR_C_OUTZ_L_G 0x26U -#define LSM6DS3TR_C_OUTZ_H_G 0x27U -#define LSM6DS3TR_C_OUTX_L_XL 0x28U -#define LSM6DS3TR_C_OUTX_H_XL 0x29U -#define LSM6DS3TR_C_OUTY_L_XL 0x2AU -#define LSM6DS3TR_C_OUTY_H_XL 0x2BU -#define LSM6DS3TR_C_OUTZ_L_XL 0x2CU -#define LSM6DS3TR_C_OUTZ_H_XL 0x2DU -#define LSM6DS3TR_C_SENSORHUB1_REG 0x2EU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub1_reg_t; - -#define LSM6DS3TR_C_SENSORHUB2_REG 0x2FU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub2_reg_t; - -#define LSM6DS3TR_C_SENSORHUB3_REG 0x30U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub3_reg_t; - -#define LSM6DS3TR_C_SENSORHUB4_REG 0x31U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub4_reg_t; - -#define LSM6DS3TR_C_SENSORHUB5_REG 0x32U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub5_reg_t; - -#define LSM6DS3TR_C_SENSORHUB6_REG 0x33U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub6_reg_t; - -#define LSM6DS3TR_C_SENSORHUB7_REG 0x34U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub7_reg_t; - -#define LSM6DS3TR_C_SENSORHUB8_REG 0x35U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub8_reg_t; - -#define LSM6DS3TR_C_SENSORHUB9_REG 0x36U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub9_reg_t; - -#define LSM6DS3TR_C_SENSORHUB10_REG 0x37U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub10_reg_t; - -#define LSM6DS3TR_C_SENSORHUB11_REG 0x38U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub11_reg_t; - -#define LSM6DS3TR_C_SENSORHUB12_REG 0x39U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub12_reg_t; - -#define LSM6DS3TR_C_FIFO_STATUS1 0x3AU -typedef struct { - uint8_t diff_fifo : 8; /* + FIFO_STATUS2(diff_fifo) */ -} lsm6ds3tr_c_fifo_status1_t; - -#define LSM6DS3TR_C_FIFO_STATUS2 0x3BU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t diff_fifo : 3; /* + FIFO_STATUS1(diff_fifo) */ - uint8_t not_used_01 : 1; - uint8_t fifo_empty : 1; - uint8_t fifo_full_smart : 1; - uint8_t over_run : 1; - uint8_t waterm : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t waterm : 1; - uint8_t over_run : 1; - uint8_t fifo_full_smart : 1; - uint8_t fifo_empty : 1; - uint8_t not_used_01 : 1; - uint8_t diff_fifo : 3; /* + FIFO_STATUS1(diff_fifo) */ -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_fifo_status2_t; - -#define LSM6DS3TR_C_FIFO_STATUS3 0x3CU -typedef struct { - uint8_t fifo_pattern : 8; /* + FIFO_STATUS4(fifo_pattern) */ -} lsm6ds3tr_c_fifo_status3_t; - -#define LSM6DS3TR_C_FIFO_STATUS4 0x3DU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t fifo_pattern : 2; /* + FIFO_STATUS3(fifo_pattern) */ - uint8_t not_used_01 : 6; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_01 : 6; - uint8_t fifo_pattern : 2; /* + FIFO_STATUS3(fifo_pattern) */ -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_fifo_status4_t; - -#define LSM6DS3TR_C_FIFO_DATA_OUT_L 0x3EU -#define LSM6DS3TR_C_FIFO_DATA_OUT_H 0x3FU -#define LSM6DS3TR_C_TIMESTAMP0_REG 0x40U -#define LSM6DS3TR_C_TIMESTAMP1_REG 0x41U -#define LSM6DS3TR_C_TIMESTAMP2_REG 0x42U -#define LSM6DS3TR_C_STEP_TIMESTAMP_L 0x49U -#define LSM6DS3TR_C_STEP_TIMESTAMP_H 0x4AU -#define LSM6DS3TR_C_STEP_COUNTER_L 0x4BU -#define LSM6DS3TR_C_STEP_COUNTER_H 0x4CU - -#define LSM6DS3TR_C_SENSORHUB13_REG 0x4DU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub13_reg_t; - -#define LSM6DS3TR_C_SENSORHUB14_REG 0x4EU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub14_reg_t; - -#define LSM6DS3TR_C_SENSORHUB15_REG 0x4FU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub15_reg_t; - -#define LSM6DS3TR_C_SENSORHUB16_REG 0x50U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub16_reg_t; - -#define LSM6DS3TR_C_SENSORHUB17_REG 0x51U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub17_reg_t; - -#define LSM6DS3TR_C_SENSORHUB18_REG 0x52U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t bit0 : 1; - uint8_t bit1 : 1; - uint8_t bit2 : 1; - uint8_t bit3 : 1; - uint8_t bit4 : 1; - uint8_t bit5 : 1; - uint8_t bit6 : 1; - uint8_t bit7 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t bit7 : 1; - uint8_t bit6 : 1; - uint8_t bit5 : 1; - uint8_t bit4 : 1; - uint8_t bit3 : 1; - uint8_t bit2 : 1; - uint8_t bit1 : 1; - uint8_t bit0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_sensorhub18_reg_t; - -#define LSM6DS3TR_C_FUNC_SRC1 0x53U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t sensorhub_end_op : 1; - uint8_t si_end_op : 1; - uint8_t hi_fail : 1; - uint8_t step_overflow : 1; - uint8_t step_detected : 1; - uint8_t tilt_ia : 1; - uint8_t sign_motion_ia : 1; - uint8_t step_count_delta_ia : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t step_count_delta_ia : 1; - uint8_t sign_motion_ia : 1; - uint8_t tilt_ia : 1; - uint8_t step_detected : 1; - uint8_t step_overflow : 1; - uint8_t hi_fail : 1; - uint8_t si_end_op : 1; - uint8_t sensorhub_end_op : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_func_src1_t; - -#define LSM6DS3TR_C_FUNC_SRC2 0x54U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t wrist_tilt_ia : 1; - uint8_t not_used_01 : 2; - uint8_t slave0_nack : 1; - uint8_t slave1_nack : 1; - uint8_t slave2_nack : 1; - uint8_t slave3_nack : 1; - uint8_t not_used_02 : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t not_used_02 : 1; - uint8_t slave3_nack : 1; - uint8_t slave2_nack : 1; - uint8_t slave1_nack : 1; - uint8_t slave0_nack : 1; - uint8_t not_used_01 : 2; - uint8_t wrist_tilt_ia : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_func_src2_t; - -#define LSM6DS3TR_C_WRIST_TILT_IA 0x55U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 2; - uint8_t wrist_tilt_ia_zneg : 1; - uint8_t wrist_tilt_ia_zpos : 1; - uint8_t wrist_tilt_ia_yneg : 1; - uint8_t wrist_tilt_ia_ypos : 1; - uint8_t wrist_tilt_ia_xneg : 1; - uint8_t wrist_tilt_ia_xpos : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t wrist_tilt_ia_xpos : 1; - uint8_t wrist_tilt_ia_xneg : 1; - uint8_t wrist_tilt_ia_ypos : 1; - uint8_t wrist_tilt_ia_yneg : 1; - uint8_t wrist_tilt_ia_zpos : 1; - uint8_t wrist_tilt_ia_zneg : 1; - uint8_t not_used_01 : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_wrist_tilt_ia_t; - -#define LSM6DS3TR_C_TAP_CFG 0x58U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t lir : 1; - uint8_t tap_z_en : 1; - uint8_t tap_y_en : 1; - uint8_t tap_x_en : 1; - uint8_t slope_fds : 1; - uint8_t inact_en : 2; - uint8_t interrupts_enable : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t interrupts_enable : 1; - uint8_t inact_en : 2; - uint8_t slope_fds : 1; - uint8_t tap_x_en : 1; - uint8_t tap_y_en : 1; - uint8_t tap_z_en : 1; - uint8_t lir : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_tap_cfg_t; - -#define LSM6DS3TR_C_TAP_THS_6D 0x59U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t tap_ths : 5; - uint8_t sixd_ths : 2; - uint8_t d4d_en : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t d4d_en : 1; - uint8_t sixd_ths : 2; - uint8_t tap_ths : 5; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_tap_ths_6d_t; - -#define LSM6DS3TR_C_INT_DUR2 0x5AU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t shock : 2; - uint8_t quiet : 2; - uint8_t dur : 4; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t dur : 4; - uint8_t quiet : 2; - uint8_t shock : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_int_dur2_t; - -#define LSM6DS3TR_C_WAKE_UP_THS 0x5BU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t wk_ths : 6; - uint8_t not_used_01 : 1; - uint8_t single_double_tap : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t single_double_tap : 1; - uint8_t not_used_01 : 1; - uint8_t wk_ths : 6; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_wake_up_ths_t; - -#define LSM6DS3TR_C_WAKE_UP_DUR 0x5CU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t sleep_dur : 4; - uint8_t timer_hr : 1; - uint8_t wake_dur : 2; - uint8_t ff_dur : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t ff_dur : 1; - uint8_t wake_dur : 2; - uint8_t timer_hr : 1; - uint8_t sleep_dur : 4; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_wake_up_dur_t; - -#define LSM6DS3TR_C_FREE_FALL 0x5DU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t ff_ths : 3; - uint8_t ff_dur : 5; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t ff_dur : 5; - uint8_t ff_ths : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_free_fall_t; - -#define LSM6DS3TR_C_MD1_CFG 0x5EU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t int1_timer : 1; - uint8_t int1_tilt : 1; - uint8_t int1_6d : 1; - uint8_t int1_double_tap : 1; - uint8_t int1_ff : 1; - uint8_t int1_wu : 1; - uint8_t int1_single_tap : 1; - uint8_t int1_inact_state : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t int1_inact_state : 1; - uint8_t int1_single_tap : 1; - uint8_t int1_wu : 1; - uint8_t int1_ff : 1; - uint8_t int1_double_tap : 1; - uint8_t int1_6d : 1; - uint8_t int1_tilt : 1; - uint8_t int1_timer : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_md1_cfg_t; - -#define LSM6DS3TR_C_MD2_CFG 0x5FU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t int2_iron : 1; - uint8_t int2_tilt : 1; - uint8_t int2_6d : 1; - uint8_t int2_double_tap : 1; - uint8_t int2_ff : 1; - uint8_t int2_wu : 1; - uint8_t int2_single_tap : 1; - uint8_t int2_inact_state : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t int2_inact_state : 1; - uint8_t int2_single_tap : 1; - uint8_t int2_wu : 1; - uint8_t int2_ff : 1; - uint8_t int2_double_tap : 1; - uint8_t int2_6d : 1; - uint8_t int2_tilt : 1; - uint8_t int2_iron : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_md2_cfg_t; - -#define LSM6DS3TR_C_MASTER_CMD_CODE 0x60U -typedef struct { - uint8_t master_cmd_code : 8; -} lsm6ds3tr_c_master_cmd_code_t; - -#define LSM6DS3TR_C_SENS_SYNC_SPI_ERROR_CODE 0x61U -typedef struct { - uint8_t error_code : 8; -} lsm6ds3tr_c_sens_sync_spi_error_code_t; - -#define LSM6DS3TR_C_OUT_MAG_RAW_X_L 0x66U -#define LSM6DS3TR_C_OUT_MAG_RAW_X_H 0x67U -#define LSM6DS3TR_C_OUT_MAG_RAW_Y_L 0x68U -#define LSM6DS3TR_C_OUT_MAG_RAW_Y_H 0x69U -#define LSM6DS3TR_C_OUT_MAG_RAW_Z_L 0x6AU -#define LSM6DS3TR_C_OUT_MAG_RAW_Z_H 0x6BU -#define LSM6DS3TR_C_X_OFS_USR 0x73U -#define LSM6DS3TR_C_Y_OFS_USR 0x74U -#define LSM6DS3TR_C_Z_OFS_USR 0x75U -#define LSM6DS3TR_C_SLV0_ADD 0x02U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t rw_0 : 1; - uint8_t slave0_add : 7; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave0_add : 7; - uint8_t rw_0 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slv0_add_t; - -#define LSM6DS3TR_C_SLV0_SUBADD 0x03U -typedef struct { - uint8_t slave0_reg : 8; -} lsm6ds3tr_c_slv0_subadd_t; - -#define LSM6DS3TR_C_SLAVE0_CONFIG 0x04U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t slave0_numop : 3; - uint8_t src_mode : 1; - uint8_t aux_sens_on : 2; - uint8_t slave0_rate : 2; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave0_rate : 2; - uint8_t aux_sens_on : 2; - uint8_t src_mode : 1; - uint8_t slave0_numop : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slave0_config_t; - -#define LSM6DS3TR_C_SLV1_ADD 0x05U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t r_1 : 1; - uint8_t slave1_add : 7; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave1_add : 7; - uint8_t r_1 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slv1_add_t; - -#define LSM6DS3TR_C_SLV1_SUBADD 0x06U -typedef struct { - uint8_t slave1_reg : 8; -} lsm6ds3tr_c_slv1_subadd_t; - -#define LSM6DS3TR_C_SLAVE1_CONFIG 0x07U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t slave1_numop : 3; - uint8_t not_used_01 : 2; - uint8_t write_once : 1; - uint8_t slave1_rate : 2; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave1_rate : 2; - uint8_t write_once : 1; - uint8_t not_used_01 : 2; - uint8_t slave1_numop : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slave1_config_t; - -#define LSM6DS3TR_C_SLV2_ADD 0x08U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t r_2 : 1; - uint8_t slave2_add : 7; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave2_add : 7; - uint8_t r_2 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slv2_add_t; - -#define LSM6DS3TR_C_SLV2_SUBADD 0x09U -typedef struct { - uint8_t slave2_reg : 8; -} lsm6ds3tr_c_slv2_subadd_t; - -#define LSM6DS3TR_C_SLAVE2_CONFIG 0x0AU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t slave2_numop : 3; - uint8_t not_used_01 : 3; - uint8_t slave2_rate : 2; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave2_rate : 2; - uint8_t not_used_01 : 3; - uint8_t slave2_numop : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slave2_config_t; - -#define LSM6DS3TR_C_SLV3_ADD 0x0BU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t r_3 : 1; - uint8_t slave3_add : 7; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave3_add : 7; - uint8_t r_3 : 1; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slv3_add_t; - -#define LSM6DS3TR_C_SLV3_SUBADD 0x0CU -typedef struct { - uint8_t slave3_reg : 8; -} lsm6ds3tr_c_slv3_subadd_t; - -#define LSM6DS3TR_C_SLAVE3_CONFIG 0x0DU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t slave3_numop : 3; - uint8_t not_used_01 : 3; - uint8_t slave3_rate : 2; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t slave3_rate : 2; - uint8_t not_used_01 : 3; - uint8_t slave3_numop : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_slave3_config_t; - -#define LSM6DS3TR_C_DATAWRITE_SRC_MODE_SUB_SLV0 0x0EU -typedef struct { - uint8_t slave_dataw : 8; -} lsm6ds3tr_c_datawrite_src_mode_sub_slv0_t; - -#define LSM6DS3TR_C_CONFIG_PEDO_THS_MIN 0x0FU -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t ths_min : 5; - uint8_t not_used_01 : 2; - uint8_t pedo_fs : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t pedo_fs : 1; - uint8_t not_used_01 : 2; - uint8_t ths_min : 5; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_config_pedo_ths_min_t; - -#define LSM6DS3TR_C_SM_THS 0x13U -#define LSM6DS3TR_C_PEDO_DEB_REG 0x14U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t deb_step : 3; - uint8_t deb_time : 5; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t deb_time : 5; - uint8_t deb_step : 3; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_pedo_deb_reg_t; - -#define LSM6DS3TR_C_STEP_COUNT_DELTA 0x15U -#define LSM6DS3TR_C_MAG_SI_XX 0x24U -#define LSM6DS3TR_C_MAG_SI_XY 0x25U -#define LSM6DS3TR_C_MAG_SI_XZ 0x26U -#define LSM6DS3TR_C_MAG_SI_YX 0x27U -#define LSM6DS3TR_C_MAG_SI_YY 0x28U -#define LSM6DS3TR_C_MAG_SI_YZ 0x29U -#define LSM6DS3TR_C_MAG_SI_ZX 0x2AU -#define LSM6DS3TR_C_MAG_SI_ZY 0x2BU -#define LSM6DS3TR_C_MAG_SI_ZZ 0x2CU -#define LSM6DS3TR_C_MAG_OFFX_L 0x2DU -#define LSM6DS3TR_C_MAG_OFFX_H 0x2EU -#define LSM6DS3TR_C_MAG_OFFY_L 0x2FU -#define LSM6DS3TR_C_MAG_OFFY_H 0x30U -#define LSM6DS3TR_C_MAG_OFFZ_L 0x31U -#define LSM6DS3TR_C_MAG_OFFZ_H 0x32U -#define LSM6DS3TR_C_A_WRIST_TILT_LAT 0x50U -#define LSM6DS3TR_C_A_WRIST_TILT_THS 0x54U -#define LSM6DS3TR_C_A_WRIST_TILT_MASK 0x59U -typedef struct { -#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN - uint8_t not_used_01 : 2; - uint8_t wrist_tilt_mask_zneg : 1; - uint8_t wrist_tilt_mask_zpos : 1; - uint8_t wrist_tilt_mask_yneg : 1; - uint8_t wrist_tilt_mask_ypos : 1; - uint8_t wrist_tilt_mask_xneg : 1; - uint8_t wrist_tilt_mask_xpos : 1; -#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN - uint8_t wrist_tilt_mask_xpos : 1; - uint8_t wrist_tilt_mask_xneg : 1; - uint8_t wrist_tilt_mask_ypos : 1; - uint8_t wrist_tilt_mask_yneg : 1; - uint8_t wrist_tilt_mask_zpos : 1; - uint8_t wrist_tilt_mask_zneg : 1; - uint8_t not_used_01 : 2; -#endif /* DRV_BYTE_ORDER */ -} lsm6ds3tr_c_a_wrist_tilt_mask_t; - -/** - * @defgroup LSM6DS3TR_C_Register_Union - * @brief This union group all the registers having a bit-field - * description. - * This union is useful but it's not needed by the driver. - * - * REMOVING this union you are compliant with: - * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " - * - * @{ - * - */ -typedef union { - lsm6ds3tr_c_func_cfg_access_t func_cfg_access; - lsm6ds3tr_c_sensor_sync_time_frame_t sensor_sync_time_frame; - lsm6ds3tr_c_sensor_sync_res_ratio_t sensor_sync_res_ratio; - lsm6ds3tr_c_fifo_ctrl1_t fifo_ctrl1; - lsm6ds3tr_c_fifo_ctrl2_t fifo_ctrl2; - lsm6ds3tr_c_fifo_ctrl3_t fifo_ctrl3; - lsm6ds3tr_c_fifo_ctrl4_t fifo_ctrl4; - lsm6ds3tr_c_fifo_ctrl5_t fifo_ctrl5; - lsm6ds3tr_c_drdy_pulse_cfg_g_t drdy_pulse_cfg_g; - lsm6ds3tr_c_int1_ctrl_t int1_ctrl; - lsm6ds3tr_c_int2_ctrl_t int2_ctrl; - lsm6ds3tr_c_ctrl1_xl_t ctrl1_xl; - lsm6ds3tr_c_ctrl2_g_t ctrl2_g; - lsm6ds3tr_c_ctrl3_c_t ctrl3_c; - lsm6ds3tr_c_ctrl4_c_t ctrl4_c; - lsm6ds3tr_c_ctrl5_c_t ctrl5_c; - lsm6ds3tr_c_ctrl6_c_t ctrl6_c; - lsm6ds3tr_c_ctrl7_g_t ctrl7_g; - lsm6ds3tr_c_ctrl8_xl_t ctrl8_xl; - lsm6ds3tr_c_ctrl9_xl_t ctrl9_xl; - lsm6ds3tr_c_ctrl10_c_t ctrl10_c; - lsm6ds3tr_c_master_config_t master_config; - lsm6ds3tr_c_wake_up_src_t wake_up_src; - lsm6ds3tr_c_tap_src_t tap_src; - lsm6ds3tr_c_d6d_src_t d6d_src; - lsm6ds3tr_c_status_reg_t status_reg; - lsm6ds3tr_c_sensorhub1_reg_t sensorhub1_reg; - lsm6ds3tr_c_sensorhub2_reg_t sensorhub2_reg; - lsm6ds3tr_c_sensorhub3_reg_t sensorhub3_reg; - lsm6ds3tr_c_sensorhub4_reg_t sensorhub4_reg; - lsm6ds3tr_c_sensorhub5_reg_t sensorhub5_reg; - lsm6ds3tr_c_sensorhub6_reg_t sensorhub6_reg; - lsm6ds3tr_c_sensorhub7_reg_t sensorhub7_reg; - lsm6ds3tr_c_sensorhub8_reg_t sensorhub8_reg; - lsm6ds3tr_c_sensorhub9_reg_t sensorhub9_reg; - lsm6ds3tr_c_sensorhub10_reg_t sensorhub10_reg; - lsm6ds3tr_c_sensorhub11_reg_t sensorhub11_reg; - lsm6ds3tr_c_sensorhub12_reg_t sensorhub12_reg; - lsm6ds3tr_c_fifo_status1_t fifo_status1; - lsm6ds3tr_c_fifo_status2_t fifo_status2; - lsm6ds3tr_c_fifo_status3_t fifo_status3; - lsm6ds3tr_c_fifo_status4_t fifo_status4; - lsm6ds3tr_c_sensorhub13_reg_t sensorhub13_reg; - lsm6ds3tr_c_sensorhub14_reg_t sensorhub14_reg; - lsm6ds3tr_c_sensorhub15_reg_t sensorhub15_reg; - lsm6ds3tr_c_sensorhub16_reg_t sensorhub16_reg; - lsm6ds3tr_c_sensorhub17_reg_t sensorhub17_reg; - lsm6ds3tr_c_sensorhub18_reg_t sensorhub18_reg; - lsm6ds3tr_c_func_src1_t func_src1; - lsm6ds3tr_c_func_src2_t func_src2; - lsm6ds3tr_c_wrist_tilt_ia_t wrist_tilt_ia; - lsm6ds3tr_c_tap_cfg_t tap_cfg; - lsm6ds3tr_c_tap_ths_6d_t tap_ths_6d; - lsm6ds3tr_c_int_dur2_t int_dur2; - lsm6ds3tr_c_wake_up_ths_t wake_up_ths; - lsm6ds3tr_c_wake_up_dur_t wake_up_dur; - lsm6ds3tr_c_free_fall_t free_fall; - lsm6ds3tr_c_md1_cfg_t md1_cfg; - lsm6ds3tr_c_md2_cfg_t md2_cfg; - lsm6ds3tr_c_master_cmd_code_t master_cmd_code; - lsm6ds3tr_c_sens_sync_spi_error_code_t sens_sync_spi_error_code; - lsm6ds3tr_c_slv0_add_t slv0_add; - lsm6ds3tr_c_slv0_subadd_t slv0_subadd; - lsm6ds3tr_c_slave0_config_t slave0_config; - lsm6ds3tr_c_slv1_add_t slv1_add; - lsm6ds3tr_c_slv1_subadd_t slv1_subadd; - lsm6ds3tr_c_slave1_config_t slave1_config; - lsm6ds3tr_c_slv2_add_t slv2_add; - lsm6ds3tr_c_slv2_subadd_t slv2_subadd; - lsm6ds3tr_c_slave2_config_t slave2_config; - lsm6ds3tr_c_slv3_add_t slv3_add; - lsm6ds3tr_c_slv3_subadd_t slv3_subadd; - lsm6ds3tr_c_slave3_config_t slave3_config; - lsm6ds3tr_c_datawrite_src_mode_sub_slv0_t datawrite_src_mode_sub_slv0; - lsm6ds3tr_c_config_pedo_ths_min_t config_pedo_ths_min; - lsm6ds3tr_c_pedo_deb_reg_t pedo_deb_reg; - lsm6ds3tr_c_a_wrist_tilt_mask_t a_wrist_tilt_mask; - bitwise_t bitwise; - uint8_t byte; -} lsm6ds3tr_c_reg_t; - -/** - * @} - * - */ - -int32_t lsm6ds3tr_c_read_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len); -int32_t lsm6ds3tr_c_write_reg(stmdev_ctx_t* ctx, uint8_t reg, uint8_t* data, uint16_t len); - -float_t lsm6ds3tr_c_from_fs2g_to_mg(int16_t lsb); -float_t lsm6ds3tr_c_from_fs4g_to_mg(int16_t lsb); -float_t lsm6ds3tr_c_from_fs8g_to_mg(int16_t lsb); -float_t lsm6ds3tr_c_from_fs16g_to_mg(int16_t lsb); - -float_t lsm6ds3tr_c_from_fs125dps_to_mdps(int16_t lsb); -float_t lsm6ds3tr_c_from_fs250dps_to_mdps(int16_t lsb); -float_t lsm6ds3tr_c_from_fs500dps_to_mdps(int16_t lsb); -float_t lsm6ds3tr_c_from_fs1000dps_to_mdps(int16_t lsb); -float_t lsm6ds3tr_c_from_fs2000dps_to_mdps(int16_t lsb); - -float_t lsm6ds3tr_c_from_lsb_to_celsius(int16_t lsb); - -typedef enum { - LSM6DS3TR_C_2g = 0, - LSM6DS3TR_C_16g = 1, - LSM6DS3TR_C_4g = 2, - LSM6DS3TR_C_8g = 3, - LSM6DS3TR_C_XL_FS_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_fs_xl_t; -int32_t lsm6ds3tr_c_xl_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t val); -int32_t lsm6ds3tr_c_xl_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_xl_t* val); - -typedef enum { - LSM6DS3TR_C_XL_ODR_OFF = 0, - LSM6DS3TR_C_XL_ODR_12Hz5 = 1, - LSM6DS3TR_C_XL_ODR_26Hz = 2, - LSM6DS3TR_C_XL_ODR_52Hz = 3, - LSM6DS3TR_C_XL_ODR_104Hz = 4, - LSM6DS3TR_C_XL_ODR_208Hz = 5, - LSM6DS3TR_C_XL_ODR_416Hz = 6, - LSM6DS3TR_C_XL_ODR_833Hz = 7, - LSM6DS3TR_C_XL_ODR_1k66Hz = 8, - LSM6DS3TR_C_XL_ODR_3k33Hz = 9, - LSM6DS3TR_C_XL_ODR_6k66Hz = 10, - LSM6DS3TR_C_XL_ODR_1Hz6 = 11, - LSM6DS3TR_C_XL_ODR_ND = 12, /* ERROR CODE */ -} lsm6ds3tr_c_odr_xl_t; -int32_t lsm6ds3tr_c_xl_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t val); -int32_t lsm6ds3tr_c_xl_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_xl_t* val); - -typedef enum { - LSM6DS3TR_C_250dps = 0, - LSM6DS3TR_C_125dps = 1, - LSM6DS3TR_C_500dps = 2, - LSM6DS3TR_C_1000dps = 4, - LSM6DS3TR_C_2000dps = 6, - LSM6DS3TR_C_GY_FS_ND = 7, /* ERROR CODE */ -} lsm6ds3tr_c_fs_g_t; -int32_t lsm6ds3tr_c_gy_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t val); -int32_t lsm6ds3tr_c_gy_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fs_g_t* val); - -typedef enum { - LSM6DS3TR_C_GY_ODR_OFF = 0, - LSM6DS3TR_C_GY_ODR_12Hz5 = 1, - LSM6DS3TR_C_GY_ODR_26Hz = 2, - LSM6DS3TR_C_GY_ODR_52Hz = 3, - LSM6DS3TR_C_GY_ODR_104Hz = 4, - LSM6DS3TR_C_GY_ODR_208Hz = 5, - LSM6DS3TR_C_GY_ODR_416Hz = 6, - LSM6DS3TR_C_GY_ODR_833Hz = 7, - LSM6DS3TR_C_GY_ODR_1k66Hz = 8, - LSM6DS3TR_C_GY_ODR_3k33Hz = 9, - LSM6DS3TR_C_GY_ODR_6k66Hz = 10, - LSM6DS3TR_C_GY_ODR_ND = 11, /* ERROR CODE */ -} lsm6ds3tr_c_odr_g_t; -int32_t lsm6ds3tr_c_gy_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t val); -int32_t lsm6ds3tr_c_gy_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_g_t* val); - -int32_t lsm6ds3tr_c_block_data_update_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_block_data_update_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_LSb_1mg = 0, - LSM6DS3TR_C_LSb_16mg = 1, - LSM6DS3TR_C_WEIGHT_ND = 2, -} lsm6ds3tr_c_usr_off_w_t; -int32_t lsm6ds3tr_c_xl_offset_weight_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t val); -int32_t lsm6ds3tr_c_xl_offset_weight_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_usr_off_w_t* val); - -typedef enum { - LSM6DS3TR_C_XL_HIGH_PERFORMANCE = 0, - LSM6DS3TR_C_XL_NORMAL = 1, - LSM6DS3TR_C_XL_PW_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_xl_hm_mode_t; -int32_t lsm6ds3tr_c_xl_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t val); -int32_t lsm6ds3tr_c_xl_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_xl_hm_mode_t* val); - -typedef enum { - LSM6DS3TR_C_STAT_RND_DISABLE = 0, - LSM6DS3TR_C_STAT_RND_ENABLE = 1, - LSM6DS3TR_C_STAT_RND_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_rounding_status_t; -int32_t lsm6ds3tr_c_rounding_on_status_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t val); -int32_t lsm6ds3tr_c_rounding_on_status_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_status_t* val); - -typedef enum { - LSM6DS3TR_C_GY_HIGH_PERFORMANCE = 0, - LSM6DS3TR_C_GY_NORMAL = 1, - LSM6DS3TR_C_GY_PW_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_g_hm_mode_t; -int32_t lsm6ds3tr_c_gy_power_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t val); -int32_t lsm6ds3tr_c_gy_power_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_g_hm_mode_t* val); - -typedef struct { - lsm6ds3tr_c_wake_up_src_t wake_up_src; - lsm6ds3tr_c_tap_src_t tap_src; - lsm6ds3tr_c_d6d_src_t d6d_src; - lsm6ds3tr_c_status_reg_t status_reg; - lsm6ds3tr_c_func_src1_t func_src1; - lsm6ds3tr_c_func_src2_t func_src2; - lsm6ds3tr_c_wrist_tilt_ia_t wrist_tilt_ia; - lsm6ds3tr_c_a_wrist_tilt_mask_t a_wrist_tilt_mask; -} lsm6ds3tr_c_all_sources_t; -int32_t lsm6ds3tr_c_all_sources_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_all_sources_t* val); - -int32_t lsm6ds3tr_c_status_reg_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_status_reg_t* val); - -int32_t lsm6ds3tr_c_xl_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_gy_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_temp_flag_data_ready_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_xl_usr_offset_set(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_xl_usr_offset_get(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_timestamp_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_timestamp_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_LSB_6ms4 = 0, - LSM6DS3TR_C_LSB_25us = 1, - LSM6DS3TR_C_TS_RES_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_timer_hr_t; -int32_t lsm6ds3tr_c_timestamp_res_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t val); -int32_t lsm6ds3tr_c_timestamp_res_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_timer_hr_t* val); - -typedef enum { - LSM6DS3TR_C_ROUND_DISABLE = 0, - LSM6DS3TR_C_ROUND_XL = 1, - LSM6DS3TR_C_ROUND_GY = 2, - LSM6DS3TR_C_ROUND_GY_XL = 3, - LSM6DS3TR_C_ROUND_SH1_TO_SH6 = 4, - LSM6DS3TR_C_ROUND_XL_SH1_TO_SH6 = 5, - LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH12 = 6, - LSM6DS3TR_C_ROUND_GY_XL_SH1_TO_SH6 = 7, - LSM6DS3TR_C_ROUND_OUT_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_rounding_t; -int32_t lsm6ds3tr_c_rounding_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t val); -int32_t lsm6ds3tr_c_rounding_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rounding_t* val); - -int32_t lsm6ds3tr_c_temperature_raw_get(stmdev_ctx_t* ctx, int16_t* val); -int32_t lsm6ds3tr_c_angular_rate_raw_get(stmdev_ctx_t* ctx, int16_t* val); -int32_t lsm6ds3tr_c_acceleration_raw_get(stmdev_ctx_t* ctx, int16_t* val); - -int32_t lsm6ds3tr_c_mag_calibrated_raw_get(stmdev_ctx_t* ctx, int16_t* val); - -int32_t lsm6ds3tr_c_fifo_raw_data_get(stmdev_ctx_t* ctx, uint8_t* buffer, uint8_t len); - -typedef enum { - LSM6DS3TR_C_USER_BANK = 0, - LSM6DS3TR_C_BANK_A = 4, - LSM6DS3TR_C_BANK_B = 5, - LSM6DS3TR_C_BANK_ND = 6, /* ERROR CODE */ -} lsm6ds3tr_c_func_cfg_en_t; -int32_t lsm6ds3tr_c_mem_bank_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t val); -int32_t lsm6ds3tr_c_mem_bank_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_func_cfg_en_t* val); - -typedef enum { - LSM6DS3TR_C_DRDY_LATCHED = 0, - LSM6DS3TR_C_DRDY_PULSED = 1, - LSM6DS3TR_C_DRDY_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_drdy_pulsed_g_t; -int32_t lsm6ds3tr_c_data_ready_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t val); -int32_t lsm6ds3tr_c_data_ready_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_drdy_pulsed_g_t* val); - -int32_t lsm6ds3tr_c_device_id_get(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_reset_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_reset_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_LSB_AT_LOW_ADD = 0, - LSM6DS3TR_C_MSB_AT_LOW_ADD = 1, - LSM6DS3TR_C_DATA_FMT_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_ble_t; -int32_t lsm6ds3tr_c_data_format_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t val); -int32_t lsm6ds3tr_c_data_format_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ble_t* val); - -int32_t lsm6ds3tr_c_auto_increment_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_auto_increment_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_boot_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_boot_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_XL_ST_DISABLE = 0, - LSM6DS3TR_C_XL_ST_POSITIVE = 1, - LSM6DS3TR_C_XL_ST_NEGATIVE = 2, - LSM6DS3TR_C_XL_ST_ND = 3, /* ERROR CODE */ -} lsm6ds3tr_c_st_xl_t; -int32_t lsm6ds3tr_c_xl_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t val); -int32_t lsm6ds3tr_c_xl_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_xl_t* val); - -typedef enum { - LSM6DS3TR_C_GY_ST_DISABLE = 0, - LSM6DS3TR_C_GY_ST_POSITIVE = 1, - LSM6DS3TR_C_GY_ST_NEGATIVE = 3, - LSM6DS3TR_C_GY_ST_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_st_g_t; -int32_t lsm6ds3tr_c_gy_self_test_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t val); -int32_t lsm6ds3tr_c_gy_self_test_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_st_g_t* val); - -int32_t lsm6ds3tr_c_filter_settling_mask_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_filter_settling_mask_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_USE_SLOPE = 0, - LSM6DS3TR_C_USE_HPF = 1, - LSM6DS3TR_C_HP_PATH_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_slope_fds_t; -int32_t lsm6ds3tr_c_xl_hp_path_internal_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t val); -int32_t lsm6ds3tr_c_xl_hp_path_internal_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slope_fds_t* val); - -typedef enum { - LSM6DS3TR_C_XL_ANA_BW_1k5Hz = 0, - LSM6DS3TR_C_XL_ANA_BW_400Hz = 1, - LSM6DS3TR_C_XL_ANA_BW_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_bw0_xl_t; -int32_t lsm6ds3tr_c_xl_filter_analog_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t val); -int32_t lsm6ds3tr_c_xl_filter_analog_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_bw0_xl_t* val); - -typedef enum { - LSM6DS3TR_C_XL_LP1_ODR_DIV_2 = 0, - LSM6DS3TR_C_XL_LP1_ODR_DIV_4 = 1, - LSM6DS3TR_C_XL_LP1_NA = 2, /* ERROR CODE */ -} lsm6ds3tr_c_lpf1_bw_sel_t; -int32_t lsm6ds3tr_c_xl_lp1_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t val); -int32_t lsm6ds3tr_c_xl_lp1_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_bw_sel_t* val); - -typedef enum { - LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_50 = 0x00, - LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_100 = 0x01, - LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_9 = 0x02, - LSM6DS3TR_C_XL_LOW_LAT_LP_ODR_DIV_400 = 0x03, - LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_50 = 0x10, - LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_100 = 0x11, - LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_9 = 0x12, - LSM6DS3TR_C_XL_LOW_NOISE_LP_ODR_DIV_400 = 0x13, - LSM6DS3TR_C_XL_LP_NA = 0x20, /* ERROR CODE */ -} lsm6ds3tr_c_input_composite_t; -int32_t lsm6ds3tr_c_xl_lp2_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t val); -int32_t lsm6ds3tr_c_xl_lp2_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_input_composite_t* val); - -int32_t lsm6ds3tr_c_xl_reference_mode_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_xl_reference_mode_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_XL_HP_ODR_DIV_4 = 0x00, /* Slope filter */ - LSM6DS3TR_C_XL_HP_ODR_DIV_100 = 0x01, - LSM6DS3TR_C_XL_HP_ODR_DIV_9 = 0x02, - LSM6DS3TR_C_XL_HP_ODR_DIV_400 = 0x03, - LSM6DS3TR_C_XL_HP_NA = 0x10, /* ERROR CODE */ -} lsm6ds3tr_c_hpcf_xl_t; -int32_t lsm6ds3tr_c_xl_hp_bandwidth_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t val); -int32_t lsm6ds3tr_c_xl_hp_bandwidth_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_hpcf_xl_t* val); - -typedef enum { - LSM6DS3TR_C_LP2_ONLY = 0x00, - - LSM6DS3TR_C_HP_16mHz_LP2 = 0x80, - LSM6DS3TR_C_HP_65mHz_LP2 = 0x90, - LSM6DS3TR_C_HP_260mHz_LP2 = 0xA0, - LSM6DS3TR_C_HP_1Hz04_LP2 = 0xB0, - - LSM6DS3TR_C_HP_DISABLE_LP1_LIGHT = 0x0A, - LSM6DS3TR_C_HP_DISABLE_LP1_NORMAL = 0x09, - LSM6DS3TR_C_HP_DISABLE_LP_STRONG = 0x08, - LSM6DS3TR_C_HP_DISABLE_LP1_AGGRESSIVE = 0x0B, - - LSM6DS3TR_C_HP_16mHz_LP1_LIGHT = 0x8A, - LSM6DS3TR_C_HP_65mHz_LP1_NORMAL = 0x99, - LSM6DS3TR_C_HP_260mHz_LP1_STRONG = 0xA8, - LSM6DS3TR_C_HP_1Hz04_LP1_AGGRESSIVE = 0xBB, - - LSM6DS3TR_C_HP_GY_BAND_NA = 0xFF, /* ERROR CODE */ -} lsm6ds3tr_c_lpf1_sel_g_t; -int32_t lsm6ds3tr_c_gy_band_pass_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t val); -int32_t lsm6ds3tr_c_gy_band_pass_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lpf1_sel_g_t* val); - -typedef enum { - LSM6DS3TR_C_SPI_4_WIRE = 0, - LSM6DS3TR_C_SPI_3_WIRE = 1, - LSM6DS3TR_C_SPI_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_sim_t; -int32_t lsm6ds3tr_c_spi_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t val); -int32_t lsm6ds3tr_c_spi_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sim_t* val); - -typedef enum { - LSM6DS3TR_C_I2C_ENABLE = 0, - LSM6DS3TR_C_I2C_DISABLE = 1, - LSM6DS3TR_C_I2C_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_i2c_disable_t; -int32_t lsm6ds3tr_c_i2c_interface_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t val); -int32_t lsm6ds3tr_c_i2c_interface_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_i2c_disable_t* val); - -typedef struct { - uint8_t int1_drdy_xl : 1; - uint8_t int1_drdy_g : 1; - uint8_t int1_boot : 1; - uint8_t int1_fth : 1; - uint8_t int1_fifo_ovr : 1; - uint8_t int1_full_flag : 1; - uint8_t int1_sign_mot : 1; - uint8_t int1_step_detector : 1; - uint8_t int1_timer : 1; - uint8_t int1_tilt : 1; - uint8_t int1_6d : 1; - uint8_t int1_double_tap : 1; - uint8_t int1_ff : 1; - uint8_t int1_wu : 1; - uint8_t int1_single_tap : 1; - uint8_t int1_inact_state : 1; - uint8_t den_drdy_int1 : 1; - uint8_t drdy_on_int1 : 1; -} lsm6ds3tr_c_int1_route_t; -int32_t lsm6ds3tr_c_pin_int1_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t val); -int32_t lsm6ds3tr_c_pin_int1_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int1_route_t* val); - -typedef struct { - uint8_t int2_drdy_xl : 1; - uint8_t int2_drdy_g : 1; - uint8_t int2_drdy_temp : 1; - uint8_t int2_fth : 1; - uint8_t int2_fifo_ovr : 1; - uint8_t int2_full_flag : 1; - uint8_t int2_step_count_ov : 1; - uint8_t int2_step_delta : 1; - uint8_t int2_iron : 1; - uint8_t int2_tilt : 1; - uint8_t int2_6d : 1; - uint8_t int2_double_tap : 1; - uint8_t int2_ff : 1; - uint8_t int2_wu : 1; - uint8_t int2_single_tap : 1; - uint8_t int2_inact_state : 1; - uint8_t int2_wrist_tilt : 1; -} lsm6ds3tr_c_int2_route_t; -int32_t lsm6ds3tr_c_pin_int2_route_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t val); -int32_t lsm6ds3tr_c_pin_int2_route_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_int2_route_t* val); - -typedef enum { - LSM6DS3TR_C_PUSH_PULL = 0, - LSM6DS3TR_C_OPEN_DRAIN = 1, - LSM6DS3TR_C_PIN_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_pp_od_t; -int32_t lsm6ds3tr_c_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t val); -int32_t lsm6ds3tr_c_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pp_od_t* val); - -typedef enum { - LSM6DS3TR_C_ACTIVE_HIGH = 0, - LSM6DS3TR_C_ACTIVE_LOW = 1, - LSM6DS3TR_C_POLARITY_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_h_lactive_t; -int32_t lsm6ds3tr_c_pin_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t val); -int32_t lsm6ds3tr_c_pin_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_h_lactive_t* val); - -int32_t lsm6ds3tr_c_all_on_int1_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_all_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_INT_PULSED = 0, - LSM6DS3TR_C_INT_LATCHED = 1, - LSM6DS3TR_C_INT_MODE = 2, /* ERROR CODE */ -} lsm6ds3tr_c_lir_t; -int32_t lsm6ds3tr_c_int_notification_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t val); -int32_t lsm6ds3tr_c_int_notification_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_lir_t* val); - -int32_t lsm6ds3tr_c_wkup_threshold_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_wkup_threshold_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_wkup_dur_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_wkup_dur_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_gy_sleep_mode_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_gy_sleep_mode_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_PROPERTY_DISABLE = 0, - LSM6DS3TR_C_XL_12Hz5_GY_NOT_AFFECTED = 1, - LSM6DS3TR_C_XL_12Hz5_GY_SLEEP = 2, - LSM6DS3TR_C_XL_12Hz5_GY_PD = 3, - LSM6DS3TR_C_ACT_MODE_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_inact_en_t; -int32_t lsm6ds3tr_c_act_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t val); -int32_t lsm6ds3tr_c_act_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_inact_en_t* val); - -int32_t lsm6ds3tr_c_act_sleep_dur_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_act_sleep_dur_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_tap_src_t* val); - -int32_t lsm6ds3tr_c_tap_detection_on_z_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_detection_on_z_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_detection_on_y_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_detection_on_y_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_detection_on_x_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_detection_on_x_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_threshold_x_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_threshold_x_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_shock_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_shock_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_quiet_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_quiet_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tap_dur_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tap_dur_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_ONLY_SINGLE = 0, - LSM6DS3TR_C_BOTH_SINGLE_DOUBLE = 1, - LSM6DS3TR_C_TAP_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_single_double_tap_t; -int32_t lsm6ds3tr_c_tap_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t val); -int32_t lsm6ds3tr_c_tap_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_single_double_tap_t* val); - -typedef enum { - LSM6DS3TR_C_ODR_DIV_2_FEED = 0, - LSM6DS3TR_C_LPF2_FEED = 1, - LSM6DS3TR_C_6D_FEED_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_low_pass_on_6d_t; -int32_t lsm6ds3tr_c_6d_feed_data_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t val); -int32_t lsm6ds3tr_c_6d_feed_data_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_low_pass_on_6d_t* val); - -typedef enum { - LSM6DS3TR_C_DEG_80 = 0, - LSM6DS3TR_C_DEG_70 = 1, - LSM6DS3TR_C_DEG_60 = 2, - LSM6DS3TR_C_DEG_50 = 3, - LSM6DS3TR_C_6D_TH_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_sixd_ths_t; -int32_t lsm6ds3tr_c_6d_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t val); -int32_t lsm6ds3tr_c_6d_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_sixd_ths_t* val); - -int32_t lsm6ds3tr_c_4d_mode_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_4d_mode_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_ff_dur_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_ff_dur_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_FF_TSH_156mg = 0, - LSM6DS3TR_C_FF_TSH_219mg = 1, - LSM6DS3TR_C_FF_TSH_250mg = 2, - LSM6DS3TR_C_FF_TSH_312mg = 3, - LSM6DS3TR_C_FF_TSH_344mg = 4, - LSM6DS3TR_C_FF_TSH_406mg = 5, - LSM6DS3TR_C_FF_TSH_469mg = 6, - LSM6DS3TR_C_FF_TSH_500mg = 7, - LSM6DS3TR_C_FF_TSH_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_ff_ths_t; -int32_t lsm6ds3tr_c_ff_threshold_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t val); -int32_t lsm6ds3tr_c_ff_threshold_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_ff_ths_t* val); - -int32_t lsm6ds3tr_c_fifo_watermark_set(stmdev_ctx_t* ctx, uint16_t val); -int32_t lsm6ds3tr_c_fifo_watermark_get(stmdev_ctx_t* ctx, uint16_t* val); - -int32_t lsm6ds3tr_c_fifo_data_level_get(stmdev_ctx_t* ctx, uint16_t* val); - -int32_t lsm6ds3tr_c_fifo_wtm_flag_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_fifo_pattern_get(stmdev_ctx_t* ctx, uint16_t* val); - -int32_t lsm6ds3tr_c_fifo_temp_batch_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_fifo_temp_batch_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_TRG_XL_GY_DRDY = 0, - LSM6DS3TR_C_TRG_STEP_DETECT = 1, - LSM6DS3TR_C_TRG_SH_DRDY = 2, - LSM6DS3TR_C_TRG_SH_ND = 3, /* ERROR CODE */ -} lsm6ds3tr_c_trigger_fifo_t; -int32_t lsm6ds3tr_c_fifo_write_trigger_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t val); -int32_t lsm6ds3tr_c_fifo_write_trigger_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_trigger_fifo_t* val); - -int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_fifo_pedo_and_timestamp_batch_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_FIFO_XL_DISABLE = 0, - LSM6DS3TR_C_FIFO_XL_NO_DEC = 1, - LSM6DS3TR_C_FIFO_XL_DEC_2 = 2, - LSM6DS3TR_C_FIFO_XL_DEC_3 = 3, - LSM6DS3TR_C_FIFO_XL_DEC_4 = 4, - LSM6DS3TR_C_FIFO_XL_DEC_8 = 5, - LSM6DS3TR_C_FIFO_XL_DEC_16 = 6, - LSM6DS3TR_C_FIFO_XL_DEC_32 = 7, - LSM6DS3TR_C_FIFO_XL_DEC_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_dec_fifo_xl_t; -int32_t lsm6ds3tr_c_fifo_xl_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t val); -int32_t lsm6ds3tr_c_fifo_xl_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_xl_t* val); - -typedef enum { - LSM6DS3TR_C_FIFO_GY_DISABLE = 0, - LSM6DS3TR_C_FIFO_GY_NO_DEC = 1, - LSM6DS3TR_C_FIFO_GY_DEC_2 = 2, - LSM6DS3TR_C_FIFO_GY_DEC_3 = 3, - LSM6DS3TR_C_FIFO_GY_DEC_4 = 4, - LSM6DS3TR_C_FIFO_GY_DEC_8 = 5, - LSM6DS3TR_C_FIFO_GY_DEC_16 = 6, - LSM6DS3TR_C_FIFO_GY_DEC_32 = 7, - LSM6DS3TR_C_FIFO_GY_DEC_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_dec_fifo_gyro_t; -int32_t lsm6ds3tr_c_fifo_gy_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t val); -int32_t lsm6ds3tr_c_fifo_gy_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_fifo_gyro_t* val); - -typedef enum { - LSM6DS3TR_C_FIFO_DS3_DISABLE = 0, - LSM6DS3TR_C_FIFO_DS3_NO_DEC = 1, - LSM6DS3TR_C_FIFO_DS3_DEC_2 = 2, - LSM6DS3TR_C_FIFO_DS3_DEC_3 = 3, - LSM6DS3TR_C_FIFO_DS3_DEC_4 = 4, - LSM6DS3TR_C_FIFO_DS3_DEC_8 = 5, - LSM6DS3TR_C_FIFO_DS3_DEC_16 = 6, - LSM6DS3TR_C_FIFO_DS3_DEC_32 = 7, - LSM6DS3TR_C_FIFO_DS3_DEC_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_dec_ds3_fifo_t; -int32_t lsm6ds3tr_c_fifo_dataset_3_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t val); -int32_t lsm6ds3tr_c_fifo_dataset_3_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds3_fifo_t* val); - -typedef enum { - LSM6DS3TR_C_FIFO_DS4_DISABLE = 0, - LSM6DS3TR_C_FIFO_DS4_NO_DEC = 1, - LSM6DS3TR_C_FIFO_DS4_DEC_2 = 2, - LSM6DS3TR_C_FIFO_DS4_DEC_3 = 3, - LSM6DS3TR_C_FIFO_DS4_DEC_4 = 4, - LSM6DS3TR_C_FIFO_DS4_DEC_8 = 5, - LSM6DS3TR_C_FIFO_DS4_DEC_16 = 6, - LSM6DS3TR_C_FIFO_DS4_DEC_32 = 7, - LSM6DS3TR_C_FIFO_DS4_DEC_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_dec_ds4_fifo_t; -int32_t lsm6ds3tr_c_fifo_dataset_4_batch_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t val); -int32_t lsm6ds3tr_c_fifo_dataset_4_batch_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_dec_ds4_fifo_t* val); - -int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_fifo_xl_gy_8bit_format_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_fifo_stop_on_wtm_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_fifo_stop_on_wtm_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_BYPASS_MODE = 0, - LSM6DS3TR_C_FIFO_MODE = 1, - LSM6DS3TR_C_STREAM_TO_FIFO_MODE = 3, - LSM6DS3TR_C_BYPASS_TO_STREAM_MODE = 4, - LSM6DS3TR_C_STREAM_MODE = 6, - LSM6DS3TR_C_FIFO_MODE_ND = 8, /* ERROR CODE */ -} lsm6ds3tr_c_fifo_mode_t; -int32_t lsm6ds3tr_c_fifo_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t val); -int32_t lsm6ds3tr_c_fifo_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_fifo_mode_t* val); - -typedef enum { - LSM6DS3TR_C_FIFO_DISABLE = 0, - LSM6DS3TR_C_FIFO_12Hz5 = 1, - LSM6DS3TR_C_FIFO_26Hz = 2, - LSM6DS3TR_C_FIFO_52Hz = 3, - LSM6DS3TR_C_FIFO_104Hz = 4, - LSM6DS3TR_C_FIFO_208Hz = 5, - LSM6DS3TR_C_FIFO_416Hz = 6, - LSM6DS3TR_C_FIFO_833Hz = 7, - LSM6DS3TR_C_FIFO_1k66Hz = 8, - LSM6DS3TR_C_FIFO_3k33Hz = 9, - LSM6DS3TR_C_FIFO_6k66Hz = 10, - LSM6DS3TR_C_FIFO_RATE_ND = 11, /* ERROR CODE */ -} lsm6ds3tr_c_odr_fifo_t; -int32_t lsm6ds3tr_c_fifo_data_rate_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t val); -int32_t lsm6ds3tr_c_fifo_data_rate_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_odr_fifo_t* val); - -typedef enum { - LSM6DS3TR_C_DEN_ACT_LOW = 0, - LSM6DS3TR_C_DEN_ACT_HIGH = 1, - LSM6DS3TR_C_DEN_POL_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_den_lh_t; -int32_t lsm6ds3tr_c_den_polarity_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t val); -int32_t lsm6ds3tr_c_den_polarity_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_lh_t* val); - -typedef enum { - LSM6DS3TR_C_DEN_DISABLE = 0, - LSM6DS3TR_C_LEVEL_FIFO = 6, - LSM6DS3TR_C_LEVEL_LETCHED = 3, - LSM6DS3TR_C_LEVEL_TRIGGER = 2, - LSM6DS3TR_C_EDGE_TRIGGER = 4, - LSM6DS3TR_C_DEN_MODE_ND = 5, /* ERROR CODE */ -} lsm6ds3tr_c_den_mode_t; -int32_t lsm6ds3tr_c_den_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t val); -int32_t lsm6ds3tr_c_den_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_mode_t* val); - -typedef enum { - LSM6DS3TR_C_STAMP_IN_GY_DATA = 0, - LSM6DS3TR_C_STAMP_IN_XL_DATA = 1, - LSM6DS3TR_C_STAMP_IN_GY_XL_DATA = 2, - LSM6DS3TR_C_DEN_STAMP_ND = 3, /* ERROR CODE */ -} lsm6ds3tr_c_den_xl_en_t; -int32_t lsm6ds3tr_c_den_enable_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t val); -int32_t lsm6ds3tr_c_den_enable_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_den_xl_en_t* val); - -int32_t lsm6ds3tr_c_den_mark_axis_z_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_den_mark_axis_z_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_den_mark_axis_y_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_den_mark_axis_y_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_den_mark_axis_x_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_den_mark_axis_x_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_pedo_step_reset_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_pedo_step_reset_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_pedo_sens_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_pedo_sens_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_pedo_threshold_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_pedo_threshold_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_PEDO_AT_2g = 0, - LSM6DS3TR_C_PEDO_AT_4g = 1, - LSM6DS3TR_C_PEDO_FS_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_pedo_fs_t; -int32_t lsm6ds3tr_c_pedo_full_scale_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t val); -int32_t lsm6ds3tr_c_pedo_full_scale_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pedo_fs_t* val); - -int32_t lsm6ds3tr_c_pedo_debounce_steps_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_pedo_debounce_steps_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_pedo_timeout_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_pedo_timeout_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_pedo_steps_period_set(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_pedo_steps_period_get(stmdev_ctx_t* ctx, uint8_t* buff); - -int32_t lsm6ds3tr_c_motion_sens_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_motion_sens_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_motion_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_motion_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff); - -int32_t lsm6ds3tr_c_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_wrist_tilt_sens_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_wrist_tilt_sens_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_tilt_latency_set(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_tilt_latency_get(stmdev_ctx_t* ctx, uint8_t* buff); - -int32_t lsm6ds3tr_c_tilt_threshold_set(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_tilt_threshold_get(stmdev_ctx_t* ctx, uint8_t* buff); - -int32_t lsm6ds3tr_c_tilt_src_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val); -int32_t lsm6ds3tr_c_tilt_src_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_a_wrist_tilt_mask_t* val); - -int32_t lsm6ds3tr_c_mag_soft_iron_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_mag_soft_iron_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_mag_hard_iron_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_mag_hard_iron_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_mag_soft_iron_mat_set(stmdev_ctx_t* ctx, uint8_t* buff); -int32_t lsm6ds3tr_c_mag_soft_iron_mat_get(stmdev_ctx_t* ctx, uint8_t* buff); - -int32_t lsm6ds3tr_c_mag_offset_set(stmdev_ctx_t* ctx, int16_t* val); -int32_t lsm6ds3tr_c_mag_offset_get(stmdev_ctx_t* ctx, int16_t* val); - -int32_t lsm6ds3tr_c_func_en_set(stmdev_ctx_t* ctx, uint8_t val); - -int32_t lsm6ds3tr_c_sh_sync_sens_frame_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_sh_sync_sens_frame_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_RES_RATIO_2_11 = 0, - LSM6DS3TR_C_RES_RATIO_2_12 = 1, - LSM6DS3TR_C_RES_RATIO_2_13 = 2, - LSM6DS3TR_C_RES_RATIO_2_14 = 3, - LSM6DS3TR_C_RES_RATIO_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_rr_t; -int32_t lsm6ds3tr_c_sh_sync_sens_ratio_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t val); -int32_t lsm6ds3tr_c_sh_sync_sens_ratio_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_rr_t* val); - -int32_t lsm6ds3tr_c_sh_master_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_sh_master_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_sh_pass_through_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_sh_pass_through_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_EXT_PULL_UP = 0, - LSM6DS3TR_C_INTERNAL_PULL_UP = 1, - LSM6DS3TR_C_SH_PIN_MODE = 2, /* ERROR CODE */ -} lsm6ds3tr_c_pull_up_en_t; -int32_t lsm6ds3tr_c_sh_pin_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t val); -int32_t lsm6ds3tr_c_sh_pin_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_pull_up_en_t* val); - -typedef enum { - LSM6DS3TR_C_XL_GY_DRDY = 0, - LSM6DS3TR_C_EXT_ON_INT2_PIN = 1, - LSM6DS3TR_C_SH_SYNCRO_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_start_config_t; -int32_t lsm6ds3tr_c_sh_syncro_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t val); -int32_t lsm6ds3tr_c_sh_syncro_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_start_config_t* val); - -int32_t lsm6ds3tr_c_sh_drdy_on_int1_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_sh_drdy_on_int1_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef struct { - lsm6ds3tr_c_sensorhub1_reg_t sh_byte_1; - lsm6ds3tr_c_sensorhub2_reg_t sh_byte_2; - lsm6ds3tr_c_sensorhub3_reg_t sh_byte_3; - lsm6ds3tr_c_sensorhub4_reg_t sh_byte_4; - lsm6ds3tr_c_sensorhub5_reg_t sh_byte_5; - lsm6ds3tr_c_sensorhub6_reg_t sh_byte_6; - lsm6ds3tr_c_sensorhub7_reg_t sh_byte_7; - lsm6ds3tr_c_sensorhub8_reg_t sh_byte_8; - lsm6ds3tr_c_sensorhub9_reg_t sh_byte_9; - lsm6ds3tr_c_sensorhub10_reg_t sh_byte_10; - lsm6ds3tr_c_sensorhub11_reg_t sh_byte_11; - lsm6ds3tr_c_sensorhub12_reg_t sh_byte_12; - lsm6ds3tr_c_sensorhub13_reg_t sh_byte_13; - lsm6ds3tr_c_sensorhub14_reg_t sh_byte_14; - lsm6ds3tr_c_sensorhub15_reg_t sh_byte_15; - lsm6ds3tr_c_sensorhub16_reg_t sh_byte_16; - lsm6ds3tr_c_sensorhub17_reg_t sh_byte_17; - lsm6ds3tr_c_sensorhub18_reg_t sh_byte_18; -} lsm6ds3tr_c_emb_sh_read_t; -int32_t lsm6ds3tr_c_sh_read_data_raw_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_emb_sh_read_t* val); - -int32_t lsm6ds3tr_c_sh_cmd_sens_sync_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_sh_cmd_sens_sync_get(stmdev_ctx_t* ctx, uint8_t* val); - -int32_t lsm6ds3tr_c_sh_spi_sync_error_set(stmdev_ctx_t* ctx, uint8_t val); -int32_t lsm6ds3tr_c_sh_spi_sync_error_get(stmdev_ctx_t* ctx, uint8_t* val); - -typedef enum { - LSM6DS3TR_C_SLV_0 = 0, - LSM6DS3TR_C_SLV_0_1 = 1, - LSM6DS3TR_C_SLV_0_1_2 = 2, - LSM6DS3TR_C_SLV_0_1_2_3 = 3, - LSM6DS3TR_C_SLV_EN_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_aux_sens_on_t; -int32_t lsm6ds3tr_c_sh_num_of_dev_connected_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t val); -int32_t lsm6ds3tr_c_sh_num_of_dev_connected_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_aux_sens_on_t* val); - -typedef struct { - uint8_t slv0_add; - uint8_t slv0_subadd; - uint8_t slv0_data; -} lsm6ds3tr_c_sh_cfg_write_t; -int32_t lsm6ds3tr_c_sh_cfg_write(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_write_t* val); - -typedef struct { - uint8_t slv_add; - uint8_t slv_subadd; - uint8_t slv_len; -} lsm6ds3tr_c_sh_cfg_read_t; -int32_t lsm6ds3tr_c_sh_slv0_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); -int32_t lsm6ds3tr_c_sh_slv1_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); -int32_t lsm6ds3tr_c_sh_slv2_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); -int32_t lsm6ds3tr_c_sh_slv3_cfg_read(stmdev_ctx_t* ctx, lsm6ds3tr_c_sh_cfg_read_t* val); - -typedef enum { - LSM6DS3TR_C_SL0_NO_DEC = 0, - LSM6DS3TR_C_SL0_DEC_2 = 1, - LSM6DS3TR_C_SL0_DEC_4 = 2, - LSM6DS3TR_C_SL0_DEC_8 = 3, - LSM6DS3TR_C_SL0_DEC_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_slave0_rate_t; -int32_t lsm6ds3tr_c_sh_slave_0_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t val); -int32_t lsm6ds3tr_c_sh_slave_0_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave0_rate_t* val); - -typedef enum { - LSM6DS3TR_C_EACH_SH_CYCLE = 0, - LSM6DS3TR_C_ONLY_FIRST_CYCLE = 1, - LSM6DS3TR_C_SH_WR_MODE_ND = 2, /* ERROR CODE */ -} lsm6ds3tr_c_write_once_t; -int32_t lsm6ds3tr_c_sh_write_mode_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t val); -int32_t lsm6ds3tr_c_sh_write_mode_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_write_once_t* val); - -typedef enum { - LSM6DS3TR_C_SL1_NO_DEC = 0, - LSM6DS3TR_C_SL1_DEC_2 = 1, - LSM6DS3TR_C_SL1_DEC_4 = 2, - LSM6DS3TR_C_SL1_DEC_8 = 3, - LSM6DS3TR_C_SL1_DEC_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_slave1_rate_t; -int32_t lsm6ds3tr_c_sh_slave_1_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t val); -int32_t lsm6ds3tr_c_sh_slave_1_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave1_rate_t* val); - -typedef enum { - LSM6DS3TR_C_SL2_NO_DEC = 0, - LSM6DS3TR_C_SL2_DEC_2 = 1, - LSM6DS3TR_C_SL2_DEC_4 = 2, - LSM6DS3TR_C_SL2_DEC_8 = 3, - LSM6DS3TR_C_SL2_DEC_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_slave2_rate_t; -int32_t lsm6ds3tr_c_sh_slave_2_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t val); -int32_t lsm6ds3tr_c_sh_slave_2_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave2_rate_t* val); - -typedef enum { - LSM6DS3TR_C_SL3_NO_DEC = 0, - LSM6DS3TR_C_SL3_DEC_2 = 1, - LSM6DS3TR_C_SL3_DEC_4 = 2, - LSM6DS3TR_C_SL3_DEC_8 = 3, - LSM6DS3TR_C_SL3_DEC_ND = 4, /* ERROR CODE */ -} lsm6ds3tr_c_slave3_rate_t; -int32_t lsm6ds3tr_c_sh_slave_3_dec_set(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t val); -int32_t lsm6ds3tr_c_sh_slave_3_dec_get(stmdev_ctx_t* ctx, lsm6ds3tr_c_slave3_rate_t* val); - -/** - * @} - * - */ - -#ifdef __cplusplus -} -#endif - -#endif /* LSM6DS3TR_C_DRIVER_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/non_catalog_apps/airmouse/tracking/imu/imu_lsm6ds3trc.c b/non_catalog_apps/airmouse/tracking/imu/lsm6ds3trc.c similarity index 73% rename from non_catalog_apps/airmouse/tracking/imu/imu_lsm6ds3trc.c rename to non_catalog_apps/airmouse/tracking/imu/lsm6ds3trc.c index c013fc6e611..9ea6cebe860 100644 --- a/non_catalog_apps/airmouse/tracking/imu/imu_lsm6ds3trc.c +++ b/non_catalog_apps/airmouse/tracking/imu/lsm6ds3trc.c @@ -1,33 +1,27 @@ -#include "lsm6ds3tr_c_reg.h" - -#include - #include "imu.h" +#include "../../lib/lsm6ds3tr-api/lsm6ds3tr-c_reg.h" -#define TAG "LSM6DS3TR-C" - -#define LSM6DS3_ADDRESS (0x6A << 1) - -static const double DEG_TO_RAD = 0.017453292519943295769236907684886; +#define LSM6DS3_TAG "LSM6DS3" +#define LSM6DS3_DEV_ADDRESS (0x6A << 1) stmdev_ctx_t lsm6ds3trc_ctx; int32_t lsm6ds3trc_write_i2c(void* handle, uint8_t reg_addr, const uint8_t* data, uint16_t len) { - if(furi_hal_i2c_write_mem(handle, LSM6DS3_ADDRESS, reg_addr, (uint8_t*)data, len, 50)) + if(furi_hal_i2c_write_mem(handle, LSM6DS3_DEV_ADDRESS, reg_addr, (uint8_t*)data, len, 50)) return 0; return -1; } int32_t lsm6ds3trc_read_i2c(void* handle, uint8_t reg_addr, uint8_t* read_data, uint16_t len) { - if(furi_hal_i2c_read_mem(handle, LSM6DS3_ADDRESS, reg_addr, read_data, len, 50)) return 0; + if(furi_hal_i2c_read_mem(handle, LSM6DS3_DEV_ADDRESS, reg_addr, read_data, len, 50)) return 0; return -1; } bool lsm6ds3trc_begin() { - FURI_LOG_I(TAG, "Init LSM6DS3TR-C"); + FURI_LOG_I(LSM6DS3_TAG, "Init LSM6DS3TR-C"); - if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, LSM6DS3_ADDRESS, 50)) { - FURI_LOG_E(TAG, "Not ready"); + if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, LSM6DS3_DEV_ADDRESS, 50)) { + FURI_LOG_E(LSM6DS3_TAG, "Not ready"); return false; } @@ -39,7 +33,7 @@ bool lsm6ds3trc_begin() { uint8_t whoami; lsm6ds3tr_c_device_id_get(&lsm6ds3trc_ctx, &whoami); if(whoami != LSM6DS3TR_C_ID) { - FURI_LOG_I(TAG, "Unknown model: %x", (int)whoami); + FURI_LOG_I(LSM6DS3_TAG, "Unknown model: %x", (int)whoami); return false; } @@ -59,7 +53,7 @@ bool lsm6ds3trc_begin() { lsm6ds3tr_c_gy_power_mode_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_GY_HIGH_PERFORMANCE); lsm6ds3tr_c_gy_band_pass_set(&lsm6ds3trc_ctx, LSM6DS3TR_C_LP2_ONLY); - FURI_LOG_I(TAG, "Init OK"); + FURI_LOG_I(LSM6DS3_TAG, "Init OK"); return true; } @@ -76,19 +70,22 @@ int lsm6ds3trc_read(double* vec) { if(reg.status_reg.xlda) { lsm6ds3tr_c_acceleration_raw_get(&lsm6ds3trc_ctx, data); - vec[2] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[0]) / 1000; + vec[1] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[0]) / 1000; vec[0] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[1]) / 1000; - vec[1] = (double)lsm6ds3tr_c_from_fs2g_to_mg(data[2]) / 1000; + vec[2] = -(double)lsm6ds3tr_c_from_fs2g_to_mg(data[2]) / 1000; ret |= ACC_DATA_READY; } if(reg.status_reg.gda) { lsm6ds3tr_c_angular_rate_raw_get(&lsm6ds3trc_ctx, data); - vec[5] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[0]) * DEG_TO_RAD / 1000; + vec[4] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[0]) * DEG_TO_RAD / 1000; vec[3] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[1]) * DEG_TO_RAD / 1000; - vec[4] = (double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[2]) * DEG_TO_RAD / 1000; + vec[5] = -(double)lsm6ds3tr_c_from_fs2000dps_to_mdps(data[2]) * DEG_TO_RAD / 1000; ret |= GYR_DATA_READY; } return ret; } + +struct imu_t imu_lsm6ds3trc = + {LSM6DS3_DEV_ADDRESS, lsm6ds3trc_begin, lsm6ds3trc_end, lsm6ds3trc_read, LSM6DS3_TAG}; diff --git a/non_catalog_apps/airmouse/tracking/imu/lsm6dso.c b/non_catalog_apps/airmouse/tracking/imu/lsm6dso.c new file mode 100644 index 00000000000..01b1020c07c --- /dev/null +++ b/non_catalog_apps/airmouse/tracking/imu/lsm6dso.c @@ -0,0 +1,90 @@ +#include "imu.h" +#include "../../lib/lsm6dso-api/lsm6dso_reg.h" + +#define LSM6DSO_TAG "LSM6DO" +#define LSM6DSO_DEV_ADDRESS (0x6B << 1) + +stmdev_ctx_t lsm6dso_ctx; + +int32_t lsm6dso_write_i2c(void* handle, uint8_t reg_addr, uint8_t* data, uint16_t len) { + if(furi_hal_i2c_write_mem(handle, LSM6DSO_DEV_ADDRESS, reg_addr, data, len, 50)) return 0; + return -2; +} + +int32_t lsm6dso_read_i2c(void* handle, uint8_t reg_addr, uint8_t* read_data, uint16_t len) { + if(furi_hal_i2c_read_mem(handle, LSM6DSO_DEV_ADDRESS, reg_addr, read_data, len, 50)) return 0; + return -2; +} + +bool lsm6dso_begin() { + FURI_LOG_I(LSM6DSO_TAG, "Init LSM6DSOTR-C"); + + if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, LSM6DSO_DEV_ADDRESS, 50)) { + FURI_LOG_E(LSM6DSO_TAG, "Not ready"); + return false; + } + + lsm6dso_ctx.write_reg = lsm6dso_write_i2c; + lsm6dso_ctx.read_reg = lsm6dso_read_i2c; + lsm6dso_ctx.mdelay = furi_delay_ms; + lsm6dso_ctx.handle = &furi_hal_i2c_handle_external; + + uint8_t whoami; + lsm6dso_device_id_get(&lsm6dso_ctx, &whoami); + if(whoami != LSM6DSO_ID) { + FURI_LOG_I(LSM6DSO_TAG, "Unknown model: %x", (int)whoami); + return false; + } + + lsm6dso_reset_set(&lsm6dso_ctx, PROPERTY_ENABLE); + uint8_t rst = PROPERTY_ENABLE; + while(rst) lsm6dso_reset_get(&lsm6dso_ctx, &rst); + + lsm6dso_block_data_update_set(&lsm6dso_ctx, PROPERTY_ENABLE); + lsm6dso_fifo_mode_set(&lsm6dso_ctx, LSM6DSO_BYPASS_MODE); + + lsm6dso_xl_data_rate_set(&lsm6dso_ctx, LSM6DSO_XL_ODR_104Hz); + lsm6dso_xl_full_scale_set(&lsm6dso_ctx, LSM6DSO_4g); + //lsm6dso_xl_lp1_bandwidth_set(&lsm6dso_ctx, LSM6DSO_XL_LP1_ODR_DIV_4); + + lsm6dso_gy_data_rate_set(&lsm6dso_ctx, LSM6DSO_GY_ODR_104Hz); + lsm6dso_gy_full_scale_set(&lsm6dso_ctx, LSM6DSO_2000dps); + lsm6dso_gy_power_mode_set(&lsm6dso_ctx, LSM6DSO_GY_HIGH_PERFORMANCE); + //lsm6dso_gy_band_pass_set(&lsm6dso_ctx, LSM6DSO_LP2_ONLY); + + FURI_LOG_I(LSM6DSO_TAG, "Init OK"); + return true; +} + +void lsm6dso_end() { + lsm6dso_xl_data_rate_set(&lsm6dso_ctx, LSM6DSO_XL_ODR_OFF); + lsm6dso_gy_data_rate_set(&lsm6dso_ctx, LSM6DSO_GY_ODR_OFF); +} + +int lsm6dso_read(double* vec) { + int ret = 0; + int16_t data[3]; + lsm6dso_reg_t reg; + lsm6dso_status_reg_get(&lsm6dso_ctx, ®.status_reg); + + if(reg.status_reg.xlda) { + lsm6dso_acceleration_raw_get(&lsm6dso_ctx, data); + vec[2] = (double)lsm6dso_from_fs2_to_mg(data[0]) / 1000; + vec[0] = (double)lsm6dso_from_fs2_to_mg(data[1]) / 1000; + vec[1] = (double)lsm6dso_from_fs2_to_mg(data[2]) / 1000; + ret |= ACC_DATA_READY; + } + + if(reg.status_reg.gda) { + lsm6dso_angular_rate_raw_get(&lsm6dso_ctx, data); + vec[5] = (double)lsm6dso_from_fs2000_to_mdps(data[0]) * DEG_TO_RAD / 1000; + vec[3] = (double)lsm6dso_from_fs2000_to_mdps(data[1]) * DEG_TO_RAD / 1000; + vec[4] = (double)lsm6dso_from_fs2000_to_mdps(data[2]) * DEG_TO_RAD / 1000; + ret |= GYR_DATA_READY; + } + + return ret; +} + +struct imu_t imu_lsm6dso = + {LSM6DSO_DEV_ADDRESS, lsm6dso_begin, lsm6dso_end, lsm6dso_read, LSM6DSO_TAG}; From 38a956f119d509c255f7ef60e094a8f320bd443b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 12:48:13 +0300 Subject: [PATCH 13/36] upd nfc playlist --- non_catalog_apps/nfc_playlist/README.md | 7 +- non_catalog_apps/nfc_playlist/application.fam | 4 +- .../nfc_playlist_emulation_worker.c | 84 +++++++++++++++++++ .../nfc_playlist_emulation_worker.h | 35 ++++++++ .../lib/worker/nfc_playlist_worker.c | 73 ---------------- .../lib/worker/nfc_playlist_worker.h | 31 ------- non_catalog_apps/nfc_playlist/nfc_playlist.c | 9 +- non_catalog_apps/nfc_playlist/nfc_playlist.h | 13 +-- .../nfc_playlist_scene_confirm_delete.c | 24 +++--- .../scenes/nfc_playlist_scene_emulation.c | 71 ++++++++++------ .../scenes/nfc_playlist_scene_main_menu.c | 22 ++--- .../nfc_playlist_scene_name_new_playlist.c | 52 ++++++++---- .../scenes/nfc_playlist_scene_nfc_remove.c | 22 ++--- .../scenes/nfc_playlist_scene_playlist_edit.c | 12 +-- .../nfc_playlist_scene_playlist_rename.c | 48 +++++++---- .../scenes/nfc_playlist_scene_settings.c | 19 +++-- ...nfc_playlist_scene_view_playlist_content.c | 1 - 17 files changed, 299 insertions(+), 228 deletions(-) create mode 100644 non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.c create mode 100644 non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.h delete mode 100644 non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.c delete mode 100644 non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.h diff --git a/non_catalog_apps/nfc_playlist/README.md b/non_catalog_apps/nfc_playlist/README.md index 5c38a3e09a7..56c0a7133a9 100644 --- a/non_catalog_apps/nfc_playlist/README.md +++ b/non_catalog_apps/nfc_playlist/README.md @@ -29,10 +29,5 @@ As i know these firmwares are supported and working if you know any more please - Add NFC Item (Adds the selected nfc item to the currently selected playlist) - Remove NFC Item (Opens a menu allowing you to select a line to remove from the playlist) - View playlist content (Allows you to view the contents of the playlist) -## Development plans/ideas: -Things i would like to add: -- Ability to remove cards from the playlist -These features are not guaranteed to be added but are being looked at as features to add - -Any feedback is welcome and would be very much appreciated +Any feedback is welcome and would be very much appreciated \ No newline at end of file diff --git a/non_catalog_apps/nfc_playlist/application.fam b/non_catalog_apps/nfc_playlist/application.fam index 9532f952769..fb399d0da5c 100644 --- a/non_catalog_apps/nfc_playlist/application.fam +++ b/non_catalog_apps/nfc_playlist/application.fam @@ -8,12 +8,12 @@ App( fap_category="NFC", fap_author="@acegoal07", fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main", - fap_version="2.1", + fap_version="2.2", fap_icon_assets="assets", fap_icon="icon.png", fap_private_libs=[ Lib( - name="worker", + name="emulation_worker", ), ], ) diff --git a/non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.c b/non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.c new file mode 100644 index 00000000000..79855b49ef2 --- /dev/null +++ b/non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.c @@ -0,0 +1,84 @@ +#include "nfc_playlist_emulation_worker.h" + +NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker_alloc() { + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker = + malloc(sizeof(NfcPlaylistEmulationWorker)); + nfc_playlist_emulation_worker->thread = furi_thread_alloc_ex( + "NfcPlaylistEmulationWorker", + 4096, + nfc_playlist_emulation_worker_task, + nfc_playlist_emulation_worker); + nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped; + nfc_playlist_emulation_worker->nfc = nfc_alloc(); + nfc_playlist_emulation_worker->nfc_device = nfc_device_alloc(); + return nfc_playlist_emulation_worker; +} + +void nfc_playlist_emulation_worker_free(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) { + furi_assert(nfc_playlist_emulation_worker); + furi_thread_free(nfc_playlist_emulation_worker->thread); + nfc_free(nfc_playlist_emulation_worker->nfc); + nfc_device_free(nfc_playlist_emulation_worker->nfc_device); + free(nfc_playlist_emulation_worker); +} + +void nfc_playlist_emulation_worker_stop(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) { + furi_assert(nfc_playlist_emulation_worker); + if(nfc_playlist_emulation_worker->state != NfcPlaylistEmulationWorkerState_Stopped) { + nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped; + furi_thread_join(nfc_playlist_emulation_worker->thread); + } +} + +void nfc_playlist_emulation_worker_start( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) { + furi_assert(nfc_playlist_emulation_worker); + nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Emulating; + furi_thread_start(nfc_playlist_emulation_worker->thread); +} + +int32_t nfc_playlist_emulation_worker_task(void* context) { + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker = context; + + if(nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating) { + nfc_playlist_emulation_worker->nfc_listener = nfc_listener_alloc( + nfc_playlist_emulation_worker->nfc, + nfc_playlist_emulation_worker->nfc_protocol, + nfc_device_get_data( + nfc_playlist_emulation_worker->nfc_device, + nfc_playlist_emulation_worker->nfc_protocol)); + nfc_listener_start(nfc_playlist_emulation_worker->nfc_listener, NULL, NULL); + + while(nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating) { + furi_delay_ms(50); + } + + nfc_listener_stop(nfc_playlist_emulation_worker->nfc_listener); + nfc_listener_free(nfc_playlist_emulation_worker->nfc_listener); + } + + nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped; + + return 0; +} + +bool nfc_playlist_emulation_worker_is_emulating( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) { + furi_assert(nfc_playlist_emulation_worker); + return nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating; +} + +void nfc_playlist_emulation_worker_set_nfc_data( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker, + char* file_path) { + furi_assert(nfc_playlist_emulation_worker); + nfc_device_load(nfc_playlist_emulation_worker->nfc_device, file_path); + nfc_playlist_emulation_worker->nfc_protocol = + nfc_device_get_protocol(nfc_playlist_emulation_worker->nfc_device); +} + +void nfc_playlist_emulation_worker_clear_nfc_data( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) { + furi_assert(nfc_playlist_emulation_worker); + nfc_device_clear(nfc_playlist_emulation_worker->nfc_device); +} \ No newline at end of file diff --git a/non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.h b/non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.h new file mode 100644 index 00000000000..baddbff44ac --- /dev/null +++ b/non_catalog_apps/nfc_playlist/lib/emulation_worker/nfc_playlist_emulation_worker.h @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#include +#include +#include + +typedef enum NfcPlaylistEmulationWorkerState { + NfcPlaylistEmulationWorkerState_Emulating, + NfcPlaylistEmulationWorkerState_Stopped +} NfcPlaylistEmulationWorkerState; + +typedef struct NfcPlaylistEmulationWorker { + FuriThread* thread; + NfcPlaylistEmulationWorkerState state; + NfcListener* nfc_listener; + NfcDevice* nfc_device; + NfcProtocol nfc_protocol; + Nfc* nfc; +} NfcPlaylistEmulationWorker; + +NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker_alloc(); +void nfc_playlist_emulation_worker_free(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker); +void nfc_playlist_emulation_worker_stop(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker); +void nfc_playlist_emulation_worker_start(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker); + +int32_t nfc_playlist_emulation_worker_task(void* context); + +bool nfc_playlist_emulation_worker_is_emulating( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker); +void nfc_playlist_emulation_worker_set_nfc_data( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker, + char* file_path); +void nfc_playlist_emulation_worker_clear_nfc_data( + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker); \ No newline at end of file diff --git a/non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.c b/non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.c deleted file mode 100644 index 8ae0641e2fc..00000000000 --- a/non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "nfc_playlist_worker.h" - -NfcPlaylistWorker* nfc_playlist_worker_alloc() { - NfcPlaylistWorker* nfc_playlist_worker = malloc(sizeof(NfcPlaylistWorker)); - nfc_playlist_worker->thread = furi_thread_alloc_ex("NfcPlaylistWorker", 8192, nfc_playlist_worker_task, nfc_playlist_worker); - nfc_playlist_worker->state = NfcPlaylistWorkerState_Stopped; - nfc_playlist_worker->nfc = nfc_alloc(); - nfc_playlist_worker->nfc_device = nfc_device_alloc(); - return nfc_playlist_worker; -} - -void nfc_playlist_worker_free(NfcPlaylistWorker* nfc_playlist_worker) { - furi_assert(nfc_playlist_worker); - furi_thread_free(nfc_playlist_worker->thread); - nfc_free(nfc_playlist_worker->nfc); - nfc_device_free(nfc_playlist_worker->nfc_device); - free(nfc_playlist_worker); -} - -void nfc_playlist_worker_stop(NfcPlaylistWorker* nfc_playlist_worker) { - furi_assert(nfc_playlist_worker); - if (nfc_playlist_worker->state != NfcPlaylistWorkerState_Stopped) { - nfc_playlist_worker->state = NfcPlaylistWorkerState_Stopped; - furi_thread_join(nfc_playlist_worker->thread); - } -} - -void nfc_playlist_worker_start(NfcPlaylistWorker* nfc_playlist_worker) { - furi_assert(nfc_playlist_worker); - nfc_playlist_worker->state = NfcPlaylistWorkerState_Emulating; - furi_thread_start(nfc_playlist_worker->thread); -} - -int32_t nfc_playlist_worker_task(void* context) { - NfcPlaylistWorker* nfc_playlist_worker = context; - - if (nfc_playlist_worker->state == NfcPlaylistWorkerState_Emulating) { - - nfc_playlist_worker->nfc_listener = - nfc_listener_alloc(nfc_playlist_worker->nfc, - nfc_playlist_worker->nfc_protocol, - nfc_device_get_data(nfc_playlist_worker->nfc_device, nfc_playlist_worker->nfc_protocol) - ); - nfc_listener_start(nfc_playlist_worker->nfc_listener, NULL, NULL); - - while(nfc_playlist_worker->state == NfcPlaylistWorkerState_Emulating) { - furi_delay_ms(50); - } - - nfc_listener_stop(nfc_playlist_worker->nfc_listener); - nfc_listener_free(nfc_playlist_worker->nfc_listener); - } - - nfc_playlist_worker->state = NfcPlaylistWorkerState_Stopped; - - return 0; -} - -bool nfc_playlist_worker_is_emulating(NfcPlaylistWorker* nfc_playlist_worker) { - furi_assert(nfc_playlist_worker); - return nfc_playlist_worker->state == NfcPlaylistWorkerState_Emulating; -} - -void nfc_playlist_worker_set_nfc_data(NfcPlaylistWorker* nfc_playlist_worker, char* file_path) { - furi_assert(nfc_playlist_worker); - nfc_device_load(nfc_playlist_worker->nfc_device, file_path); - nfc_playlist_worker->nfc_protocol = nfc_device_get_protocol(nfc_playlist_worker->nfc_device); -} - -void nfc_playlist_worker_clear_nfc_data(NfcPlaylistWorker* nfc_playlist_worker) { - furi_assert(nfc_playlist_worker); - nfc_device_clear(nfc_playlist_worker->nfc_device); -} \ No newline at end of file diff --git a/non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.h b/non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.h deleted file mode 100644 index 511ea7d2991..00000000000 --- a/non_catalog_apps/nfc_playlist/lib/worker/nfc_playlist_worker.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -typedef enum NfcPlaylistWorkerState { - NfcPlaylistWorkerState_Emulating, - NfcPlaylistWorkerState_Stopped -} NfcPlaylistWorkerState; - -typedef struct NfcPlaylistWorker { - FuriThread* thread; - NfcPlaylistWorkerState state; - NfcListener* nfc_listener; - NfcDevice* nfc_device; - NfcProtocol nfc_protocol; - Nfc* nfc; -} NfcPlaylistWorker; - -NfcPlaylistWorker* nfc_playlist_worker_alloc(); -void nfc_playlist_worker_free(NfcPlaylistWorker* nfc_playlist_worker); -void nfc_playlist_worker_stop(NfcPlaylistWorker* nfc_playlist_worker); -void nfc_playlist_worker_start(NfcPlaylistWorker* nfc_playlist_worker); - -int32_t nfc_playlist_worker_task(void* context); - -bool nfc_playlist_worker_is_emulating(NfcPlaylistWorker* nfc_playlist_worker); -void nfc_playlist_worker_set_nfc_data(NfcPlaylistWorker* nfc_playlist_worker, char* file_path); -void nfc_playlist_worker_clear_nfc_data(NfcPlaylistWorker* nfc_playlist_worker); \ No newline at end of file diff --git a/non_catalog_apps/nfc_playlist/nfc_playlist.c b/non_catalog_apps/nfc_playlist/nfc_playlist.c index 2d6bc261188..640b381bfda 100644 --- a/non_catalog_apps/nfc_playlist/nfc_playlist.c +++ b/non_catalog_apps/nfc_playlist/nfc_playlist.c @@ -66,9 +66,8 @@ static NfcPlaylist* nfc_playlist_alloc() { text_input_get_view(nfc_playlist->text_input)); Storage* storage = furi_record_open(RECORD_STORAGE); - if(!storage_common_exists(storage, PLAYLIST_DIR)) { - storage_common_mkdir(storage, PLAYLIST_DIR); - } + storage_simply_mkdir(storage, PLAYLIST_DIR); + furi_record_close(RECORD_STORAGE); return nfc_playlist; @@ -86,11 +85,11 @@ static void nfc_playlist_free(NfcPlaylist* nfc_playlist) { scene_manager_free(nfc_playlist->scene_manager); view_dispatcher_free(nfc_playlist->view_dispatcher); + furi_record_close(RECORD_NOTIFICATION); + variable_item_list_free(nfc_playlist->variable_item_list); submenu_free(nfc_playlist->submenu); widget_free(nfc_playlist->widget); - - furi_record_close(RECORD_NOTIFICATION); file_browser_free(nfc_playlist->file_browser); text_input_free(nfc_playlist->text_input); popup_free(nfc_playlist->popup); diff --git a/non_catalog_apps/nfc_playlist/nfc_playlist.h b/non_catalog_apps/nfc_playlist/nfc_playlist.h index bd271a9d489..9625109eba7 100644 --- a/non_catalog_apps/nfc_playlist/nfc_playlist.h +++ b/non_catalog_apps/nfc_playlist/nfc_playlist.h @@ -23,11 +23,16 @@ #include #include +#include -#include "lib/worker/nfc_playlist_worker.h" +#include "lib/emulation_worker/nfc_playlist_emulation_worker.h" #include "scenes/nfc_playlist_scene.h" +#define PLAYLIST_LOCATION "/ext/apps_data/nfc_playlist/" +#define PLAYLIST_DIR "/ext/apps_data/nfc_playlist" +#define MAX_PLAYLIST_NAME_LEN 50 + typedef enum { NfcPlaylistView_Submenu, NfcPlaylistView_Popup, @@ -60,8 +65,7 @@ typedef struct { char* text_input_output; NotificationApp* notification; FuriThread* thread; - FuriString* temp_furi_string; - NfcPlaylistWorker* nfc_playlist_worker; + NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker; NfcPlaylistSettings settings; } NfcPlaylist; @@ -72,9 +76,6 @@ static const int default_emulate_delay = 0; static const bool default_emulate_led_indicator = true; static const bool default_skip_error = false; -#define PLAYLIST_LOCATION "/ext/apps_data/nfc_playlist/" -#define PLAYLIST_DIR "/ext/apps_data/nfc_playlist" - typedef enum NfcPlaylistLedState { NfcPlaylistLedState_Normal, NfcPlaylistLedState_Error diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_confirm_delete.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_confirm_delete.c index 41fa831f9b2..2125b4a9e08 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_confirm_delete.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_confirm_delete.c @@ -10,13 +10,11 @@ void nfc_playlist_confirm_delete_menu_callback(GuiButtonType result, InputType t void nfc_playlist_confirm_delete_scene_on_enter(void* context) { NfcPlaylist* nfc_playlist = context; - FuriString* temp_str = furi_string_alloc(); - char* file_path = (char*)furi_string_get_cstr(nfc_playlist->settings.playlist_path); - furi_string_printf( - temp_str, - "\e#Delete %s?\e#", - strchr(file_path, '/') != NULL ? &strrchr(file_path, '/')[1] : file_path); - furi_string_replace(temp_str, ".txt", ""); + FuriString* file_name = furi_string_alloc(); + path_extract_filename_no_ext( + furi_string_get_cstr(nfc_playlist->settings.playlist_path), file_name); + FuriString* temp_str = + furi_string_alloc_printf("\e#Delete %s?\e#", furi_string_get_cstr(file_name)); widget_add_text_box_element( nfc_playlist->widget, @@ -42,6 +40,7 @@ void nfc_playlist_confirm_delete_scene_on_enter(void* context) { nfc_playlist); furi_string_free(temp_str); + furi_string_free(file_name); view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Widget); } @@ -53,14 +52,15 @@ bool nfc_playlist_confirm_delete_scene_on_event(void* context, SceneManagerEvent switch(event.event) { case GuiButtonTypeRight: Storage* storage = furi_record_open(RECORD_STORAGE); - storage_simply_remove( - storage, furi_string_get_cstr(nfc_playlist->settings.playlist_path)); - nfc_playlist->settings.playlist_selected = false; - furi_string_reset(nfc_playlist->settings.playlist_path); + if(storage_simply_remove( + storage, furi_string_get_cstr(nfc_playlist->settings.playlist_path))) { + nfc_playlist->settings.playlist_selected = false; + furi_string_reset(nfc_playlist->settings.playlist_path); + } furi_record_close(RECORD_STORAGE); - consumed = true; scene_manager_search_and_switch_to_previous_scene( nfc_playlist->scene_manager, NfcPlaylistScene_MainMenu); + consumed = true; break; default: scene_manager_previous_scene(nfc_playlist->scene_manager); diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_emulation.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_emulation.c index 67f37a12b2c..cce7eb3e7e1 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_emulation.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_emulation.c @@ -31,6 +31,10 @@ int32_t nfc_playlist_emulation_task(void* context) { FuriString* line = furi_string_alloc(); FuriString* tmp_header_str = furi_string_alloc(); FuriString* tmp_counter_str = furi_string_alloc(); + FuriString* tmp_file_name = furi_string_alloc(); + // + char tmp_file_ext[6] = {0}; + //FuriString* tmp_file_ext = furi_string_alloc(); while(stream_read_line(stream, line) && EmulationState == NfcPlaylistEmulationState_Emulating) { @@ -57,6 +61,7 @@ int32_t nfc_playlist_emulation_task(void* context) { AlignTop); furi_delay_ms(50); time_counter_delay_ms -= 50; + furi_string_reset(tmp_counter_str); }; } else if(nfc_playlist->settings.emulate_delay > 0) { skip_delay = false; @@ -67,18 +72,23 @@ int32_t nfc_playlist_emulation_task(void* context) { break; } - char* file_name = strchr(file_path, '/') != NULL ? &strrchr(file_path, '/')[1] : - file_path; - char const* file_ext = &strrchr(file_path, '.')[1]; + path_extract_filename(line, tmp_file_name, false); + //path_extract_ext_str(line, tmp_file_ext); + // why? + path_extract_extension(line, tmp_file_ext, 6); + int time_counter_ms = (options_emulate_timeout[nfc_playlist->settings.emulate_timeout] * 1000); - - if(!strcasestr(file_ext, "nfc")) { + // use strcmp instead furi string to compare file extension + if(strcmp(tmp_file_ext, ".nfc") != 0) { if(nfc_playlist->settings.skip_error) { skip_delay = true; continue; } - furi_string_printf(tmp_header_str, "ERROR invalid file:\n%s", file_name); + furi_string_printf( + tmp_header_str, + "ERROR invalid file:\n%s", + furi_string_get_cstr(tmp_file_name)); popup_set_header( nfc_playlist->popup, furi_string_get_cstr(tmp_header_str), @@ -105,7 +115,8 @@ int32_t nfc_playlist_emulation_task(void* context) { skip_delay = true; continue; } - furi_string_printf(tmp_header_str, "ERROR not found:\n%s", file_name); + furi_string_printf( + tmp_header_str, "ERROR not found:\n%s", furi_string_get_cstr(tmp_file_name)); popup_set_header( nfc_playlist->popup, furi_string_get_cstr(tmp_header_str), @@ -128,7 +139,8 @@ int32_t nfc_playlist_emulation_task(void* context) { time_counter_ms -= 50; }; } else { - furi_string_printf(tmp_header_str, "Emulating:\n%s", file_name); + furi_string_printf( + tmp_header_str, "Emulating:\n%s", furi_string_get_cstr(tmp_file_name)); popup_set_header( nfc_playlist->popup, furi_string_get_cstr(tmp_header_str), @@ -136,10 +148,12 @@ int32_t nfc_playlist_emulation_task(void* context) { 10, AlignCenter, AlignTop); - nfc_playlist_worker_set_nfc_data(nfc_playlist->nfc_playlist_worker, file_path); - nfc_playlist_worker_start(nfc_playlist->nfc_playlist_worker); + nfc_playlist_emulation_worker_set_nfc_data( + nfc_playlist->nfc_playlist_emulation_worker, file_path); + nfc_playlist_emulation_worker_start(nfc_playlist->nfc_playlist_emulation_worker); start_blink(nfc_playlist, NfcPlaylistLedState_Normal); - while(nfc_playlist_worker_is_emulating(nfc_playlist->nfc_playlist_worker) && + while(nfc_playlist_emulation_worker_is_emulating( + nfc_playlist->nfc_playlist_emulation_worker) && time_counter_ms > 0 && EmulationState == NfcPlaylistEmulationState_Emulating) { furi_string_printf(tmp_counter_str, "%ds", (time_counter_ms / 1000)); @@ -153,19 +167,24 @@ int32_t nfc_playlist_emulation_task(void* context) { furi_delay_ms(50); time_counter_ms -= 50; }; - nfc_playlist_worker_stop(nfc_playlist->nfc_playlist_worker); - nfc_playlist_worker_clear_nfc_data(nfc_playlist->nfc_playlist_worker); + nfc_playlist_emulation_worker_stop(nfc_playlist->nfc_playlist_emulation_worker); + nfc_playlist_emulation_worker_clear_nfc_data( + nfc_playlist->nfc_playlist_emulation_worker); } } popup_reset(nfc_playlist->popup); - popup_set_header( - nfc_playlist->popup, - EmulationState == NfcPlaylistEmulationState_Canceled ? "Emulation stopped" : - "Emulation finished", - 64, - 10, - AlignCenter, - AlignTop); + if(nfc_playlist->settings.playlist_length == 0) { + popup_set_header(nfc_playlist->popup, "Empty playlist", 64, 10, AlignCenter, AlignTop); + } else { + popup_set_header( + nfc_playlist->popup, + EmulationState == NfcPlaylistEmulationState_Canceled ? "Emulation stopped" : + "Emulation finished", + 64, + 10, + AlignCenter, + AlignTop); + } popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop); stop_blink(nfc_playlist); @@ -173,6 +192,8 @@ int32_t nfc_playlist_emulation_task(void* context) { furi_string_free(line); furi_string_free(tmp_header_str); furi_string_free(tmp_counter_str); + furi_string_free(tmp_file_name); + //furi_string_free(tmp_file_ext); } else { popup_set_header( nfc_playlist->popup, "Failed to open playlist", 64, 10, AlignCenter, AlignTop); @@ -189,16 +210,16 @@ int32_t nfc_playlist_emulation_task(void* context) { void nfc_playlist_emulation_setup(void* context) { NfcPlaylist* nfc_playlist = context; nfc_playlist->thread = furi_thread_alloc_ex( - "NfcPlaylistEmulationWorker", 8192, nfc_playlist_emulation_task, nfc_playlist); - nfc_playlist->nfc_playlist_worker = nfc_playlist_worker_alloc(); + "NfcPlaylistEmulationWorker", 4096, nfc_playlist_emulation_task, nfc_playlist); + nfc_playlist->nfc_playlist_emulation_worker = nfc_playlist_emulation_worker_alloc(); } void nfc_playlist_emulation_free(NfcPlaylist* nfc_playlist) { furi_assert(nfc_playlist); furi_thread_free(nfc_playlist->thread); - nfc_playlist_worker_free(nfc_playlist->nfc_playlist_worker); + nfc_playlist_emulation_worker_free(nfc_playlist->nfc_playlist_emulation_worker); nfc_playlist->thread = NULL; - nfc_playlist->nfc_playlist_worker = NULL; + nfc_playlist->nfc_playlist_emulation_worker = NULL; } void nfc_playlist_emulation_start(NfcPlaylist* nfc_playlist) { diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_main_menu.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_main_menu.c index 95d33f70e2c..c475678b96f 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_main_menu.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_main_menu.c @@ -1,12 +1,5 @@ #include "../nfc_playlist.h" -typedef enum { - NfcPlaylistEvent_ShowEmulation, - NfcPlaylistEvent_ShowPlaylistSelect, - NfcPlaylistEvent_ShowFileEdit, - NfcPlaylistEvent_ShowSettings -} NfcPlaylistMainMenuEvent; - typedef enum { NfcPlaylistMenuSelection_Start, NfcPlaylistMenuSelection_PlaylistSelect, @@ -27,10 +20,9 @@ void nfc_playlist_main_menu_scene_on_enter(void* context) { return; } - FuriString* tmp_str = furi_string_alloc(); - furi_string_printf(tmp_str, "NFC Playlist v%s", FAP_VERSION); - submenu_set_header(nfc_playlist->submenu, furi_string_get_cstr(tmp_str)); - furi_string_free(tmp_str); + FuriString* header = furi_string_alloc_printf("NFC Playlist v%s", FAP_VERSION); + submenu_set_header(nfc_playlist->submenu, furi_string_get_cstr(header)); + furi_string_free(header); submenu_add_lockable_item( nfc_playlist->submenu, @@ -70,19 +62,19 @@ bool nfc_playlist_main_menu_scene_on_event(void* context, SceneManagerEvent even bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case NfcPlaylistEvent_ShowEmulation: + case NfcPlaylistMenuSelection_Start: scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Emulation); consumed = true; break; - case NfcPlaylistEvent_ShowPlaylistSelect: + case NfcPlaylistMenuSelection_PlaylistSelect: scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistSelect); consumed = true; break; - case NfcPlaylistEvent_ShowFileEdit: + case NfcPlaylistMenuSelection_FileEdit: scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistEdit); consumed = true; break; - case NfcPlaylistEvent_ShowSettings: + case NfcPlaylistMenuSelection_Settings: scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Settings); consumed = true; break; diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_name_new_playlist.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_name_new_playlist.c index 7637f560435..2686c923f15 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_name_new_playlist.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_name_new_playlist.c @@ -1,30 +1,54 @@ #include "../nfc_playlist.h" -void nfc_playlist_name_new_playlist_menu_callback(void* context) { +int32_t nfc_playlist_name_new_playlist_thread_task(void* context) { NfcPlaylist* nfc_playlist = context; - Storage* storage = furi_record_open(RECORD_STORAGE); - FuriString* file_name = furi_string_alloc(); - furi_string_printf( - file_name, "/ext/apps_data/nfc_playlist/%s.txt", nfc_playlist->text_input_output); + FuriString* file_name = furi_string_alloc_printf( + "/ext/apps_data/nfc_playlist/%s.txt", nfc_playlist->text_input_output); + char const* file_name_cstr = furi_string_get_cstr(file_name); + Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); - if(storage_file_open(file, furi_string_get_cstr(file_name), FSAM_READ_WRITE, FSOM_CREATE_NEW)) { - storage_file_close(file); - furi_string_swap(nfc_playlist->settings.playlist_path, file_name); - } - nfc_playlist->settings.playlist_length = 0; + if(!storage_file_exists(storage, file_name_cstr)) { + if(storage_file_open(file, file_name_cstr, FSAM_READ_WRITE, FSOM_CREATE_NEW)) { + storage_file_close(file); + furi_string_swap(nfc_playlist->settings.playlist_path, file_name); + nfc_playlist->settings.playlist_length = 0; + } + } - storage_file_free(file); furi_string_free(file_name); + storage_file_free(file); furi_record_close(RECORD_STORAGE); - scene_manager_previous_scene(nfc_playlist->scene_manager); + + return 0; +} + +void nfc_playlist_name_new_playlist_thread_state_callback(FuriThreadState state, void* context) { + NfcPlaylist* nfc_playlist = context; + if(state == FuriThreadStateStopped) { + furi_thread_yield(); + nfc_playlist->thread = NULL; + scene_manager_search_and_switch_to_previous_scene( + nfc_playlist->scene_manager, NfcPlaylistScene_MainMenu); + } +} + +void nfc_playlist_name_new_playlist_menu_callback(void* context) { + NfcPlaylist* nfc_playlist = context; + nfc_playlist->thread = furi_thread_alloc_ex( + "NfcPlaylistCreator", 1024, nfc_playlist_name_new_playlist_thread_task, nfc_playlist); + furi_thread_set_state_context(nfc_playlist->thread, nfc_playlist); + furi_thread_set_state_callback( + nfc_playlist->thread, nfc_playlist_name_new_playlist_thread_state_callback); + furi_thread_start(nfc_playlist->thread); } void nfc_playlist_name_new_playlist_scene_on_enter(void* context) { NfcPlaylist* nfc_playlist = context; - nfc_playlist->text_input_output = (char*)malloc(50); + + nfc_playlist->text_input_output = malloc(MAX_PLAYLIST_NAME_LEN + 1); text_input_set_header_text(nfc_playlist->text_input, "Enter file name"); text_input_set_minimum_length(nfc_playlist->text_input, 1); text_input_set_result_callback( @@ -32,7 +56,7 @@ void nfc_playlist_name_new_playlist_scene_on_enter(void* context) { nfc_playlist_name_new_playlist_menu_callback, nfc_playlist, nfc_playlist->text_input_output, - 50, + MAX_PLAYLIST_NAME_LEN, true); view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput); diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_nfc_remove.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_nfc_remove.c index 9548ad0c1aa..8c89099857c 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_nfc_remove.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_nfc_remove.c @@ -18,22 +18,22 @@ void nfc_playlist_nfc_remove_options_change_callback(VariableItem* item) { uint8_t current_option = variable_item_list_get_selected_item_index(nfc_playlist->variable_item_list); uint8_t option_value_index = variable_item_get_current_value_index(item); - FuriString* tmp_str = furi_string_alloc(); + switch(current_option) { - case NfcPlaylistSettings_LineSelector: + case NfcPlaylistSettings_LineSelector: { selected_line = option_value_index + 1; - furi_string_printf(tmp_str, "%d", selected_line); + FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line); variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str)); + furi_string_free(tmp_str); break; + } default: break; } - furi_string_free(tmp_str); } void nfc_playlist_nfc_remove_scene_on_enter(void* context) { NfcPlaylist* nfc_playlist = context; - FuriString* tmp_str = furi_string_alloc(); selected_line = nfc_playlist->settings.playlist_length; @@ -47,8 +47,11 @@ void nfc_playlist_nfc_remove_scene_on_enter(void* context) { nfc_playlist); variable_item_set_current_value_index( Line_selector, nfc_playlist->settings.playlist_length - 1); - furi_string_printf(tmp_str, "%d", selected_line); + + FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line); variable_item_set_current_value_text(Line_selector, furi_string_get_cstr(tmp_str)); + furi_string_free(tmp_str); + variable_item_set_locked( Line_selector, nfc_playlist->settings.playlist_length == 0 ? true : false, @@ -62,7 +65,6 @@ void nfc_playlist_nfc_remove_scene_on_enter(void* context) { variable_item_list_set_enter_callback( nfc_playlist->variable_item_list, nfc_playlist_nfc_remove_menu_callback, nfc_playlist); - furi_string_free(tmp_str); view_dispatcher_switch_to_view( nfc_playlist->view_dispatcher, NfcPlaylistView_VariableItemList); @@ -111,16 +113,14 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve if(selected_line == 0) { scene_manager_previous_scene(nfc_playlist->scene_manager); } else { - FuriString* tmp_str = furi_string_alloc(); - VariableItem* Line_selector = variable_item_list_get( nfc_playlist->variable_item_list, NfcPlaylistSettings_LineSelector); variable_item_set_values_count( Line_selector, nfc_playlist->settings.playlist_length); variable_item_set_current_value_index(Line_selector, selected_line - 1); - furi_string_printf(tmp_str, "%d", selected_line); - variable_item_set_current_value_text(Line_selector, furi_string_get_cstr(tmp_str)); + FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line); + variable_item_set_current_value_text(Line_selector, furi_string_get_cstr(tmp_str)); furi_string_free(tmp_str); } diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_edit.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_edit.c index abcf29e4686..f5c8ba93f4b 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_edit.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_edit.c @@ -19,6 +19,8 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) { submenu_set_header(nfc_playlist->submenu, "Edit Playlist"); + bool playlist_path_empty = furi_string_empty(nfc_playlist->settings.playlist_path); + submenu_add_item( nfc_playlist->submenu, "Create Playlist", @@ -32,7 +34,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) { NfcPlaylistMenuSelection_DeletePlaylist, nfc_playlist_playlist_edit_menu_callback, nfc_playlist, - furi_string_empty(nfc_playlist->settings.playlist_path), + playlist_path_empty, "No\nplaylist\nselected"); submenu_add_lockable_item( @@ -41,7 +43,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) { NfcPlaylistMenuSelection_RenamePlaylist, nfc_playlist_playlist_edit_menu_callback, nfc_playlist, - furi_string_empty(nfc_playlist->settings.playlist_path), + playlist_path_empty, "No\nplaylist\nselected"); submenu_add_lockable_item( @@ -50,7 +52,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) { NfcPlaylistMenuSelection_AddNfcItem, nfc_playlist_playlist_edit_menu_callback, nfc_playlist, - furi_string_empty(nfc_playlist->settings.playlist_path), + playlist_path_empty, "No\nplaylist\nselected"); submenu_add_lockable_item( @@ -59,7 +61,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) { NfcPlaylistMenuSelection_RemoveNfcItem, nfc_playlist_playlist_edit_menu_callback, nfc_playlist, - furi_string_empty(nfc_playlist->settings.playlist_path), + playlist_path_empty, "No\nplaylist\nselected"); submenu_add_lockable_item( @@ -68,7 +70,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) { NfcPlaylistMenuSelection_ViewPlaylistContent, nfc_playlist_playlist_edit_menu_callback, nfc_playlist, - furi_string_empty(nfc_playlist->settings.playlist_path), + playlist_path_empty, "No\nplaylist\nselected"); view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Submenu); diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_rename.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_rename.c index 66a8df90696..c2a7cc8ad10 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_rename.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_playlist_rename.c @@ -1,27 +1,47 @@ #include "../nfc_playlist.h" -void nfc_playlist_playlist_rename_menu_callback(void* context) { +int32_t nfc_playlist_playlist_rename_thread_task(void* context) { NfcPlaylist* nfc_playlist = context; - Storage* storage = furi_record_open(RECORD_STORAGE); - char const* old_file_path = (char*)furi_string_get_cstr(nfc_playlist->settings.playlist_path); + char const* old_file_path = furi_string_get_cstr(nfc_playlist->settings.playlist_path); char const* old_file_name = strchr(old_file_path, '/') != NULL ? &strrchr(old_file_path, '/')[1] : old_file_path; - - FuriString* new_file_path = furi_string_alloc_set(nfc_playlist->settings.playlist_path); + FuriString* new_file_path = furi_string_alloc_set_str(old_file_path); furi_string_replace(new_file_path, old_file_name, nfc_playlist->text_input_output); furi_string_cat_str(new_file_path, ".txt"); - if(storage_common_rename(storage, old_file_path, furi_string_get_cstr(new_file_path)) == 0) { - furi_string_move(nfc_playlist->settings.playlist_path, new_file_path); - } else { - furi_string_free(new_file_path); + Storage* storage = furi_record_open(RECORD_STORAGE); + + if(!storage_file_exists(storage, furi_string_get_cstr(new_file_path))) { + if(storage_common_rename(storage, old_file_path, furi_string_get_cstr(new_file_path)) == + 0) { + furi_string_move(nfc_playlist->settings.playlist_path, new_file_path); + } } furi_record_close(RECORD_STORAGE); - scene_manager_search_and_switch_to_previous_scene( - nfc_playlist->scene_manager, NfcPlaylistScene_MainMenu); + return 0; +} + +void nfc_playlist_playlist_rename_thread_state_callback(FuriThreadState state, void* context) { + NfcPlaylist* nfc_playlist = context; + if(state == FuriThreadStateStopped) { + furi_thread_yield(); + nfc_playlist->thread = NULL; + scene_manager_search_and_switch_to_previous_scene( + nfc_playlist->scene_manager, NfcPlaylistScene_MainMenu); + } +} + +void nfc_playlist_playlist_rename_menu_callback(void* context) { + NfcPlaylist* nfc_playlist = context; + nfc_playlist->thread = furi_thread_alloc_ex( + "NfcPlaylistRenamer", 1024, nfc_playlist_playlist_rename_thread_task, nfc_playlist); + furi_thread_set_state_context(nfc_playlist->thread, nfc_playlist); + furi_thread_set_state_callback( + nfc_playlist->thread, nfc_playlist_playlist_rename_thread_state_callback); + furi_thread_start(nfc_playlist->thread); } void nfc_playlist_playlist_rename_scene_on_enter(void* context) { @@ -30,11 +50,11 @@ void nfc_playlist_playlist_rename_scene_on_enter(void* context) { char const* tmp_file_path = furi_string_get_cstr(nfc_playlist->settings.playlist_path); char const* tmp_file_name = strchr(tmp_file_path, '/') != NULL ? &strrchr(tmp_file_path, '/')[1] : tmp_file_path; - FuriString* tmp_file_name_furi = furi_string_alloc_set_str(tmp_file_name); furi_string_replace(tmp_file_name_furi, ".txt", ""); - nfc_playlist->text_input_output = strdup(furi_string_get_cstr(tmp_file_name_furi)); + nfc_playlist->text_input_output = malloc(MAX_PLAYLIST_NAME_LEN + 1); + strcpy(nfc_playlist->text_input_output, furi_string_get_cstr(tmp_file_name_furi)); furi_string_free(tmp_file_name_furi); text_input_set_header_text(nfc_playlist->text_input, "Enter new file name"); @@ -44,7 +64,7 @@ void nfc_playlist_playlist_rename_scene_on_enter(void* context) { nfc_playlist_playlist_rename_menu_callback, nfc_playlist, nfc_playlist->text_input_output, - (50 + sizeof(nfc_playlist->text_input_output)), + MAX_PLAYLIST_NAME_LEN, false); view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput); diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_settings.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_settings.c index 6ebe0781323..5e798dba646 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_settings.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_settings.c @@ -19,20 +19,24 @@ void nfc_playlist_settings_options_change_callback(VariableItem* item) { uint8_t current_option = variable_item_list_get_selected_item_index(nfc_playlist->variable_item_list); uint8_t option_value_index = variable_item_get_current_value_index(item); - FuriString* tmp_str = furi_string_alloc(); + switch(current_option) { - case NfcPlaylistSettings_Timeout: + case NfcPlaylistSettings_Timeout: { nfc_playlist->settings.emulate_timeout = option_value_index; - furi_string_printf( - tmp_str, "%ds", options_emulate_timeout[nfc_playlist->settings.emulate_timeout]); + FuriString* tmp_str = furi_string_alloc_printf( + "%ds", options_emulate_timeout[nfc_playlist->settings.emulate_timeout]); variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str)); + furi_string_free(tmp_str); break; - case NfcPlaylistSettings_Delay: + } + case NfcPlaylistSettings_Delay: { nfc_playlist->settings.emulate_delay = option_value_index; - furi_string_printf( - tmp_str, "%ds", options_emulate_delay[nfc_playlist->settings.emulate_delay]); + FuriString* tmp_str = furi_string_alloc_printf( + "%ds", options_emulate_delay[nfc_playlist->settings.emulate_delay]); variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str)); + furi_string_free(tmp_str); break; + } case NfcPlaylistSettings_LedIndicator: nfc_playlist->settings.emulate_led_indicator = option_value_index; variable_item_set_current_value_text( @@ -46,7 +50,6 @@ void nfc_playlist_settings_options_change_callback(VariableItem* item) { default: break; } - furi_string_free(tmp_str); } void nfc_playlist_settings_scene_on_enter(void* context) { diff --git a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_view_playlist_content.c b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_view_playlist_content.c index 7efdd46c284..e6d9ed5a252 100644 --- a/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_view_playlist_content.c +++ b/non_catalog_apps/nfc_playlist/scenes/nfc_playlist_scene_view_playlist_content.c @@ -18,7 +18,6 @@ void nfc_playlist_view_playlist_content_scene_on_enter(void* context) { furi_string_cat_printf(tmp_str, "%s", furi_string_get_cstr(line)); } - stream_clean(stream); furi_string_free(line); file_stream_close(stream); From e45ef250bc9bf4d6a3627e5726b3895fcc7b473b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jun 2024 12:48:39 +0300 Subject: [PATCH 14/36] upd readme --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index c13be39abf5..915c33bd0a0 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -13,7 +13,7 @@ Apps contains changes needed to compile them on latest firmware, fixes has been The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done. -### Apps checked & updated at `6 Jun 00:22 GMT +3` +### Apps checked & updated at `6 Jun 12:48 GMT +3` # Default pack From b5ba9f4e4f6eb62c9bf6bed0a7c463bd4a4f5ad4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:56:40 +0300 Subject: [PATCH 15/36] upd picopass --- base_pack/picopass/acknowledgements.h | 10 ++- base_pack/picopass/plugin/wiegand.c | 106 ++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 16 deletions(-) diff --git a/base_pack/picopass/acknowledgements.h b/base_pack/picopass/acknowledgements.h index bc65cb76445..9f2eac90720 100644 --- a/base_pack/picopass/acknowledgements.h +++ b/base_pack/picopass/acknowledgements.h @@ -1,2 +1,10 @@ const char* acknowledgements_text = - "The developers of Picopass would like to humbly acknowledge the work of those who came before and made this possible.\nWe stand on the shoulders of giants.\nFlavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and Milosch Meriac for their research on iClass. Martin HS (holiman) for their work on the loclass library. Iceman and the Proxmark3 community."; + "The developers of Picopass would like to humbly acknowledge the work of those who came before and made this possible. (cont.)\ + \nWe stand on the shoulders of giants:\ + \n* Flavio D. Garcia\ + \n* Gerhard de Koning Gans\ + \n* Roel Verdult \ + \n* Milosch Meriac \ + \nfor their research on iClass.\ + \nMartin HS (holiman) for their work on the loclass library.\ + \nIceman and the Proxmark3 community."; diff --git a/base_pack/picopass/plugin/wiegand.c b/base_pack/picopass/plugin/wiegand.c index 1a87112d06d..a362f2b59c9 100644 --- a/base_pack/picopass/plugin/wiegand.c +++ b/base_pack/picopass/plugin/wiegand.c @@ -26,16 +26,39 @@ static inline uint8_t evenparity32(uint32_t x) { return bit_lib_test_parity_32(x, BitLibParityEven); } -static int wiegand_C1k35s_parse(uint8_t bit_length, uint64_t bits, FuriString* description) { - if(bit_length != 35) { - return 0; +uint8_t get_bit_by_position(wiegand_message_t* data, uint8_t pos) { + if(pos >= data->Length) return false; + pos = (data->Length - pos) - + 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + uint8_t result = 0; + if(pos > 95) + result = 0; + else if(pos > 63) + result = (data->Top >> (pos - 64)) & 1; + else if(pos > 31) + result = (data->Mid >> (pos - 32)) & 1; + else + result = (data->Bot >> pos) & 1; + return result; +} + +uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length) { + uint64_t result = 0; + for(uint8_t i = 0; i < length; i++) { + result = (result << 1) | get_bit_by_position(data, firstBit + i); } + return result; +} +static int wiegand_C1k35s_parse(uint8_t bit_length, uint64_t bits, FuriString* description) { wiegand_message_t value; + value.Length = bit_length; value.Mid = bits >> 32; value.Bot = bits; wiegand_message_t* packed = &value; + if(packed->Length != 35) return false; // Wrong length? Stop here. + uint32_t cn = (packed->Bot >> 1) & 0x000FFFFF; uint32_t fc = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); bool valid = (evenparity32((packed->Mid & 0x1) ^ (packed->Bot & 0xB6DB6DB6)) == @@ -48,6 +71,8 @@ static int wiegand_C1k35s_parse(uint8_t bit_length, uint64_t bits, FuriString* d if(valid) { furi_string_cat_printf(description, "C1k35s\nFC: %ld CN: %ld\n", fc, cn); return 1; + } else { + FURI_LOG_D(PLUGIN_APP_ID, "C1k35s invalid"); } return 0; @@ -89,6 +114,57 @@ static int wiegand_h10301_parse(uint8_t bit_length, uint64_t bits, FuriString* d furi_string_cat_printf(description, "H10301\nFC: %d CN: %d\n", fc, cn); return 1; + } else { + FURI_LOG_D(PLUGIN_APP_ID, "H10301 invalid"); + } + + return 0; +} + +static int wiegand_H10304_parse(uint8_t bit_length, uint64_t bits, FuriString* description) { + wiegand_message_t value; + value.Length = bit_length; + value.Mid = bits >> 32; + value.Bot = bits; + wiegand_message_t* packed = &value; + + if(packed->Length != 37) return false; // Wrong length? Stop here. + + uint32_t fc = get_linear_field(packed, 1, 16); + uint32_t cn = get_linear_field(packed, 17, 19); + bool valid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && + (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); + + if(valid) { + furi_string_cat_printf(description, "H10304\nFC: %ld CN: %ld\n", fc, cn); + return 1; + } else { + FURI_LOG_D(PLUGIN_APP_ID, "H10304 invalid"); + } + + return 0; +} + +static int wiegand_H10302_parse(uint8_t bit_length, uint64_t bits, FuriString* description) { + wiegand_message_t value; + value.Length = bit_length; + value.Mid = bits >> 32; + value.Bot = bits; + wiegand_message_t* packed = &value; + + if(packed->Length != 37) return false; // Wrong length? Stop here. + + uint64_t cn = get_linear_field(packed, 1, 35); + bool valid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && + (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); + + if(valid) { + furi_string_cat_printf(description, "H10302\nCN: %lld\n", cn); + return 1; + } else { + FURI_LOG_D(PLUGIN_APP_ID, "H10302 invalid"); } return 0; @@ -100,12 +176,17 @@ static int wiegand_format_count(uint8_t bit_length, uint64_t bits) { int count = 0; FuriString* ignore = furi_string_alloc(); + // NOTE: Always update the `total` and add to the wiegand_format_description function + // TODO: Make this into a function pointer array count += wiegand_h10301_parse(bit_length, bits, ignore); count += wiegand_C1k35s_parse(bit_length, bits, ignore); + count += wiegand_H10302_parse(bit_length, bits, ignore); + count += wiegand_H10304_parse(bit_length, bits, ignore); + int total = 4; furi_string_free(ignore); - FURI_LOG_I(PLUGIN_APP_ID, "count: %i", count); + FURI_LOG_I(PLUGIN_APP_ID, "count: %i/%i", count, total); return count; } @@ -115,21 +196,16 @@ static void wiegand_format_description( size_t index, FuriString* description) { FURI_LOG_I(PLUGIN_APP_ID, "description %d", index); - UNUSED(bit_length); - UNUSED(bits); - - size_t i = 0; - i += wiegand_h10301_parse(bit_length, bits, description); - if(i - 1 == index) { - return; - } - i += wiegand_C1k35s_parse(bit_length, bits, description); - if(i - 1 == index) { + // Turns out I did this wrong and trying to use the index means the results get repeated. Instead, just return the results for index == 0 + if(index != 0) { return; } - furi_string_cat_printf(description, "[%i] FC: CN:", index); + wiegand_h10301_parse(bit_length, bits, description); + wiegand_C1k35s_parse(bit_length, bits, description); + wiegand_H10302_parse(bit_length, bits, description); + wiegand_H10304_parse(bit_length, bits, description); } /* Actual implementation of app<>plugin interface */ From d1d10010890865399843b955588377a73ab7c4f5 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:57:03 +0300 Subject: [PATCH 16/36] upd readme --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 915c33bd0a0..49258f6a378 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -13,7 +13,7 @@ Apps contains changes needed to compile them on latest firmware, fixes has been The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done. -### Apps checked & updated at `6 Jun 12:48 GMT +3` +### Apps checked & updated at `11 Jun 16:56 GMT +3` # Default pack From 5b30723f392af0bd717c1a476443d832b47b34a7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:33:36 +0300 Subject: [PATCH 17/36] fix reuse of define --- non_catalog_apps/meal_pager/helpers/subghz/subghz_i.c | 2 +- non_catalog_apps/meal_pager/meal_pager_i.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/non_catalog_apps/meal_pager/helpers/subghz/subghz_i.c b/non_catalog_apps/meal_pager/helpers/subghz/subghz_i.c index cda36a15b15..45138f9d341 100644 --- a/non_catalog_apps/meal_pager/helpers/subghz/subghz_i.c +++ b/non_catalog_apps/meal_pager/helpers/subghz/subghz_i.c @@ -197,7 +197,7 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { /*DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options( &browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px); - browser_options.base_path = SUBGHZ_APP_FOLDER; + browser_options.base_path = SUBGHZ_MP_FOLDER; // Input events and views are managed by file_select bool res = dialog_file_browser_show( diff --git a/non_catalog_apps/meal_pager/meal_pager_i.h b/non_catalog_apps/meal_pager/meal_pager_i.h index 01e92e2dc7e..c8a593cd893 100644 --- a/non_catalog_apps/meal_pager/meal_pager_i.h +++ b/non_catalog_apps/meal_pager/meal_pager_i.h @@ -23,8 +23,8 @@ #define TAG "Meal_Pager" -#define SUBGHZ_APP_EXTENSION ".sub" -#define SUBGHZ_APP_FOLDER ANY_PATH("subghz") +//#define SUBGHZ_APP_EXTENSION ".sub" +#define SUBGHZ_MP_FOLDER EXT_PATH("subghz") #define MEAL_PAGER_VERSION "1.3" typedef struct Meal_PagerTransmit Meal_PagerTransmit; From 31bc2d8446b5dfc9a65c493f2dd3a662c57f75e7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:26:07 +0300 Subject: [PATCH 18/36] free some memory in esubghz chat --- .../lib/nfclegacy/helpers/mf_classic_dict.c | 349 ---- .../lib/nfclegacy/helpers/mf_classic_dict.h | 107 -- .../lib/nfclegacy/helpers/mfkey32.c | 228 --- .../lib/nfclegacy/helpers/mfkey32.h | 34 - .../lib/nfclegacy/helpers/nfc_debug_log.c | 71 - .../lib/nfclegacy/helpers/nfc_debug_log.h | 17 - .../lib/nfclegacy/helpers/nfc_debug_pcap.c | 128 -- .../lib/nfclegacy/helpers/nfc_debug_pcap.h | 17 - .../lib/nfclegacy/helpers/nfc_generators.c | 548 ------ .../lib/nfclegacy/helpers/nfc_generators.h | 29 - .../lib/nfclegacy/helpers/reader_analyzer.c | 265 --- .../lib/nfclegacy/helpers/reader_analyzer.h | 43 - .../esubghz_chat/lib/nfclegacy/nfc_device.c | 339 +--- .../esubghz_chat/lib/nfclegacy/nfc_device.h | 9 - .../esubghz_chat/lib/nfclegacy/nfc_types.c | 12 - .../esubghz_chat/lib/nfclegacy/nfc_types.h | 2 - .../esubghz_chat/lib/nfclegacy/nfc_worker.c | 585 +----- .../esubghz_chat/lib/nfclegacy/nfc_worker_i.h | 4 - .../lib/nfclegacy/protocols/mifare_classic.c | 1627 ----------------- .../lib/nfclegacy/protocols/mifare_classic.h | 251 --- .../lib/nfclegacy/pulse_reader/pulse_reader.c | 236 --- .../lib/nfclegacy/pulse_reader/pulse_reader.h | 122 -- 22 files changed, 3 insertions(+), 5020 deletions(-) delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.h delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.c delete mode 100644 non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.h diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.c deleted file mode 100644 index 937addb46ef..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.c +++ /dev/null @@ -1,349 +0,0 @@ -#include "mf_classic_dict.h" - -#include -#include - -#define MF_CLASSIC_DICT_FLIPPER_PATH EXT_PATH("nfc/assets/mf_classic_dict.nfc") -#define MF_CLASSIC_DICT_USER_PATH EXT_PATH("nfc/assets/mf_classic_dict_user.nfc") -#define MF_CLASSIC_DICT_UNIT_TEST_PATH EXT_PATH("unit_tests/mf_classic_dict.nfc") - -#define TAG "MfClassicDict" - -#define NFC_MF_CLASSIC_KEY_LEN (13) - -struct MfClassicDict { - Stream* stream; - uint32_t total_keys; -}; - -bool mf_classic_dict_check_presence(MfClassicDictType dict_type) { - Storage* storage = furi_record_open(RECORD_STORAGE); - - bool dict_present = false; - if(dict_type == MfClassicDictTypeSystem) { - dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_FLIPPER_PATH, NULL) == FSE_OK; - } else if(dict_type == MfClassicDictTypeUser) { - dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_USER_PATH, NULL) == FSE_OK; - } else if(dict_type == MfClassicDictTypeUnitTest) { - dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_UNIT_TEST_PATH, NULL) == - FSE_OK; - } - - furi_record_close(RECORD_STORAGE); - - return dict_present; -} - -MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { - MfClassicDict* dict = malloc(sizeof(MfClassicDict)); - Storage* storage = furi_record_open(RECORD_STORAGE); - dict->stream = buffered_file_stream_alloc(storage); - furi_record_close(RECORD_STORAGE); - - bool dict_loaded = false; - do { - if(dict_type == MfClassicDictTypeSystem) { - if(!buffered_file_stream_open( - dict->stream, - MF_CLASSIC_DICT_FLIPPER_PATH, - FSAM_READ_WRITE, - FSOM_OPEN_EXISTING)) { - buffered_file_stream_close(dict->stream); - break; - } - } else if(dict_type == MfClassicDictTypeUser) { - if(!buffered_file_stream_open( - dict->stream, MF_CLASSIC_DICT_USER_PATH, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS)) { - buffered_file_stream_close(dict->stream); - break; - } - } else if(dict_type == MfClassicDictTypeUnitTest) { - if(!buffered_file_stream_open( - dict->stream, - MF_CLASSIC_DICT_UNIT_TEST_PATH, - FSAM_READ_WRITE, - FSOM_OPEN_ALWAYS)) { - buffered_file_stream_close(dict->stream); - break; - } - } - - // Check for new line ending - if(!stream_eof(dict->stream)) { - if(!stream_seek(dict->stream, -1, StreamOffsetFromEnd)) break; - uint8_t last_char = 0; - if(stream_read(dict->stream, &last_char, 1) != 1) break; - if(last_char != '\n') { - FURI_LOG_D(TAG, "Adding new line ending"); - if(stream_write_char(dict->stream, '\n') != 1) break; - } - if(!stream_rewind(dict->stream)) break; - } - - // Read total amount of keys - FuriString* next_line; - next_line = furi_string_alloc(); - while(true) { - if(!stream_read_line(dict->stream, next_line)) { - FURI_LOG_T(TAG, "No keys left in dict"); - break; - } - FURI_LOG_T( - TAG, - "Read line: %s, len: %zu", - furi_string_get_cstr(next_line), - furi_string_size(next_line)); - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - dict->total_keys++; - } - furi_string_free(next_line); - stream_rewind(dict->stream); - - dict_loaded = true; - FURI_LOG_I(TAG, "Loaded dictionary with %lu keys", dict->total_keys); - } while(false); - - if(!dict_loaded) { - buffered_file_stream_close(dict->stream); - free(dict); - dict = NULL; - } - - return dict; -} - -void mf_classic_dict_free(MfClassicDict* dict) { - furi_assert(dict); - furi_assert(dict->stream); - - buffered_file_stream_close(dict->stream); - stream_free(dict->stream); - free(dict); -} - -static void mf_classic_dict_int_to_str(uint8_t* key_int, FuriString* key_str) { - furi_string_reset(key_str); - for(size_t i = 0; i < 6; i++) { - furi_string_cat_printf(key_str, "%02X", key_int[i]); - } -} - -static void mf_classic_dict_str_to_int(FuriString* key_str, uint64_t* key_int) { - uint8_t key_byte_tmp; - - *key_int = 0ULL; - for(uint8_t i = 0; i < 12; i += 2) { - args_char_to_hex( - furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp); - *key_int |= (uint64_t)key_byte_tmp << (8 * (5 - i / 2)); - } -} - -uint32_t mf_classic_dict_get_total_keys(MfClassicDict* dict) { - furi_assert(dict); - - return dict->total_keys; -} - -bool mf_classic_dict_rewind(MfClassicDict* dict) { - furi_assert(dict); - furi_assert(dict->stream); - - return stream_rewind(dict->stream); -} - -bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key) { - furi_assert(dict); - furi_assert(dict->stream); - - bool key_read = false; - furi_string_reset(key); - while(!key_read) { - if(!stream_read_line(dict->stream, key)) break; - if(furi_string_get_char(key, 0) == '#') continue; - if(furi_string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue; - furi_string_left(key, 12); - key_read = true; - } - - return key_read; -} - -bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* temp_key; - temp_key = furi_string_alloc(); - bool key_read = mf_classic_dict_get_next_key_str(dict, temp_key); - if(key_read) { - mf_classic_dict_str_to_int(temp_key, key); - } - furi_string_free(temp_key); - return key_read; -} - -bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* next_line; - next_line = furi_string_alloc(); - - bool key_found = false; - stream_rewind(dict->stream); - while(!key_found) { //-V654 - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - furi_string_left(next_line, 12); - if(!furi_string_equal(key, next_line)) continue; - key_found = true; - } - - furi_string_free(next_line); - return key_found; -} - -bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key) { - FuriString* temp_key; - - temp_key = furi_string_alloc(); - mf_classic_dict_int_to_str(key, temp_key); - bool key_found = mf_classic_dict_is_key_present_str(dict, temp_key); - furi_string_free(temp_key); - return key_found; -} - -bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key) { - furi_assert(dict); - furi_assert(dict->stream); - - furi_string_cat_printf(key, "\n"); - - bool key_added = false; - do { - if(!stream_seek(dict->stream, 0, StreamOffsetFromEnd)) break; - if(!stream_insert_string(dict->stream, key)) break; - dict->total_keys++; - key_added = true; - } while(false); - - furi_string_left(key, 12); - return key_added; -} - -bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* temp_key; - temp_key = furi_string_alloc(); - mf_classic_dict_int_to_str(key, temp_key); - bool key_added = mf_classic_dict_add_key_str(dict, temp_key); - - furi_string_free(temp_key); - return key_added; -} - -bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* next_line; - uint32_t index = 0; - next_line = furi_string_alloc(); - furi_string_reset(key); - - bool key_found = false; - while(!key_found) { - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - if(index++ != target) continue; - furi_string_set_n(key, next_line, 0, 12); - key_found = true; - } - - furi_string_free(next_line); - return key_found; -} - -bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32_t target) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* temp_key; - temp_key = furi_string_alloc(); - bool key_found = mf_classic_dict_get_key_at_index_str(dict, temp_key, target); - if(key_found) { - mf_classic_dict_str_to_int(temp_key, key); - } - furi_string_free(temp_key); - return key_found; -} - -bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* next_line; - next_line = furi_string_alloc(); - - bool key_found = false; - uint32_t index = 0; - stream_rewind(dict->stream); - while(!key_found) { //-V654 - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - furi_string_left(next_line, 12); - if(!furi_string_equal(key, next_line)) continue; - key_found = true; - *target = index; - } - - furi_string_free(next_line); - return key_found; -} - -bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* temp_key; - temp_key = furi_string_alloc(); - mf_classic_dict_int_to_str(key, temp_key); - bool key_found = mf_classic_dict_find_index_str(dict, temp_key, target); - - furi_string_free(temp_key); - return key_found; -} - -bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) { - furi_assert(dict); - furi_assert(dict->stream); - - FuriString* next_line; - next_line = furi_string_alloc(); - uint32_t index = 0; - - bool key_removed = false; - stream_rewind(dict->stream); - while(!key_removed) { - if(!stream_read_line(dict->stream, next_line)) break; - if(furi_string_get_char(next_line, 0) == '#') continue; - if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - if(index++ != target) continue; - stream_seek(dict->stream, -NFC_MF_CLASSIC_KEY_LEN, StreamOffsetFromCurrent); - if(!stream_delete(dict->stream, NFC_MF_CLASSIC_KEY_LEN)) break; - dict->total_keys--; - key_removed = true; - } - - stream_rewind(dict->stream); - - furi_string_free(next_line); - return key_removed; -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.h deleted file mode 100644 index 71002664a2d..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mf_classic_dict.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MfClassicDictTypeUser, - MfClassicDictTypeSystem, - MfClassicDictTypeUnitTest, -} MfClassicDictType; - -typedef struct MfClassicDict MfClassicDict; - -bool mf_classic_dict_check_presence(MfClassicDictType dict_type); - -/** Allocate MfClassicDict instance - * - * @param[in] dict_type The dictionary type - * - * @return MfClassicDict instance - */ -MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type); - -/** Free MfClassicDict instance - * - * @param dict MfClassicDict instance - */ -void mf_classic_dict_free(MfClassicDict* dict); - -/** Get total keys count - * - * @param dict MfClassicDict instance - * - * @return total keys count - */ -uint32_t mf_classic_dict_get_total_keys(MfClassicDict* dict); - -/** Rewind to the beginning - * - * @param dict MfClassicDict instance - * - * @return true on success - */ -bool mf_classic_dict_rewind(MfClassicDict* dict); - -bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key); - -bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key); - -bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key); - -bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key); - -/** Get key at target offset as uint64_t - * - * @param dict MfClassicDict instance - * @param[out] key Pointer to the uint64_t key - * @param[in] target Target offset from current position - * - * @return true on success - */ -bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32_t target); - -/** Get key at target offset as FuriString* - * - * @param dict MfClassicDict instance - * @param[out] key Found key destination buffer - * @param[in] target Target offset from current position - * - * @return true on success - */ -bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target); - -bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key); - -/** Add string representation of the key - * - * @param dict MfClassicDict instance - * @param[in] key String representation of the key - * - * @return true on success - */ -bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key); - -bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target); - -bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target); - -/** Delete key at target offset - * - * @param dict MfClassicDict instance - * @param[in] target Target offset from current position - * - * @return true on success - */ -bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.c deleted file mode 100644 index 94a9d1f8938..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "mfkey32.h" - -#include -#include -#include -#include -#include - -#include "../protocols/mifare_classic.h" -#include "../protocols/nfc_util.h" - -#define TAG "Mfkey32" - -#define MFKEY32_LOGS_PATH EXT_PATH("nfc/.mfkey32.log") - -typedef enum { - Mfkey32StateIdle, - Mfkey32StateAuthReceived, - Mfkey32StateAuthNtSent, - Mfkey32StateAuthArNrReceived, -} Mfkey32State; - -typedef struct { - uint32_t cuid; - uint8_t sector; - MfClassicKey key; - uint32_t nt0; - uint32_t nr0; - uint32_t ar0; - uint32_t nt1; - uint32_t nr1; - uint32_t ar1; -} Mfkey32Params; - -ARRAY_DEF(Mfkey32Params, Mfkey32Params, M_POD_OPLIST); - -typedef struct { - uint8_t sector; - MfClassicKey key; - uint32_t nt; - uint32_t nr; - uint32_t ar; -} Mfkey32Nonce; - -struct Mfkey32 { - Mfkey32State state; - Stream* file_stream; - Mfkey32Params_t params_arr; - Mfkey32Nonce nonce; - uint32_t cuid; - Mfkey32ParseDataCallback callback; - void* context; -}; - -Mfkey32* mfkey32_alloc(uint32_t cuid) { - Mfkey32* instance = malloc(sizeof(Mfkey32)); - instance->cuid = cuid; - instance->state = Mfkey32StateIdle; - Storage* storage = furi_record_open(RECORD_STORAGE); - instance->file_stream = buffered_file_stream_alloc(storage); - if(!buffered_file_stream_open( - instance->file_stream, MFKEY32_LOGS_PATH, FSAM_WRITE, FSOM_OPEN_APPEND)) { - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - free(instance); - instance = NULL; - } else { - Mfkey32Params_init(instance->params_arr); - } - - furi_record_close(RECORD_STORAGE); - - return instance; -} - -void mfkey32_free(Mfkey32* instance) { - furi_assert(instance != NULL); - - Mfkey32Params_clear(instance->params_arr); - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - free(instance); -} - -void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { - FuriString* str = furi_string_alloc_printf( - "Sec %d key %c cuid %08lx nt0 %08lx nr0 %08lx ar0 %08lx nt1 %08lx nr1 %08lx ar1 %08lx\n", - params->sector, - params->key == MfClassicKeyA ? 'A' : 'B', - params->cuid, - params->nt0, - params->nr0, - params->ar0, - params->nt1, - params->nr1, - params->ar1); - bool write_success = stream_write_string(instance->file_stream, str); - furi_string_free(str); - return write_success; -} - -static void mfkey32_add_params(Mfkey32* instance) { - Mfkey32Nonce* nonce = &instance->nonce; - bool nonce_added = false; - // Search if we partially collected params - if(Mfkey32Params_size(instance->params_arr)) { - Mfkey32Params_it_t it; - for(Mfkey32Params_it(it, instance->params_arr); !Mfkey32Params_end_p(it); - Mfkey32Params_next(it)) { - Mfkey32Params* params = Mfkey32Params_ref(it); - if((params->sector == nonce->sector) && (params->key == nonce->key)) { - params->nt1 = nonce->nt; - params->nr1 = nonce->nr; - params->ar1 = nonce->ar; - nonce_added = true; - FURI_LOG_I( - TAG, - "Params for sector %d key %c collected", - params->sector, - params->key == MfClassicKeyA ? 'A' : 'B'); - // Write on sd card - if(mfkey32_write_params(instance, params)) { - Mfkey32Params_remove(instance->params_arr, it); - if(instance->callback) { - instance->callback(Mfkey32EventParamCollected, instance->context); - } - } - } - } - } - if(!nonce_added) { - Mfkey32Params params = { - .sector = nonce->sector, - .key = nonce->key, - .cuid = instance->cuid, - .nt0 = nonce->nt, - .nr0 = nonce->nr, - .ar0 = nonce->ar, - }; - Mfkey32Params_push_back(instance->params_arr, params); - } -} - -void mfkey32_process_data( - Mfkey32* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - furi_assert(instance); - furi_assert(data); - - Mfkey32Nonce* nonce = &instance->nonce; - uint16_t data_len = len; - if((data_len > 3) && !crc_dropped) { - data_len -= 2; - } - - bool data_processed = false; - if(instance->state == Mfkey32StateIdle) { - if(reader_to_tag) { - if((data[0] == 0x60) || (data[0] == 0x61)) { - nonce->key = data[0] == 0x60 ? MfClassicKeyA : MfClassicKeyB; - nonce->sector = mf_classic_get_sector_by_block(data[1]); - instance->state = Mfkey32StateAuthReceived; - data_processed = true; - } - } - } else if(instance->state == Mfkey32StateAuthReceived) { - if(!reader_to_tag) { - if(len == 4) { - nonce->nt = nfc_util_bytes2num(data, 4); - instance->state = Mfkey32StateAuthNtSent; - data_processed = true; - } - } - } else if(instance->state == Mfkey32StateAuthNtSent) { - if(reader_to_tag) { - if(len == 8) { - nonce->nr = nfc_util_bytes2num(data, 4); - nonce->ar = nfc_util_bytes2num(&data[4], 4); - mfkey32_add_params(instance); - instance->state = Mfkey32StateIdle; - } - } - } - if(!data_processed) { - instance->state = Mfkey32StateIdle; - } -} - -uint16_t mfkey32_get_auth_sectors(FuriString* data_str) { - furi_assert(data_str); - - uint16_t nonces_num = 0; - Storage* storage = furi_record_open(RECORD_STORAGE); - Stream* file_stream = buffered_file_stream_alloc(storage); - FuriString* temp_str; - temp_str = furi_string_alloc(); - - do { - if(!buffered_file_stream_open( - file_stream, MFKEY32_LOGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) - break; - while(true) { - if(!stream_read_line(file_stream, temp_str)) break; - size_t uid_pos = furi_string_search(temp_str, "cuid"); - furi_string_left(temp_str, uid_pos); - furi_string_push_back(temp_str, '\n'); - furi_string_cat(data_str, temp_str); - nonces_num++; - } - } while(false); - - buffered_file_stream_close(file_stream); - stream_free(file_stream); - furi_string_free(temp_str); - - return nonces_num; -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.h deleted file mode 100644 index 29e8e4c9f75..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/mfkey32.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "../protocols/mifare_classic.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Mfkey32 Mfkey32; - -typedef enum { - Mfkey32EventParamCollected, -} Mfkey32Event; - -typedef void (*Mfkey32ParseDataCallback)(Mfkey32Event event, void* context); - -Mfkey32* mfkey32_alloc(uint32_t cuid); - -void mfkey32_free(Mfkey32* instance); - -void mfkey32_process_data( - Mfkey32* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped); - -void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context); - -uint16_t mfkey32_get_auth_sectors(FuriString* string); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.c deleted file mode 100644 index 0bfbc2c62f6..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "nfc_debug_log.h" - -#include -#include - -#define TAG "NfcDebugLog" - -#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.txt") - -struct NfcDebugLog { - Stream* file_stream; - FuriString* data_str; -}; - -NfcDebugLog* nfc_debug_log_alloc() { - NfcDebugLog* instance = malloc(sizeof(NfcDebugLog)); - - Storage* storage = furi_record_open(RECORD_STORAGE); - instance->file_stream = buffered_file_stream_alloc(storage); - - if(!buffered_file_stream_open( - instance->file_stream, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) { - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - instance->file_stream = NULL; - } - - if(!instance->file_stream) { - free(instance); - instance = NULL; - } else { - instance->data_str = furi_string_alloc(); - } - furi_record_close(RECORD_STORAGE); - - return instance; -} - -void nfc_debug_log_free(NfcDebugLog* instance) { - furi_assert(instance); - furi_assert(instance->file_stream); - furi_assert(instance->data_str); - - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - furi_string_free(instance->data_str); - - free(instance); -} - -void nfc_debug_log_process_data( - NfcDebugLog* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - furi_assert(instance); - furi_assert(instance->file_stream); - furi_assert(instance->data_str); - furi_assert(data); - UNUSED(crc_dropped); - - furi_string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T'); - uint16_t data_len = len; - for(size_t i = 0; i < data_len; i++) { - furi_string_cat_printf(instance->data_str, " %02x", data[i]); - } - furi_string_push_back(instance->data_str, '\n'); - - stream_write_string(instance->file_stream, instance->data_str); -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.h deleted file mode 100644 index 261b8008b8e..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_log.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -typedef struct NfcDebugLog NfcDebugLog; - -NfcDebugLog* nfc_debug_log_alloc(); - -void nfc_debug_log_free(NfcDebugLog* instance); - -void nfc_debug_log_process_data( - NfcDebugLog* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped); diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.c deleted file mode 100644 index 10b19994c51..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.c +++ /dev/null @@ -1,128 +0,0 @@ -#include "nfc_debug_pcap.h" - -#include -#include -#include "../furi_hal_nfc.h" -#include - -#define TAG "NfcDebugPcap" - -#define PCAP_MAGIC 0xa1b2c3d4 -#define PCAP_MAJOR 2 -#define PCAP_MINOR 4 -#define DLT_ISO_14443 264 - -#define DATA_PICC_TO_PCD 0xFF -#define DATA_PCD_TO_PICC 0xFE -#define DATA_PICC_TO_PCD_CRC_DROPPED 0xFB -#define DATA_PCD_TO_PICC_CRC_DROPPED 0xFA - -#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.pcap") - -struct NfcDebugPcap { - Stream* file_stream; -}; - -static Stream* nfc_debug_pcap_open(Storage* storage) { - Stream* stream = NULL; - stream = buffered_file_stream_alloc(storage); - if(!buffered_file_stream_open(stream, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) { - buffered_file_stream_close(stream); - stream_free(stream); - stream = NULL; - } else { - if(!stream_tell(stream)) { - struct { - uint32_t magic; - uint16_t major, minor; - uint32_t reserved[2]; - uint32_t snaplen; - uint32_t link_type; - } __attribute__((__packed__)) pcap_hdr = { - .magic = PCAP_MAGIC, - .major = PCAP_MAJOR, - .minor = PCAP_MINOR, - .snaplen = FURRY_HAL_NFC_DATA_BUFF_SIZE, - .link_type = DLT_ISO_14443, - }; - if(stream_write(stream, (uint8_t*)&pcap_hdr, sizeof(pcap_hdr)) != sizeof(pcap_hdr)) { - FURI_LOG_E(TAG, "Failed to write pcap header"); - buffered_file_stream_close(stream); - stream_free(stream); - stream = NULL; - } - } - } - return stream; -} - -NfcDebugPcap* nfc_debug_pcap_alloc() { - NfcDebugPcap* instance = malloc(sizeof(NfcDebugPcap)); - - Storage* storage = furi_record_open(RECORD_STORAGE); - instance->file_stream = nfc_debug_pcap_open(storage); - if(!instance->file_stream) { - free(instance); - instance = NULL; - } - furi_record_close(RECORD_STORAGE); - - return instance; -} - -void nfc_debug_pcap_free(NfcDebugPcap* instance) { - furi_assert(instance); - furi_assert(instance->file_stream); - - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - - free(instance); -} - -void nfc_debug_pcap_process_data( - NfcDebugPcap* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - furi_assert(instance); - furi_assert(data); - - uint8_t event = 0; - if(reader_to_tag) { - if(crc_dropped) { - event = DATA_PCD_TO_PICC_CRC_DROPPED; - } else { - event = DATA_PCD_TO_PICC; - } - } else { - if(crc_dropped) { - event = DATA_PICC_TO_PCD_CRC_DROPPED; - } else { - event = DATA_PICC_TO_PCD; - } - } - - struct { - // https://wiki.wireshark.org/Development/LibpcapFileFormat#record-packet-header - uint32_t ts_sec; - uint32_t ts_usec; - uint32_t incl_len; - uint32_t orig_len; - // https://www.kaiser.cx/posts/pcap-iso14443/#_packet_data - uint8_t version; - uint8_t event; - uint16_t len; - } __attribute__((__packed__)) pkt_hdr = { - .ts_sec = furi_hal_rtc_get_timestamp(), - .ts_usec = 0, - .incl_len = len + 4, - .orig_len = len + 4, - .version = 0, - .event = event, - .len = len << 8 | len >> 8, - }; - stream_write(instance->file_stream, (uint8_t*)&pkt_hdr, sizeof(pkt_hdr)); - stream_write(instance->file_stream, data, len); -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.h deleted file mode 100644 index eeddc56112c..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_debug_pcap.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -typedef struct NfcDebugPcap NfcDebugPcap; - -NfcDebugPcap* nfc_debug_pcap_alloc(); - -void nfc_debug_pcap_free(NfcDebugPcap* instance); - -void nfc_debug_pcap_process_data( - NfcDebugPcap* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped); diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.c deleted file mode 100644 index 5ab6280680b..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.c +++ /dev/null @@ -1,548 +0,0 @@ -#include -#include "nfc_generators.h" - -#define NXP_MANUFACTURER_ID (0x04) - -static const uint8_t version_bytes_mf0ulx1[] = {0x00, 0x04, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03}; -static const uint8_t version_bytes_ntag21x[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x03}; -static const uint8_t version_bytes_ntag_i2c[] = {0x00, 0x04, 0x04, 0x05, 0x02, 0x00, 0x00, 0x03}; -static const uint8_t default_data_ntag203[] = - {0xE1, 0x10, 0x12, 0x00, 0x01, 0x03, 0xA0, 0x10, 0x44, 0x03, 0x00, 0xFE}; -static const uint8_t default_data_ntag213[] = {0x01, 0x03, 0xA0, 0x0C, 0x34, 0x03, 0x00, 0xFE}; -static const uint8_t default_data_ntag215_216[] = {0x03, 0x00, 0xFE}; -static const uint8_t default_data_ntag_i2c[] = {0xE1, 0x10, 0x00, 0x00, 0x03, 0x00, 0xFE}; -static const uint8_t default_config_ntag_i2c[] = {0x01, 0x00, 0xF8, 0x48, 0x08, 0x01, 0x00, 0x00}; - -static void nfc_generate_common_start(NfcDeviceData* data) { - nfc_device_data_clear(data); -} - -static void nfc_generate_mf_ul_uid(uint8_t* uid) { - uid[0] = NXP_MANUFACTURER_ID; - furi_hal_random_fill_buf(&uid[1], 6); - // I'm not sure how this is generated, but the upper nybble always seems to be 8 - uid[6] &= 0x0F; - uid[6] |= 0x80; -} - -static void nfc_generate_mf_classic_uid(uint8_t* uid, uint8_t length) { - uid[0] = NXP_MANUFACTURER_ID; - furi_hal_random_fill_buf(&uid[1], length - 1); -} - -static void nfc_generate_mf_classic_block_0( - uint8_t* block, - uint8_t uid_len, - uint8_t sak, - uint8_t atqa0, - uint8_t atqa1) { - // Block length is always 16 bytes, and the UID can be either 4 or 7 bytes - furi_assert(uid_len == 4 || uid_len == 7); - furi_assert(block); - - if(uid_len == 4) { - // Calculate BCC - block[uid_len] = 0; - - for(int i = 0; i < uid_len; i++) { - block[uid_len] ^= block[i]; - } - } else { - uid_len -= 1; - } - - block[uid_len + 1] = sak; - block[uid_len + 2] = atqa0; - block[uid_len + 3] = atqa1; - - for(int i = uid_len + 4; i < 16; i++) { - block[i] = 0xFF; - } -} - -static void nfc_generate_mf_classic_sector_trailer(MfClassicData* data, uint8_t block) { - // All keys are set to FFFF FFFF FFFFh at chip delivery and the bytes 6, 7 and 8 are set to FF0780h. - MfClassicSectorTrailer* sec_tr = (MfClassicSectorTrailer*)data->block[block].value; - sec_tr->access_bits[0] = 0xFF; - sec_tr->access_bits[1] = 0x07; - sec_tr->access_bits[2] = 0x80; - sec_tr->access_bits[3] = 0x69; // Nice - - memset(sec_tr->key_a, 0xff, sizeof(sec_tr->key_a)); - memset(sec_tr->key_b, 0xff, sizeof(sec_tr->key_b)); - - mf_classic_set_block_read(data, block, &data->block[block]); - mf_classic_set_key_found( - data, mf_classic_get_sector_by_block(block), MfClassicKeyA, 0xFFFFFFFFFFFF); - mf_classic_set_key_found( - data, mf_classic_get_sector_by_block(block), MfClassicKeyB, 0xFFFFFFFFFFFF); -} - -static void nfc_generate_mf_ul_common(NfcDeviceData* data) { - data->nfc_data.type = FurryHalNfcTypeA; - data->nfc_data.interface = FurryHalNfcInterfaceRf; - data->nfc_data.uid_len = 7; - nfc_generate_mf_ul_uid(data->nfc_data.uid); - data->nfc_data.atqa[0] = 0x44; - data->nfc_data.atqa[1] = 0x00; - data->nfc_data.sak = 0x00; - data->protocol = NfcDeviceProtocolMifareUl; -} - -static void - nfc_generate_mf_classic_common(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { - data->nfc_data.type = FurryHalNfcTypeA; - data->nfc_data.interface = FurryHalNfcInterfaceRf; - data->nfc_data.uid_len = uid_len; - data->nfc_data.atqa[0] = 0x44; - data->nfc_data.atqa[1] = 0x00; - data->nfc_data.sak = 0x08; - data->protocol = NfcDeviceProtocolMifareClassic; - data->mf_classic_data.type = type; -} - -static void nfc_generate_calc_bcc(uint8_t* uid, uint8_t* bcc0, uint8_t* bcc1) { - *bcc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; - *bcc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; -} - -static void nfc_generate_mf_ul_copy_uid_with_bcc(NfcDeviceData* data) { - MfUltralightData* mful = &data->mf_ul_data; - memcpy(mful->data, data->nfc_data.uid, 3); - memcpy(&mful->data[4], &data->nfc_data.uid[3], 4); - nfc_generate_calc_bcc(data->nfc_data.uid, &mful->data[3], &mful->data[8]); -} - -static void nfc_generate_mf_ul_orig(NfcDeviceData* data) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUnknown; - mful->data_size = 16 * 4; - mful->data_read = mful->data_size; - nfc_generate_mf_ul_copy_uid_with_bcc(data); - // TODO: what's internal byte on page 2? - memset(&mful->data[4 * 4], 0xFF, 4); -} - -static void nfc_generate_mf_ul_ntag203(NfcDeviceData* data) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG203; - mful->data_size = 42 * 4; - mful->data_read = mful->data_size; - nfc_generate_mf_ul_copy_uid_with_bcc(data); - mful->data[9] = 0x48; // Internal byte - memcpy(&mful->data[3 * 4], default_data_ntag203, sizeof(default_data_ntag203)); -} - -static void nfc_generate_mf_ul_with_config_common(NfcDeviceData* data, uint8_t num_pages) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->data_size = num_pages * 4; - mful->data_read = mful->data_size; - nfc_generate_mf_ul_copy_uid_with_bcc(data); - uint16_t config_index = (num_pages - 4) * 4; - mful->data[config_index] = 0x04; // STRG_MOD_EN - mful->data[config_index + 3] = 0xFF; // AUTH0 - mful->data[config_index + 5] = 0x05; // VCTID - memset(&mful->data[config_index + 8], 0xFF, 4); // Default PWD - if(num_pages > 20) mful->data[config_index - 1] = MF_UL_TEARING_FLAG_DEFAULT; -} - -static void nfc_generate_mf_ul_ev1_common(NfcDeviceData* data, uint8_t num_pages) { - nfc_generate_mf_ul_with_config_common(data, num_pages); - MfUltralightData* mful = &data->mf_ul_data; - memcpy(&mful->version, version_bytes_mf0ulx1, sizeof(version_bytes_mf0ulx1)); - for(size_t i = 0; i < 3; ++i) { - mful->tearing[i] = MF_UL_TEARING_FLAG_DEFAULT; - } - // TODO: what's internal byte on page 2? -} - -static void nfc_generate_mf_ul_11(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 20); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL11; - mful->version.prod_subtype = 0x01; - mful->version.storage_size = 0x0B; - mful->data[16 * 4] = 0x00; // Low capacitance version does not have STRG_MOD_EN -} - -static void nfc_generate_mf_ul_h11(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 20); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL11; - mful->version.prod_subtype = 0x02; - mful->version.storage_size = 0x0B; -} - -static void nfc_generate_mf_ul_21(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 41); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL21; - mful->version.prod_subtype = 0x01; - mful->version.storage_size = 0x0E; - mful->data[37 * 4] = 0x00; // Low capacitance version does not have STRG_MOD_EN -} - -static void nfc_generate_mf_ul_h21(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 41); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL21; - mful->version.prod_subtype = 0x02; - mful->version.storage_size = 0x0E; -} - -static void nfc_generate_ntag21x_common(NfcDeviceData* data, uint8_t num_pages) { - nfc_generate_mf_ul_with_config_common(data, num_pages); - MfUltralightData* mful = &data->mf_ul_data; - memcpy(&mful->version, version_bytes_ntag21x, sizeof(version_bytes_mf0ulx1)); - mful->data[9] = 0x48; // Internal byte - // Capability container - mful->data[12] = 0xE1; - mful->data[13] = 0x10; -} - -static void nfc_generate_ntag213(NfcDeviceData* data) { - nfc_generate_ntag21x_common(data, 45); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG213; - mful->version.storage_size = 0x0F; - mful->data[14] = 0x12; - // Default contents - memcpy(&mful->data[16], default_data_ntag213, sizeof(default_data_ntag213)); -} - -static void nfc_generate_ntag215(NfcDeviceData* data) { - nfc_generate_ntag21x_common(data, 135); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG215; - mful->version.storage_size = 0x11; - mful->data[14] = 0x3E; - // Default contents - memcpy(&mful->data[16], default_data_ntag215_216, sizeof(default_data_ntag215_216)); -} - -static void nfc_generate_ntag216(NfcDeviceData* data) { - nfc_generate_ntag21x_common(data, 231); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG216; - mful->version.storage_size = 0x13; - mful->data[14] = 0x6D; - // Default contents - memcpy(&mful->data[16], default_data_ntag215_216, sizeof(default_data_ntag215_216)); -} - -static void - nfc_generate_ntag_i2c_common(NfcDeviceData* data, MfUltralightType type, uint16_t num_pages) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->type = type; - memcpy(&mful->version, version_bytes_ntag_i2c, sizeof(version_bytes_ntag_i2c)); - mful->data_size = num_pages * 4; - mful->data_read = mful->data_size; - memcpy(mful->data, data->nfc_data.uid, data->nfc_data.uid_len); - mful->data[7] = data->nfc_data.sak; - mful->data[8] = data->nfc_data.atqa[0]; - mful->data[9] = data->nfc_data.atqa[1]; - - uint16_t config_register_page; - uint16_t session_register_page; - - // Sync with mifare_ultralight.c - switch(type) { - case MfUltralightTypeNTAGI2C1K: - config_register_page = 227; - session_register_page = 229; - break; - case MfUltralightTypeNTAGI2C2K: - config_register_page = 481; - session_register_page = 483; - break; - case MfUltralightTypeNTAGI2CPlus1K: - case MfUltralightTypeNTAGI2CPlus2K: - config_register_page = 232; - session_register_page = 234; - break; - default: - furi_crash("Unknown MFUL"); - break; - } - - memcpy( - &mful->data[config_register_page * 4], - default_config_ntag_i2c, - sizeof(default_config_ntag_i2c)); - memcpy( - &mful->data[session_register_page * 4], - default_config_ntag_i2c, - sizeof(default_config_ntag_i2c)); -} - -static void nfc_generate_ntag_i2c_1k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_common(data, MfUltralightTypeNTAGI2C1K, 231); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x01; - mful->version.storage_size = 0x13; - - memcpy(&mful->data[12], default_data_ntag_i2c, sizeof(default_data_ntag_i2c)); - mful->data[14] = 0x6D; // Size of tag in CC -} - -static void nfc_generate_ntag_i2c_2k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_common(data, MfUltralightTypeNTAGI2C2K, 485); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x01; - mful->version.storage_size = 0x15; - - memcpy(&mful->data[12], default_data_ntag_i2c, sizeof(default_data_ntag_i2c)); - mful->data[14] = 0xEA; // Size of tag in CC -} - -static void nfc_generate_ntag_i2c_plus_common( - NfcDeviceData* data, - MfUltralightType type, - uint16_t num_pages) { - nfc_generate_ntag_i2c_common(data, type, num_pages); - - MfUltralightData* mful = &data->mf_ul_data; - uint16_t config_index = 227 * 4; - mful->data[config_index + 3] = 0xFF; // AUTH0 - memset(&mful->data[config_index + 8], 0xFF, 4); // Default PWD -} - -static void nfc_generate_ntag_i2c_plus_1k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_plus_common(data, MfUltralightTypeNTAGI2CPlus1K, 236); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x02; - mful->version.storage_size = 0x13; -} - -static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_plus_common(data, MfUltralightTypeNTAGI2CPlus2K, 492); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x02; - mful->version.storage_size = 0x15; -} - -void nfc_generate_mf_classic_ext( - NfcDeviceData* data, - uint8_t uid_len, - MfClassicType type, - bool random_uid, - uint8_t* uid) { - nfc_generate_common_start(data); - if(random_uid) { - nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len); - } else { - memcpy(data->mf_classic_data.block[0].value, uid, uid_len); - } - nfc_generate_mf_classic_common(data, uid_len, type); - - // Set the UID - if(random_uid) { - data->nfc_data.uid[0] = NXP_MANUFACTURER_ID; - for(int i = 1; i < uid_len; i++) { - data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i]; - } - } else { - for(int i = 0; i < uid_len; i++) { - data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i]; - } - } - - MfClassicData* mfc = &data->mf_classic_data; - mf_classic_set_block_read(mfc, 0, &mfc->block[0]); - - if(type == MfClassicType4k) { - // Set every block to 0xFF - for(uint16_t i = 1; i < 256; i += 1) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc, i); - } else { - memset(&mfc->block[i].value, 0xFF, 16); - } - mf_classic_set_block_read(mfc, i, &mfc->block[i]); - } - // Set SAK to 18 - data->nfc_data.sak = 0x18; - } else if(type == MfClassicType1k) { - // Set every block to 0xFF - for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc, i); - } else { - memset(&mfc->block[i].value, 0xFF, 16); - } - mf_classic_set_block_read(mfc, i, &mfc->block[i]); - } - // Set SAK to 08 - data->nfc_data.sak = 0x08; - } else if(type == MfClassicTypeMini) { - // Set every block to 0xFF - for(uint16_t i = 1; i < MF_MINI_TOTAL_SECTORS_NUM * 4; i += 1) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc, i); - } else { - memset(&mfc->block[i].value, 0xFF, 16); - } - mf_classic_set_block_read(mfc, i, &mfc->block[i]); - } - // Set SAK to 09 - data->nfc_data.sak = 0x09; - } - - nfc_generate_mf_classic_block_0( - data->mf_classic_data.block[0].value, - uid_len, - data->nfc_data.sak, - data->nfc_data.atqa[0], - data->nfc_data.atqa[1]); - - mfc->type = type; -} - -void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { - uint8_t uid = 0; - nfc_generate_mf_classic_ext(data, uid_len, type, true, &uid); -} - -static void nfc_generate_mf_mini(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 4, MfClassicTypeMini); -} - -static void nfc_generate_mf_classic_1k_4b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 4, MfClassicType1k); -} - -static void nfc_generate_mf_classic_1k_7b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 7, MfClassicType1k); -} - -static void nfc_generate_mf_classic_4k_4b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 4, MfClassicType4k); -} - -static void nfc_generate_mf_classic_4k_7b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 7, MfClassicType4k); -} - -static const NfcGenerator mf_ul_generator = { - .name = "Mifare Ultralight", - .generator_func = nfc_generate_mf_ul_orig, -}; - -static const NfcGenerator mf_ul_11_generator = { - .name = "Mifare Ultralight EV1 11", - .generator_func = nfc_generate_mf_ul_11, -}; - -static const NfcGenerator mf_ul_h11_generator = { - .name = "Mifare Ultralight EV1 H11", - .generator_func = nfc_generate_mf_ul_h11, -}; - -static const NfcGenerator mf_ul_21_generator = { - .name = "Mifare Ultralight EV1 21", - .generator_func = nfc_generate_mf_ul_21, -}; - -static const NfcGenerator mf_ul_h21_generator = { - .name = "Mifare Ultralight EV1 H21", - .generator_func = nfc_generate_mf_ul_h21, -}; - -static const NfcGenerator ntag203_generator = { - .name = "NTAG203", - .generator_func = nfc_generate_mf_ul_ntag203, -}; - -static const NfcGenerator ntag213_generator = { - .name = "NTAG213", - .generator_func = nfc_generate_ntag213, -}; - -static const NfcGenerator ntag215_generator = { - .name = "NTAG215", - .generator_func = nfc_generate_ntag215, -}; - -static const NfcGenerator ntag216_generator = { - .name = "NTAG216", - .generator_func = nfc_generate_ntag216, -}; - -static const NfcGenerator ntag_i2c_1k_generator = { - .name = "NTAG I2C 1k", - .generator_func = nfc_generate_ntag_i2c_1k, -}; - -static const NfcGenerator ntag_i2c_2k_generator = { - .name = "NTAG I2C 2k", - .generator_func = nfc_generate_ntag_i2c_2k, -}; - -static const NfcGenerator ntag_i2c_plus_1k_generator = { - .name = "NTAG I2C Plus 1k", - .generator_func = nfc_generate_ntag_i2c_plus_1k, -}; - -static const NfcGenerator ntag_i2c_plus_2k_generator = { - .name = "NTAG I2C Plus 2k", - .generator_func = nfc_generate_ntag_i2c_plus_2k, -}; - -static const NfcGenerator mifare_mini_generator = { - .name = "Mifare Mini", - .generator_func = nfc_generate_mf_mini, -}; - -static const NfcGenerator mifare_classic_1k_4b_uid_generator = { - .name = "Mifare Classic 1k 4byte UID", - .generator_func = nfc_generate_mf_classic_1k_4b_uid, -}; - -static const NfcGenerator mifare_classic_1k_7b_uid_generator = { - .name = "Mifare Classic 1k 7byte UID", - .generator_func = nfc_generate_mf_classic_1k_7b_uid, -}; - -static const NfcGenerator mifare_classic_4k_4b_uid_generator = { - .name = "Mifare Classic 4k 4byte UID", - .generator_func = nfc_generate_mf_classic_4k_4b_uid, -}; - -static const NfcGenerator mifare_classic_4k_7b_uid_generator = { - .name = "Mifare Classic 4k 7byte UID", - .generator_func = nfc_generate_mf_classic_4k_7b_uid, -}; - -const NfcGenerator* const nfc_generators[] = { - &mf_ul_generator, - &mf_ul_11_generator, - &mf_ul_h11_generator, - &mf_ul_21_generator, - &mf_ul_h21_generator, - &ntag203_generator, - &ntag213_generator, - &ntag215_generator, - &ntag216_generator, - &ntag_i2c_1k_generator, - &ntag_i2c_2k_generator, - &ntag_i2c_plus_1k_generator, - &ntag_i2c_plus_2k_generator, - &mifare_mini_generator, - &mifare_classic_1k_4b_uid_generator, - &mifare_classic_1k_7b_uid_generator, - &mifare_classic_4k_4b_uid_generator, - &mifare_classic_4k_7b_uid_generator, - NULL, -}; diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.h deleted file mode 100644 index 5102d0bc309..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/nfc_generators.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "../nfc_device.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*NfcGeneratorFunc)(NfcDeviceData* data); - -typedef struct { - const char* name; - NfcGeneratorFunc generator_func; -} NfcGenerator; - -extern const NfcGenerator* const nfc_generators[]; - -void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type); - -void nfc_generate_mf_classic_ext( - NfcDeviceData* data, - uint8_t uid_len, - MfClassicType type, - bool random_uid, - uint8_t* uid); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.c deleted file mode 100644 index a3d82c67525..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.c +++ /dev/null @@ -1,265 +0,0 @@ -#include "reader_analyzer.h" -#include "../protocols/nfc_util.h" -#include "../protocols/mifare_classic.h" -#include - -#include "mfkey32.h" -#include "nfc_debug_pcap.h" -#include "nfc_debug_log.h" - -#define TAG "ReaderAnalyzer" - -#define READER_ANALYZER_MAX_BUFF_SIZE (1024) - -typedef struct { - bool reader_to_tag; - bool crc_dropped; - uint16_t len; -} ReaderAnalyzerHeader; - -typedef enum { - ReaderAnalyzerNfcDataMfClassic, -} ReaderAnalyzerNfcData; - -struct ReaderAnalyzer { - FurryHalNfcDevData nfc_data; - - bool alive; - FuriStreamBuffer* stream; - FuriThread* thread; - - ReaderAnalyzerParseDataCallback callback; - void* context; - - ReaderAnalyzerMode mode; - Mfkey32* mfkey32; - NfcDebugLog* debug_log; - NfcDebugPcap* pcap; -}; - -const FurryHalNfcDevData reader_analyzer_nfc_data[] = { - [ReaderAnalyzerNfcDataMfClassic] = - {.sak = 0x08, - .atqa = {0x44, 0x00}, - .interface = FurryHalNfcInterfaceRf, - .type = FurryHalNfcTypeA, - .uid_len = 7, - .uid = {0x04, 0x77, 0x70, 0x2A, 0x23, 0x4F, 0x80}, - .cuid = 0x2A234F80}, -}; - -void reader_analyzer_parse(ReaderAnalyzer* instance, uint8_t* buffer, size_t size) { - if(size < sizeof(ReaderAnalyzerHeader)) return; - - size_t bytes_i = 0; - while(bytes_i < size) { - ReaderAnalyzerHeader* header = (ReaderAnalyzerHeader*)&buffer[bytes_i]; - uint16_t len = header->len; - if(bytes_i + len > size) break; - bytes_i += sizeof(ReaderAnalyzerHeader); - if(instance->mfkey32) { - mfkey32_process_data( - instance->mfkey32, - &buffer[bytes_i], - len, - header->reader_to_tag, - header->crc_dropped); - } - if(instance->pcap) { - nfc_debug_pcap_process_data( - instance->pcap, &buffer[bytes_i], len, header->reader_to_tag, header->crc_dropped); - } - if(instance->debug_log) { - nfc_debug_log_process_data( - instance->debug_log, - &buffer[bytes_i], - len, - header->reader_to_tag, - header->crc_dropped); - } - bytes_i += len; - } -} - -int32_t reader_analyzer_thread(void* context) { - ReaderAnalyzer* reader_analyzer = context; - uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {}; - - while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) { - size_t ret = furi_stream_buffer_receive( - reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50); - if(ret) { - reader_analyzer_parse(reader_analyzer, buffer, ret); - } - } - - return 0; -} - -ReaderAnalyzer* reader_analyzer_alloc() { - ReaderAnalyzer* instance = malloc(sizeof(ReaderAnalyzer)); - - instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; - instance->alive = false; - instance->stream = - furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); - - instance->thread = - furi_thread_alloc_ex("ReaderAnalyzerWorker", 2048, reader_analyzer_thread, instance); - furi_thread_set_priority(instance->thread, FuriThreadPriorityLow); - - return instance; -} - -static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) { - furi_assert(context); - ReaderAnalyzer* instance = context; - - if(event == Mfkey32EventParamCollected) { - if(instance->callback) { - instance->callback(ReaderAnalyzerEventMfkeyCollected, instance->context); - } - } -} - -void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) { - furi_assert(instance); - - furi_stream_buffer_reset(instance->stream); - if(mode & ReaderAnalyzerModeDebugLog) { - instance->debug_log = nfc_debug_log_alloc(); - } - if(mode & ReaderAnalyzerModeMfkey) { - instance->mfkey32 = mfkey32_alloc(instance->nfc_data.cuid); - if(instance->mfkey32) { - mfkey32_set_callback(instance->mfkey32, reader_analyzer_mfkey_callback, instance); - } - } - if(mode & ReaderAnalyzerModeDebugPcap) { - instance->pcap = nfc_debug_pcap_alloc(); - } - - instance->alive = true; - furi_thread_start(instance->thread); -} - -void reader_analyzer_stop(ReaderAnalyzer* instance) { - furi_assert(instance); - - instance->alive = false; - furi_thread_join(instance->thread); - - if(instance->debug_log) { - nfc_debug_log_free(instance->debug_log); - instance->debug_log = NULL; - } - if(instance->mfkey32) { - mfkey32_free(instance->mfkey32); - instance->mfkey32 = NULL; - } - if(instance->pcap) { - nfc_debug_pcap_free(instance->pcap); - instance->pcap = NULL; - } -} - -void reader_analyzer_free(ReaderAnalyzer* instance) { - furi_assert(instance); - - reader_analyzer_stop(instance); - furi_thread_free(instance->thread); - furi_stream_buffer_free(instance->stream); - free(instance); -} - -void reader_analyzer_set_callback( - ReaderAnalyzer* instance, - ReaderAnalyzerParseDataCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -NfcProtocol - reader_analyzer_guess_protocol(ReaderAnalyzer* instance, uint8_t* buff_rx, uint16_t len) { - furi_assert(instance); - furi_assert(buff_rx); - UNUSED(len); - NfcProtocol protocol = NfcDeviceProtocolUnknown; - - if((buff_rx[0] == 0x60) || (buff_rx[0] == 0x61)) { - protocol = NfcDeviceProtocolMifareClassic; - } - - return protocol; -} - -FurryHalNfcDevData* reader_analyzer_get_nfc_data(ReaderAnalyzer* instance) { - furi_assert(instance); - instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; - return &instance->nfc_data; -} - -void reader_analyzer_set_nfc_data(ReaderAnalyzer* instance, FurryHalNfcDevData* nfc_data) { - furi_assert(instance); - furi_assert(nfc_data); - - memcpy(&instance->nfc_data, nfc_data, sizeof(FurryHalNfcDevData)); -} - -static void reader_analyzer_write( - ReaderAnalyzer* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - ReaderAnalyzerHeader header = { - .reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len}; - size_t data_sent = 0; - data_sent = furi_stream_buffer_send( - instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever); - if(data_sent != sizeof(ReaderAnalyzerHeader)) { - FURI_LOG_W(TAG, "Sent %zu out of %zu bytes", data_sent, sizeof(ReaderAnalyzerHeader)); - } - data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever); - if(data_sent != len) { - FURI_LOG_W(TAG, "Sent %zu out of %u bytes", data_sent, len); - } -} - -static void - reader_analyzer_write_rx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) { - UNUSED(crc_dropped); - ReaderAnalyzer* reader_analyzer = context; - uint16_t bytes = bits < 8 ? 1 : bits / 8; - reader_analyzer_write(reader_analyzer, data, bytes, false, crc_dropped); -} - -static void - reader_analyzer_write_tx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) { - UNUSED(crc_dropped); - ReaderAnalyzer* reader_analyzer = context; - uint16_t bytes = bits < 8 ? 1 : bits / 8; - reader_analyzer_write(reader_analyzer, data, bytes, true, crc_dropped); -} - -void reader_analyzer_prepare_tx_rx( - ReaderAnalyzer* instance, - FurryHalNfcTxRxContext* tx_rx, - bool is_picc) { - furi_assert(instance); - furi_assert(tx_rx); - - if(is_picc) { - tx_rx->sniff_tx = reader_analyzer_write_rx; - tx_rx->sniff_rx = reader_analyzer_write_tx; - } else { - tx_rx->sniff_rx = reader_analyzer_write_rx; - tx_rx->sniff_tx = reader_analyzer_write_tx; - } - - tx_rx->sniff_context = instance; -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.h deleted file mode 100644 index 5b9124a733d..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/helpers/reader_analyzer.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include "../nfc_device.h" - -typedef enum { - ReaderAnalyzerModeDebugLog = 0x01, - ReaderAnalyzerModeMfkey = 0x02, - ReaderAnalyzerModeDebugPcap = 0x04, -} ReaderAnalyzerMode; - -typedef enum { - ReaderAnalyzerEventMfkeyCollected, -} ReaderAnalyzerEvent; - -typedef struct ReaderAnalyzer ReaderAnalyzer; - -typedef void (*ReaderAnalyzerParseDataCallback)(ReaderAnalyzerEvent event, void* context); - -ReaderAnalyzer* reader_analyzer_alloc(); - -void reader_analyzer_free(ReaderAnalyzer* instance); - -void reader_analyzer_set_callback( - ReaderAnalyzer* instance, - ReaderAnalyzerParseDataCallback callback, - void* context); - -void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode); - -void reader_analyzer_stop(ReaderAnalyzer* instance); - -NfcProtocol - reader_analyzer_guess_protocol(ReaderAnalyzer* instance, uint8_t* buff_rx, uint16_t len); - -FurryHalNfcDevData* reader_analyzer_get_nfc_data(ReaderAnalyzer* instance); - -void reader_analyzer_set_nfc_data(ReaderAnalyzer* instance, FurryHalNfcDevData* nfc_data); - -void reader_analyzer_prepare_tx_rx( - ReaderAnalyzer* instance, - FurryHalNfcTxRxContext* tx_rx, - bool is_picc); diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.c index 47dcea74e20..7467dd9355d 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.c +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.c @@ -13,11 +13,7 @@ static const char* nfc_file_header = "Flipper NFC device"; static const uint32_t nfc_file_version = 3; -static const char* nfc_keys_file_header = "Flipper NFC keys"; -static const uint32_t nfc_keys_file_version = 1; - // Protocols format versions -static const uint32_t nfc_mifare_classic_data_format_version = 2; static const uint32_t nfc_mifare_ultralight_data_format_version = 1; NfcDevice* nfc_device_alloc() { @@ -236,330 +232,6 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { return parsed; } -static void nfc_device_write_mifare_classic_block( - FuriString* block_str, - MfClassicData* data, - uint8_t block_num) { - furi_string_reset(block_str); - bool is_sec_trailer = mf_classic_is_sector_trailer(block_num); - if(is_sec_trailer) { - uint8_t sector_num = mf_classic_get_sector_by_block(block_num); - MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sector_num); - // Write key A - for(size_t i = 0; i < sizeof(sec_tr->key_a); i++) { - if(mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) { - furi_string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]); - } else { - furi_string_cat_printf(block_str, "?? "); - } - } - // Write Access bytes - for(size_t i = 0; i < MF_CLASSIC_ACCESS_BYTES_SIZE; i++) { - if(mf_classic_is_block_read(data, block_num)) { - furi_string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]); - } else { - furi_string_cat_printf(block_str, "?? "); - } - } - // Write key B - for(size_t i = 0; i < sizeof(sec_tr->key_b); i++) { - if(mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) { - furi_string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]); - } else { - furi_string_cat_printf(block_str, "?? "); - } - } - } else { - // Write data block - for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { - if(mf_classic_is_block_read(data, block_num)) { - furi_string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]); - } else { - furi_string_cat_printf(block_str, "?? "); - } - } - } - furi_string_trim(block_str); -} - -static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { - bool saved = false; - MfClassicData* data = &dev->dev_data.mf_classic_data; - FuriString* temp_str; - temp_str = furi_string_alloc(); - uint16_t blocks = 0; - - // Save Mifare Classic specific data - do { - if(!flipper_format_write_comment_cstr(file, "Mifare Classic specific data")) break; - - if(data->type == MfClassicTypeMini) { - if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break; - blocks = 20; - } else if(data->type == MfClassicType1k) { - if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break; - blocks = 64; - } else if(data->type == MfClassicType4k) { - if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break; - blocks = 256; - } - if(!flipper_format_write_uint32( - file, "Data format version", &nfc_mifare_classic_data_format_version, 1)) - break; - if(!flipper_format_write_comment_cstr( - file, "Mifare Classic blocks, \'??\' means unknown data")) - break; - bool block_saved = true; - FuriString* block_str; - block_str = furi_string_alloc(); - for(size_t i = 0; i < blocks; i++) { - furi_string_printf(temp_str, "Block %d", i); - nfc_device_write_mifare_classic_block(block_str, data, i); - if(!flipper_format_write_string(file, furi_string_get_cstr(temp_str), block_str)) { - block_saved = false; - break; - } - } - furi_string_free(block_str); - if(!block_saved) break; - saved = true; - } while(false); - - furi_string_free(temp_str); - return saved; -} - -static void nfc_device_load_mifare_classic_block( - FuriString* block_str, - MfClassicData* data, - uint8_t block_num) { - furi_string_trim(block_str); - MfClassicBlock block_tmp = {}; - bool is_sector_trailer = mf_classic_is_sector_trailer(block_num); - uint8_t sector_num = mf_classic_get_sector_by_block(block_num); - uint16_t block_unknown_bytes_mask = 0; - - furi_string_trim(block_str); - for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { - char hi = furi_string_get_char(block_str, 3 * i); - char low = furi_string_get_char(block_str, 3 * i + 1); - uint8_t byte = 0; - if(hex_char_to_uint8(hi, low, &byte)) { - block_tmp.value[i] = byte; - } else { - FURI_BIT_SET(block_unknown_bytes_mask, i); - } - } - - if(block_unknown_bytes_mask == 0xffff) { - // All data is unknown, exit - return; - } - - if(is_sector_trailer) { - MfClassicSectorTrailer* sec_tr_tmp = (MfClassicSectorTrailer*)&block_tmp; - // Load Key A - // Key A mask 0b0000000000111111 = 0x003f - if((block_unknown_bytes_mask & 0x003f) == 0) { - uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_a, sizeof(sec_tr_tmp->key_a)); - mf_classic_set_key_found(data, sector_num, MfClassicKeyA, key); - } - // Load Access Bits - // Access bits mask 0b0000001111000000 = 0x03c0 - if((block_unknown_bytes_mask & 0x03c0) == 0) { - mf_classic_set_block_read(data, block_num, &block_tmp); - } - // Load Key B - // Key B mask 0b1111110000000000 = 0xfc00 - if((block_unknown_bytes_mask & 0xfc00) == 0) { - uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_b, sizeof(sec_tr_tmp->key_b)); - mf_classic_set_key_found(data, sector_num, MfClassicKeyB, key); - } - } else { - if(block_unknown_bytes_mask == 0) { - mf_classic_set_block_read(data, block_num, &block_tmp); - } - } -} - -static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { - bool parsed = false; - MfClassicData* data = &dev->dev_data.mf_classic_data; - FuriString* temp_str; - uint32_t data_format_version = 0; - temp_str = furi_string_alloc(); - uint16_t data_blocks = 0; - memset(data, 0, sizeof(MfClassicData)); - - do { - // Read Mifare Classic type - if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; - if(!furi_string_cmp(temp_str, "MINI")) { - data->type = MfClassicTypeMini; - data_blocks = 20; - } else if(!furi_string_cmp(temp_str, "1K")) { - data->type = MfClassicType1k; - data_blocks = 64; - } else if(!furi_string_cmp(temp_str, "4K")) { - data->type = MfClassicType4k; - data_blocks = 256; - } else { - break; - } - - bool old_format = false; - // Read Mifare Classic format version - if(!flipper_format_read_uint32(file, "Data format version", &data_format_version, 1)) { - // Load unread sectors with zero keys access for backward compatibility - if(!flipper_format_rewind(file)) break; - old_format = true; - } else { - if(data_format_version < nfc_mifare_classic_data_format_version) { - old_format = true; - } - } - - // Read Mifare Classic blocks - bool block_read = true; - FuriString* block_str; - block_str = furi_string_alloc(); - for(size_t i = 0; i < data_blocks; i++) { - furi_string_printf(temp_str, "Block %d", i); - if(!flipper_format_read_string(file, furi_string_get_cstr(temp_str), block_str)) { - block_read = false; - break; - } - nfc_device_load_mifare_classic_block(block_str, data, i); - } - furi_string_free(block_str); - if(!block_read) break; - - // Set keys and blocks as unknown for backward compatibility - if(old_format) { - data->key_a_mask = 0ULL; - data->key_b_mask = 0ULL; - memset(data->block_read_mask, 0, sizeof(data->block_read_mask)); - } - - parsed = true; - } while(false); - - furi_string_free(temp_str); - return parsed; -} - -static void nfc_device_get_key_cache_file_path(NfcDevice* dev, FuriString* file_path) { - uint8_t* uid = dev->dev_data.nfc_data.uid; - uint8_t uid_len = dev->dev_data.nfc_data.uid_len; - furi_string_set(file_path, NFC_DEVICE_KEYS_FOLDER "/"); - for(size_t i = 0; i < uid_len; i++) { - furi_string_cat_printf(file_path, "%02X", uid[i]); - } - furi_string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION); -} - -static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { - FlipperFormat* file = flipper_format_file_alloc(dev->storage); - MfClassicData* data = &dev->dev_data.mf_classic_data; - FuriString* temp_str; - temp_str = furi_string_alloc(); - - nfc_device_get_key_cache_file_path(dev, temp_str); - bool save_success = false; - do { - if(!storage_simply_mkdir(dev->storage, NFC_DEVICE_KEYS_FOLDER)) break; - if(!storage_simply_remove(dev->storage, furi_string_get_cstr(temp_str))) break; - if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; - if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version)) - break; - if(data->type == MfClassicTypeMini) { - if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break; - } else if(data->type == MfClassicType1k) { - if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break; - } else if(data->type == MfClassicType4k) { - if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break; - } - if(!flipper_format_write_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break; - if(!flipper_format_write_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break; - uint8_t sector_num = mf_classic_get_total_sectors_num(data->type); - bool key_save_success = true; - for(size_t i = 0; (i < sector_num) && (key_save_success); i++) { - MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); - if(FURI_BIT(data->key_a_mask, i)) { - furi_string_printf(temp_str, "Key A sector %d", i); - key_save_success = flipper_format_write_hex( - file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6); - } - if(!key_save_success) break; - if(FURI_BIT(data->key_b_mask, i)) { - furi_string_printf(temp_str, "Key B sector %d", i); - key_save_success = flipper_format_write_hex( - file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6); - } - } - save_success = key_save_success; - } while(false); - - flipper_format_free(file); - furi_string_free(temp_str); - return save_success; -} - -bool nfc_device_load_key_cache(NfcDevice* dev) { - furi_assert(dev); - FuriString* temp_str; - temp_str = furi_string_alloc(); - - MfClassicData* data = &dev->dev_data.mf_classic_data; - nfc_device_get_key_cache_file_path(dev, temp_str); - FlipperFormat* file = flipper_format_file_alloc(dev->storage); - - bool load_success = false; - do { - if(storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) != FSE_OK) - break; - if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break; - uint32_t version = 0; - if(!flipper_format_read_header(file, temp_str, &version)) break; - if(furi_string_cmp_str(temp_str, nfc_keys_file_header)) break; - if(version != nfc_keys_file_version) break; - if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; - if(!furi_string_cmp(temp_str, "MINI")) { - data->type = MfClassicTypeMini; - } else if(!furi_string_cmp(temp_str, "1K")) { - data->type = MfClassicType1k; - } else if(!furi_string_cmp(temp_str, "4K")) { - data->type = MfClassicType4k; - } else { - break; - } - if(!flipper_format_read_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break; - if(!flipper_format_read_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break; - uint8_t sectors = mf_classic_get_total_sectors_num(data->type); - bool key_read_success = true; - for(size_t i = 0; (i < sectors) && (key_read_success); i++) { - MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); - if(FURI_BIT(data->key_a_mask, i)) { - furi_string_printf(temp_str, "Key A sector %d", i); - key_read_success = flipper_format_read_hex( - file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6); - } - if(!key_read_success) break; - if(FURI_BIT(data->key_b_mask, i)) { - furi_string_printf(temp_str, "Key B sector %d", i); - key_read_success = flipper_format_read_hex( - file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6); - } - } - load_success = key_read_success; - } while(false); - - furi_string_free(temp_str); - flipper_format_free(file); - - return load_success; -} - void nfc_device_set_name(NfcDevice* dev, const char* name) { furi_assert(dev); @@ -638,11 +310,6 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) { // Save more data if necessary if(dev->format == NfcDeviceSaveFormatMifareUl) { if(!nfc_device_save_mifare_ul_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { - // Save data - if(!nfc_device_save_mifare_classic_data(file, dev)) break; - // Save keys cache - if(!nfc_device_save_mifare_classic_keys(dev)) break; } saved = true; } while(0); @@ -737,8 +404,6 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia // Parse other data if(dev->format == NfcDeviceSaveFormatMifareUl) { if(!nfc_device_load_mifare_ul_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { - if(!nfc_device_load_mifare_classic_data(file, dev)) break; } parsed = true; } while(false); @@ -780,9 +445,7 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog) { } void nfc_device_data_clear(NfcDeviceData* dev_data) { - if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { - memset(&dev_data->mf_classic_data, 0, sizeof(MfClassicData)); - } else if(dev_data->protocol == NfcDeviceProtocolMifareUl) { + if(dev_data->protocol == NfcDeviceProtocolMifareUl) { mf_ul_reset(&dev_data->mf_ul_data); } diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.h index ebfcdaa6282..af045bba694 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.h +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_device.h @@ -6,9 +6,7 @@ #include #include "./furi_hal_nfc.h" -#include "helpers/mf_classic_dict.h" #include "protocols/mifare_ultralight.h" -#include "protocols/mifare_classic.h" #ifdef __cplusplus extern "C" { @@ -47,11 +45,6 @@ typedef struct { uint16_t size; } NfcReaderRequestData; -typedef struct { - MfClassicDict* dict; - uint8_t current_sector; -} NfcMfClassicDictAttackData; - typedef enum { NfcReadModeAuto, NfcReadModeMfClassic, @@ -67,12 +60,10 @@ typedef struct { NfcReadMode read_mode; union { NfcReaderRequestData reader_data; - NfcMfClassicDictAttackData mf_classic_dict_attack_data; MfUltralightAuth mf_ul_auth; }; union { MfUltralightData mf_ul_data; - MfClassicData mf_classic_data; }; FuriString* parsed_data; } NfcDeviceData; diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.c index c3ebb7a4636..40079dc8131 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.c +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.c @@ -55,15 +55,3 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) { return "Mifare Ultralight"; } } - -const char* nfc_mf_classic_type(MfClassicType type) { - if(type == MfClassicTypeMini) { - return "Mifare Mini 0.3K"; - } else if(type == MfClassicType1k) { - return "Mifare Classic 1K"; - } else if(type == MfClassicType4k) { - return "Mifare Classic 4K"; - } else { - return "Mifare Classic"; - } -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.h index 4cdfac50c4e..5ccd8aefc13 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.h +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_types.h @@ -12,8 +12,6 @@ const char* nfc_guess_protocol(NfcProtocol protocol); const char* nfc_mf_ul_type(MfUltralightType type, bool full_name); -const char* nfc_mf_classic_type(MfClassicType type); - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker.c index aebd8b65908..b80f9aa8645 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker.c +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker.c @@ -23,8 +23,6 @@ NfcWorker* nfc_worker_alloc() { } nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); - nfc_worker->reader_analyzer = reader_analyzer_alloc(nfc_worker->storage); - return nfc_worker; } @@ -35,8 +33,6 @@ void nfc_worker_free(NfcWorker* nfc_worker) { furi_record_close(RECORD_STORAGE); - reader_analyzer_free(nfc_worker->reader_analyzer); - free(nfc_worker); } @@ -96,18 +92,8 @@ int32_t nfc_worker_task(void* context) { nfc_worker_emulate_uid(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) { nfc_worker_emulate_mf_ultralight(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { - nfc_worker_emulate_mf_classic(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateMfClassicWrite) { - nfc_worker_write_mf_classic(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateMfClassicUpdate) { - nfc_worker_update_mf_classic(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) { nfc_worker_mf_ultralight_read_auth(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) { - nfc_worker_mf_classic_dict_attack(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateAnalyzeReader) { - nfc_worker_analyze_reader(nfc_worker); } furry_hal_nfc_sleep(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); @@ -120,11 +106,6 @@ static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FurryHalNfcTxRx MfUltralightReader reader = {}; MfUltralightData data = {}; - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - do { furry_hal_nfc_sleep(); @@ -136,39 +117,6 @@ static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FurryHalNfcTxRx read_success = true; } while(false); - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } - - return read_success; -} - -static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FurryHalNfcTxRxContext* tx_rx) { - furi_assert(nfc_worker->callback); - bool read_success = false; - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - - do { - // Try to read card with key cache - FURI_LOG_I(TAG, "Search for key cache ..."); - if(nfc_worker->callback(NfcWorkerEventReadMfClassicLoadKeyCache, nfc_worker->context)) { - FURI_LOG_I(TAG, "Load keys cache success. Start reading"); - uint8_t sectors_read = - mf_classic_update_card(tx_rx, &nfc_worker->dev_data->mf_classic_data); - uint8_t sectors_total = - mf_classic_get_total_sectors_num(nfc_worker->dev_data->mf_classic_data.type); - FURI_LOG_I(TAG, "Read %d sectors out of %d total", sectors_read, sectors_total); - read_success = mf_classic_is_card_read(&nfc_worker->dev_data->mf_classic_data); - } - } while(false); - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } return read_success; } @@ -181,12 +129,6 @@ static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FurryHalNfcTxRxContext* FURI_LOG_I(TAG, "Mifare Ultralight / NTAG detected"); nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl; card_read = nfc_worker_read_mf_ultralight(nfc_worker, tx_rx); - } else if(mf_classic_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - FURI_LOG_I(TAG, "Mifare Classic detected"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; - nfc_worker->dev_data->mf_classic_data.type = - mf_classic_get_classic_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak); - card_read = nfc_worker_read_mf_classic(nfc_worker, tx_rx); } else if(nfc_data->interface == FurryHalNfcInterfaceIsoDep) { FURI_LOG_I(TAG, "ISO14443-4 card detected"); @@ -269,7 +211,7 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) { NfcReadMode read_mode = nfc_worker->dev_data->read_mode; nfc_device_data_clear(nfc_worker->dev_data); - NfcDeviceData* dev_data = nfc_worker->dev_data; + //NfcDeviceData* dev_data = nfc_worker->dev_data; FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; FurryHalNfcTxRxContext tx_rx = {}; NfcWorkerEvent event = 0; @@ -284,20 +226,7 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) { card_not_detected_notified = false; if(nfc_data->type == FurryHalNfcTypeA) { if(read_mode == NfcReadModeMfClassic) { - nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; - nfc_worker->dev_data->mf_classic_data.type = mf_classic_get_classic_type( - nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak); - if(nfc_worker_read_mf_classic(nfc_worker, &tx_rx)) { - FURI_LOG_D(TAG, "Card read"); - dev_data->protocol = NfcDeviceProtocolMifareClassic; - event = NfcWorkerEventReadMfClassicDone; - break; - } else { - FURI_LOG_D(TAG, "Card read failed"); - dev_data->protocol = NfcDeviceProtocolMifareClassic; - event = NfcWorkerEventReadMfClassicDictAttackRequired; - break; - } + // none } else if(read_mode == NfcReadModeMfUltralight) { FURI_LOG_I(TAG, "Mifare Ultralight / NTAG"); nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl; @@ -395,428 +324,6 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) { rfal_platform_spi_release(); } -static bool nfc_worker_mf_get_b_key_from_sector_trailer( - FurryHalNfcTxRxContext* tx_rx, - uint16_t sector, - uint64_t key, - uint64_t* found_key) { - // Some access conditions allow reading B key via A key - - uint8_t block = mf_classic_get_sector_trailer_block_num_by_sector(sector); - - Crypto1 crypto = {}; - MfClassicBlock block_tmp = {}; - MfClassicAuthContext auth_context = {.sector = sector, .key_a = MF_CLASSIC_NO_KEY, .key_b = 0}; - - furry_hal_nfc_sleep(); - - if(mf_classic_auth_attempt(tx_rx, &crypto, &auth_context, key)) { - if(mf_classic_read_block(tx_rx, &crypto, block, &block_tmp)) { - *found_key = nfc_util_bytes2num(&block_tmp.value[10], sizeof(uint8_t) * 6); - - return *found_key; - } - } - - return false; -} - -static void nfc_worker_mf_classic_key_attack( - NfcWorker* nfc_worker, - uint64_t key, - FurryHalNfcTxRxContext* tx_rx, - uint16_t start_sector) { - furi_assert(nfc_worker); - furi_assert(nfc_worker->callback); - - bool card_found_notified = true; - bool card_removed_notified = false; - - MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; - NfcMfClassicDictAttackData* dict_attack_data = - &nfc_worker->dev_data->mf_classic_dict_attack_data; - uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); - - furi_assert(start_sector < total_sectors); - - nfc_worker->callback(NfcWorkerEventKeyAttackStart, nfc_worker->context); - - // Check every sector's A and B keys with the given key - for(size_t i = start_sector; i < total_sectors; i++) { - nfc_worker->callback(NfcWorkerEventKeyAttackNextSector, nfc_worker->context); - dict_attack_data->current_sector = i; - furry_hal_nfc_sleep(); - if(furry_hal_nfc_activate_nfca(200, NULL)) { - furry_hal_nfc_sleep(); - if(!card_found_notified) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - card_found_notified = true; - card_removed_notified = false; - } - uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); - if(mf_classic_is_sector_read(data, i)) continue; - if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { - FURI_LOG_D(TAG, "Trying A key for sector %d, key: %012llX", i, key); - if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { - mf_classic_set_key_found(data, i, MfClassicKeyA, key); - FURI_LOG_D(TAG, "Key A found: %012llX", key); - nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); - - uint64_t found_key; - if(nfc_worker_mf_get_b_key_from_sector_trailer(tx_rx, i, key, &found_key)) { - FURI_LOG_D(TAG, "Found B key via reading sector %d", i); - mf_classic_set_key_found(data, i, MfClassicKeyB, found_key); - - if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) { - nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); - } - } - } - furry_hal_nfc_sleep(); - } - if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { - FURI_LOG_D(TAG, "Trying B key for sector %d, key: %012llX", i, key); - if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { - mf_classic_set_key_found(data, i, MfClassicKeyB, key); - FURI_LOG_D(TAG, "Key B found: %012llX", key); - nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); - } - } - - if(mf_classic_is_sector_read(data, i)) continue; - mf_classic_read_sector(tx_rx, data, i); - } else { - if(!card_removed_notified) { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - card_removed_notified = true; - card_found_notified = false; - } - } - if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; - } - nfc_worker->callback(NfcWorkerEventKeyAttackStop, nfc_worker->context); -} - -void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { - furi_assert(nfc_worker); - furi_assert(nfc_worker->callback); - - MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; - NfcMfClassicDictAttackData* dict_attack_data = - &nfc_worker->dev_data->mf_classic_dict_attack_data; - uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); - uint64_t key = 0; - uint64_t prev_key = 0; - FurryHalNfcTxRxContext tx_rx = {}; - bool card_found_notified = true; - bool card_removed_notified = false; - - // Load dictionary - MfClassicDict* dict = dict_attack_data->dict; - if(!dict) { - FURI_LOG_E(TAG, "Dictionary not found"); - nfc_worker->callback(NfcWorkerEventNoDictFound, nfc_worker->context); - return; - } - - FURI_LOG_D( - TAG, "Start Dictionary attack, Key Count %lu", mf_classic_dict_get_total_keys(dict)); - for(size_t i = 0; i < total_sectors; i++) { - FURI_LOG_I(TAG, "Sector %d", i); - nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context); - uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); - if(mf_classic_is_sector_read(data, i)) continue; - if(mf_classic_is_key_found(data, i, MfClassicKeyA) && - mf_classic_is_key_found(data, i, MfClassicKeyB)) - continue; - uint16_t key_index = 0; - while(mf_classic_dict_get_next_key(dict, &key)) { - FURI_LOG_T(TAG, "Key %d", key_index); - if(++key_index % NFC_DICT_KEY_BATCH_SIZE == 0) { - nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context); - } - furry_hal_nfc_sleep(); - uint32_t cuid; - if(furry_hal_nfc_activate_nfca(200, &cuid)) { - bool deactivated = false; - if(!card_found_notified) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - card_found_notified = true; - card_removed_notified = false; - nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i); - deactivated = true; - } - FURI_LOG_D(TAG, "Try to auth to sector %d with key %012llX", i, key); - if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { - if(mf_classic_authenticate_skip_activate( - &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) { - mf_classic_set_key_found(data, i, MfClassicKeyA, key); - FURI_LOG_D(TAG, "Key A found: %012llX", key); - nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); - - uint64_t found_key; - if(nfc_worker_mf_get_b_key_from_sector_trailer( - &tx_rx, i, key, &found_key)) { - FURI_LOG_D(TAG, "Found B key via reading sector %d", i); - mf_classic_set_key_found(data, i, MfClassicKeyB, found_key); - - if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) { - nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); - } - - nfc_worker_mf_classic_key_attack(nfc_worker, found_key, &tx_rx, i + 1); - break; - } - nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); - } - furry_hal_nfc_sleep(); - deactivated = true; - } else { - // If the key A is marked as found and matches the searching key, invalidate it - MfClassicSectorTrailer* sec_trailer = - mf_classic_get_sector_trailer_by_sector(data, i); - - uint8_t current_key[6]; - nfc_util_num2bytes(key, 6, current_key); - - if(mf_classic_is_key_found(data, i, MfClassicKeyA) && - memcmp(sec_trailer->key_a, current_key, 6) == 0) { - if(!mf_classic_authenticate_skip_activate( - &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) { - mf_classic_set_key_not_found(data, i, MfClassicKeyA); - FURI_LOG_D(TAG, "Key %dA not found in attack", i); - } - } - furry_hal_nfc_sleep(); - deactivated = true; - } - if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { - if(mf_classic_authenticate_skip_activate( - &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547 - FURI_LOG_D(TAG, "Key B found: %012llX", key); - mf_classic_set_key_found(data, i, MfClassicKeyB, key); - nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); - nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); - } - deactivated = true; //-V1048 - } else { - // If the key B is marked as found and matches the searching key, invalidate it - MfClassicSectorTrailer* sec_trailer = - mf_classic_get_sector_trailer_by_sector(data, i); - - uint8_t current_key[6]; - nfc_util_num2bytes(key, 6, current_key); - - if(mf_classic_is_key_found(data, i, MfClassicKeyB) && - memcmp(sec_trailer->key_b, current_key, 6) == 0) { - if(!mf_classic_authenticate_skip_activate( - &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547 - mf_classic_set_key_not_found(data, i, MfClassicKeyB); - FURI_LOG_D(TAG, "Key %dB not found in attack", i); - } - furry_hal_nfc_sleep(); - deactivated = true; //-V1048 - } - } - if(mf_classic_is_key_found(data, i, MfClassicKeyA) && - mf_classic_is_key_found(data, i, MfClassicKeyB)) - break; - if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; - } else { - if(!card_removed_notified) { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - card_removed_notified = true; - card_found_notified = false; - } - if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; - } - prev_key = key; - } - if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; - mf_classic_read_sector(&tx_rx, data, i); - mf_classic_dict_rewind(dict); - } - if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } else { - nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context); - } -} - -void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) { - FurryHalNfcTxRxContext tx_rx = {}; - FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - MfClassicEmulator emulator = { - .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), - .data = nfc_worker->dev_data->mf_classic_data, - .data_changed = false, - }; - NfcaSignal* nfca_signal = nfca_signal_alloc(); - tx_rx.nfca_signal = nfca_signal; - - rfal_platform_spi_acquire(); - - furry_hal_nfc_listen_start(nfc_data); - while(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { //-V1044 - if(furry_hal_nfc_listen_rx(&tx_rx, 300)) { - if(!mf_classic_emulator(&emulator, &tx_rx, false)) { - furry_hal_nfc_listen_start(nfc_data); - } - } - } - if(emulator.data_changed) { - nfc_worker->dev_data->mf_classic_data = emulator.data; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - emulator.data_changed = false; - } - - nfca_signal_free(nfca_signal); - - rfal_platform_spi_release(); -} - -void nfc_worker_write_mf_classic(NfcWorker* nfc_worker) { - FurryHalNfcTxRxContext tx_rx = {}; - bool card_found_notified = false; - FurryHalNfcDevData nfc_data = {}; - MfClassicData* src_data = &nfc_worker->dev_data->mf_classic_data; - MfClassicData dest_data = *src_data; - - while(nfc_worker->state == NfcWorkerStateMfClassicWrite) { - if(furry_hal_nfc_detect(&nfc_data, 200)) { - if(!card_found_notified) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - card_found_notified = true; - } - furry_hal_nfc_sleep(); - - FURI_LOG_I(TAG, "Check low level nfc data"); - if(memcmp(&nfc_data, &nfc_worker->dev_data->nfc_data, sizeof(FurryHalNfcDevData)) != - 0) { - FURI_LOG_E(TAG, "Wrong card"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - FURI_LOG_I(TAG, "Check mf classic type"); - MfClassicType type = - mf_classic_get_classic_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak); - if(type != nfc_worker->dev_data->mf_classic_data.type) { - FURI_LOG_E(TAG, "Wrong mf classic type"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - // Set blocks not read - mf_classic_set_sector_data_not_read(&dest_data); - FURI_LOG_I(TAG, "Updating card sectors"); - uint8_t total_sectors = mf_classic_get_total_sectors_num(type); - bool write_success = true; - for(uint8_t i = 0; i < total_sectors; i++) { - FURI_LOG_I(TAG, "Reading sector %d", i); - mf_classic_read_sector(&tx_rx, &dest_data, i); - bool old_data_read = mf_classic_is_sector_data_read(src_data, i); - bool new_data_read = mf_classic_is_sector_data_read(&dest_data, i); - if(old_data_read != new_data_read) { - FURI_LOG_E(TAG, "Failed to update sector %d", i); - write_success = false; - break; - } - if(nfc_worker->state != NfcWorkerStateMfClassicWrite) break; - if(!mf_classic_write_sector(&tx_rx, &dest_data, src_data, i)) { - FURI_LOG_E(TAG, "Failed to write %d sector", i); - write_success = false; - break; - } - } - if(nfc_worker->state != NfcWorkerStateMfClassicWrite) break; - if(write_success) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - break; - } else { - nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context); - break; - } - - } else { - if(card_found_notified) { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - card_found_notified = false; - } - } - furi_delay_ms(300); - } -} - -void nfc_worker_update_mf_classic(NfcWorker* nfc_worker) { - FurryHalNfcTxRxContext tx_rx = {}; - bool card_found_notified = false; - FurryHalNfcDevData nfc_data = {}; - MfClassicData* old_data = &nfc_worker->dev_data->mf_classic_data; - MfClassicData new_data = *old_data; - - while(nfc_worker->state == NfcWorkerStateMfClassicUpdate) { - if(furry_hal_nfc_detect(&nfc_data, 200)) { - if(!card_found_notified) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - card_found_notified = true; - } - furry_hal_nfc_sleep(); - - FURI_LOG_I(TAG, "Check low level nfc data"); - if(memcmp(&nfc_data, &nfc_worker->dev_data->nfc_data, sizeof(FurryHalNfcDevData)) != - 0) { - FURI_LOG_E(TAG, "Low level nfc data mismatch"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - FURI_LOG_I(TAG, "Check MF classic type"); - MfClassicType type = - mf_classic_get_classic_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak); - if(type != nfc_worker->dev_data->mf_classic_data.type) { - FURI_LOG_E(TAG, "MF classic type mismatch"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - // Set blocks not read - mf_classic_set_sector_data_not_read(&new_data); - FURI_LOG_I(TAG, "Updating card sectors"); - uint8_t total_sectors = mf_classic_get_total_sectors_num(type); - bool update_success = true; - for(uint8_t i = 0; i < total_sectors; i++) { - FURI_LOG_I(TAG, "Reading sector %d", i); - mf_classic_read_sector(&tx_rx, &new_data, i); - bool old_data_read = mf_classic_is_sector_data_read(old_data, i); - bool new_data_read = mf_classic_is_sector_data_read(&new_data, i); - if(old_data_read != new_data_read) { - FURI_LOG_E(TAG, "Failed to update sector %d", i); - update_success = false; - break; - } - if(nfc_worker->state != NfcWorkerStateMfClassicUpdate) break; - } - if(nfc_worker->state != NfcWorkerStateMfClassicUpdate) break; - - // Check updated data - if(update_success) { - *old_data = new_data; - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - break; - } - } else { - if(card_found_notified) { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - card_found_notified = false; - } - } - furi_delay_ms(300); - } -} - void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) { furi_assert(nfc_worker); furi_assert(nfc_worker->callback); @@ -827,11 +334,6 @@ void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) { MfUltralightReader reader = {}; mf_ul_reset(data); - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, &tx_rx, true); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - uint32_t key = 0; uint16_t pack = 0; while(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) { @@ -885,87 +387,4 @@ void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) { furi_delay_ms(10); } } - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } -} - -static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* context) { - furi_assert(context); - NfcWorker* nfc_worker = context; - - if((nfc_worker->state == NfcWorkerStateAnalyzeReader) && - (event == ReaderAnalyzerEventMfkeyCollected)) { - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context); - } - } -} - -void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { - furi_assert(nfc_worker); - furi_assert(nfc_worker->callback); - - FurryHalNfcTxRxContext tx_rx = {}; - - ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer; - FurryHalNfcDevData* nfc_data = NULL; - if(nfc_worker->dev_data->protocol == NfcDeviceProtocolMifareClassic) { - nfc_data = &nfc_worker->dev_data->nfc_data; - reader_analyzer_set_nfc_data(reader_analyzer, nfc_data); - } else { - nfc_data = reader_analyzer_get_nfc_data(reader_analyzer); - } - MfClassicEmulator emulator = { - .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), - .data = nfc_worker->dev_data->mf_classic_data, - .data_changed = false, - }; - NfcaSignal* nfca_signal = nfca_signal_alloc(); - tx_rx.nfca_signal = nfca_signal; - reader_analyzer_prepare_tx_rx(reader_analyzer, &tx_rx, true); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeMfkey); - reader_analyzer_set_callback(reader_analyzer, nfc_worker_reader_analyzer_callback, nfc_worker); - - rfal_platform_spi_acquire(); - - FURI_LOG_D(TAG, "Start reader analyzer"); - - uint8_t reader_no_data_received_cnt = 0; - bool reader_no_data_notified = true; - - while(nfc_worker->state == NfcWorkerStateAnalyzeReader) { - furry_hal_nfc_listen_start(nfc_data); - if(furry_hal_nfc_listen_rx(&tx_rx, 300)) { - if(reader_no_data_notified) { - nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context); - } - reader_no_data_received_cnt = 0; - reader_no_data_notified = false; - NfcProtocol protocol = - reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8); - if(protocol == NfcDeviceProtocolMifareClassic) { - if(!mf_classic_emulator(&emulator, &tx_rx, true)) { - furry_hal_nfc_listen_start(nfc_data); - } - } - } else { - reader_no_data_received_cnt++; - if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) { - nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context); - reader_no_data_received_cnt = 0; - reader_no_data_notified = true; - } - FURI_LOG_D(TAG, "No data from reader"); - continue; - } - furi_delay_ms(1); - } - - rfal_platform_spi_release(); - - reader_analyzer_stop(nfc_worker->reader_analyzer); - - nfca_signal_free(nfca_signal); } diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker_i.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker_i.h index d0fd50d9cd7..0b74c10703b 100644 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker_i.h +++ b/non_catalog_apps/esubghz_chat/lib/nfclegacy/nfc_worker_i.h @@ -8,9 +8,7 @@ #include "protocols/nfc_util.h" #include "protocols/mifare_common.h" #include "protocols/mifare_ultralight.h" -#include "protocols/mifare_classic.h" #include "protocols/nfca.h" -#include "helpers/reader_analyzer.h" struct NfcWorker { FuriThread* thread; @@ -23,8 +21,6 @@ struct NfcWorker { void* context; NfcWorkerState state; - - ReaderAnalyzer* reader_analyzer; }; void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state); diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.c deleted file mode 100644 index 2eb354f5a16..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.c +++ /dev/null @@ -1,1627 +0,0 @@ -#include "mifare_classic.h" -#include "nfca.h" -#include "nfc_util.h" -#include - -// Algorithm from https://github.com/RfidResearchGroup/proxmark3.git - -#define TAG "MfClassic" - -#define MF_CLASSIC_ACK_CMD 0xAU -#define MF_CLASSIC_NACK_BUF_VALID_CMD 0x0U -#define MF_CLASSIC_NACK_BUF_INVALID_CMD 0x4U -#define MF_CLASSIC_AUTH_KEY_A_CMD 0x60U -#define MF_CLASSIC_AUTH_KEY_B_CMD 0x61U -#define MF_CLASSIC_READ_BLOCK_CMD 0x30U -#define MF_CLASSIC_WRITE_BLOCK_CMD 0xA0U -#define MF_CLASSIC_TRANSFER_CMD 0xB0U -#define MF_CLASSIC_DECREMENT_CMD 0xC0U -#define MF_CLASSIC_INCREMENT_CMD 0xC1U -#define MF_CLASSIC_RESTORE_CMD 0xC2U - -const char* mf_classic_get_type_str(MfClassicType type) { - if(type == MfClassicTypeMini) { - return "MIFARE Mini 0.3K"; - } else if(type == MfClassicType1k) { - return "MIFARE Classic 1K"; - } else if(type == MfClassicType4k) { - return "MIFARE Classic 4K"; - } else { - return "Unknown"; - } -} - -static uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector) { - furi_assert(sector < 40); - if(sector < 32) { - return sector * 4; - } else { - return 32 * 4 + (sector - 32) * 16; - } -} - -uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector) { - furi_assert(sector < 40); - if(sector < 32) { - return sector * 4 + 3; - } else { - return 32 * 4 + (sector - 32) * 16 + 15; - } -} - -uint8_t mf_classic_get_sector_by_block(uint8_t block) { - if(block < 128) { - return (block | 0x03) / 4; - } else { - return 32 + ((block | 0xf) - 32 * 4) / 16; - } -} - -static uint8_t mf_classic_get_blocks_num_in_sector(uint8_t sector) { - furi_assert(sector < 40); - return sector < 32 ? 4 : 16; -} - -uint8_t mf_classic_get_sector_trailer_num_by_block(uint8_t block) { - if(block < 128) { - return block | 0x03; - } else { - return block | 0x0f; - } -} - -bool mf_classic_is_sector_trailer(uint8_t block) { - return block == mf_classic_get_sector_trailer_num_by_block(block); -} - -MfClassicSectorTrailer* - mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector) { - furi_assert(data); - uint8_t sec_tr_block_num = mf_classic_get_sector_trailer_block_num_by_sector(sector); - return (MfClassicSectorTrailer*)data->block[sec_tr_block_num].value; -} - -uint8_t mf_classic_get_total_sectors_num(MfClassicType type) { - if(type == MfClassicTypeMini) { - return MF_MINI_TOTAL_SECTORS_NUM; - } else if(type == MfClassicType1k) { - return MF_CLASSIC_1K_TOTAL_SECTORS_NUM; - } else if(type == MfClassicType4k) { - return MF_CLASSIC_4K_TOTAL_SECTORS_NUM; - } else { - return 0; - } -} - -uint16_t mf_classic_get_total_block_num(MfClassicType type) { - if(type == MfClassicTypeMini) { - return 20; - } else if(type == MfClassicType1k) { - return 64; - } else if(type == MfClassicType4k) { - return 256; - } else { - return 0; - } -} - -bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num) { - furi_assert(data); - - return (FURI_BIT(data->block_read_mask[block_num / 32], block_num % 32) == 1); -} - -void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data) { - furi_assert(data); - - if(mf_classic_is_sector_trailer(block_num)) { - memcpy(&data->block[block_num].value[6], &block_data->value[6], 4); - } else { - memcpy(data->block[block_num].value, block_data->value, MF_CLASSIC_BLOCK_SIZE); - } - FURI_BIT_SET(data->block_read_mask[block_num / 32], block_num % 32); -} - -bool mf_classic_is_sector_data_read(MfClassicData* data, uint8_t sector_num) { - furi_assert(data); - - uint8_t first_block = mf_classic_get_first_block_num_of_sector(sector_num); - uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num); - bool data_read = true; - for(size_t i = first_block; i < first_block + total_blocks; i++) { - data_read &= mf_classic_is_block_read(data, i); - } - - return data_read; -} - -void mf_classic_set_sector_data_not_read(MfClassicData* data) { - furi_assert(data); - memset(data->block_read_mask, 0, sizeof(data->block_read_mask)); -} - -bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) { - furi_assert(data); - - bool key_found = false; - if(key_type == MfClassicKeyA) { - key_found = (FURI_BIT(data->key_a_mask, sector_num) == 1); - } else if(key_type == MfClassicKeyB) { - key_found = (FURI_BIT(data->key_b_mask, sector_num) == 1); - } - - return key_found; -} - -void mf_classic_set_key_found( - MfClassicData* data, - uint8_t sector_num, - MfClassicKey key_type, - uint64_t key) { - furi_assert(data); - - uint8_t key_arr[6] = {}; - MfClassicSectorTrailer* sec_trailer = - mf_classic_get_sector_trailer_by_sector(data, sector_num); - nfc_util_num2bytes(key, 6, key_arr); - if(key_type == MfClassicKeyA) { - memcpy(sec_trailer->key_a, key_arr, sizeof(sec_trailer->key_a)); - FURI_BIT_SET(data->key_a_mask, sector_num); - } else if(key_type == MfClassicKeyB) { - memcpy(sec_trailer->key_b, key_arr, sizeof(sec_trailer->key_b)); - FURI_BIT_SET(data->key_b_mask, sector_num); - } -} - -void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) { - furi_assert(data); - - if(key_type == MfClassicKeyA) { - FURI_BIT_CLEAR(data->key_a_mask, sector_num); - } else if(key_type == MfClassicKeyB) { - FURI_BIT_CLEAR(data->key_b_mask, sector_num); - } -} - -bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num) { - furi_assert(data); - - bool sector_read = false; - do { - if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) break; - if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) break; - uint8_t start_block = mf_classic_get_first_block_num_of_sector(sector_num); - uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num); - uint8_t block_read = true; - for(size_t i = start_block; i < start_block + total_blocks; i++) { - block_read = mf_classic_is_block_read(data, i); - if(!block_read) break; - } - sector_read = block_read; - } while(false); - - return sector_read; -} - -void mf_classic_get_read_sectors_and_keys( - MfClassicData* data, - uint8_t* sectors_read, - uint8_t* keys_found) { - furi_assert(data); - furi_assert(sectors_read); - furi_assert(keys_found); - - *sectors_read = 0; - *keys_found = 0; - uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type); - for(size_t i = 0; i < sectors_total; i++) { - if(mf_classic_is_key_found(data, i, MfClassicKeyA)) { - *keys_found += 1; - } - if(mf_classic_is_key_found(data, i, MfClassicKeyB)) { - *keys_found += 1; - } - uint8_t first_block = mf_classic_get_first_block_num_of_sector(i); - uint8_t total_blocks_in_sec = mf_classic_get_blocks_num_in_sector(i); - bool blocks_read = true; - for(size_t j = first_block; j < first_block + total_blocks_in_sec; j++) { - blocks_read = mf_classic_is_block_read(data, j); - if(!blocks_read) break; - } - if(blocks_read) { - *sectors_read += 1; - } - } -} - -bool mf_classic_is_card_read(MfClassicData* data) { - furi_assert(data); - - uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type); - uint8_t sectors_read = 0; - uint8_t keys_found = 0; - mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); - bool card_read = (sectors_read == sectors_total) && (keys_found == sectors_total * 2); - - return card_read; -} - -bool mf_classic_is_allowed_access_sector_trailer( - MfClassicData* data, - uint8_t block_num, - MfClassicKey key, - MfClassicAction action) { - uint8_t* sector_trailer = data->block[block_num].value; - uint8_t AC = ((sector_trailer[7] >> 5) & 0x04) | ((sector_trailer[8] >> 2) & 0x02) | - ((sector_trailer[8] >> 7) & 0x01); - switch(action) { - case MfClassicActionKeyARead: { - return false; - } - case MfClassicActionKeyAWrite: - case MfClassicActionKeyBWrite: { - return ( - (key == MfClassicKeyA && (AC == 0x00 || AC == 0x01)) || - (key == MfClassicKeyB && (AC == 0x04 || AC == 0x03))); - } - case MfClassicActionKeyBRead: { - return (key == MfClassicKeyA && (AC == 0x00 || AC == 0x02 || AC == 0x01)); - } - case MfClassicActionACRead: { - return ( - (key == MfClassicKeyA) || - (key == MfClassicKeyB && !(AC == 0x00 || AC == 0x02 || AC == 0x01))); - } - case MfClassicActionACWrite: { - return ( - (key == MfClassicKeyA && (AC == 0x01)) || - (key == MfClassicKeyB && (AC == 0x03 || AC == 0x05))); - } - default: - return false; - } - return true; -} - -bool mf_classic_is_allowed_access_data_block( - MfClassicData* data, - uint8_t block_num, - MfClassicKey key, - MfClassicAction action) { - uint8_t* sector_trailer = - data->block[mf_classic_get_sector_trailer_num_by_block(block_num)].value; - - if(block_num == 0 && action == MfClassicActionDataWrite) { - return false; - } - - uint8_t sector_block; - if(block_num <= 128) { - sector_block = block_num & 0x03; - } else { - sector_block = (block_num & 0x0f) / 5; - } - - uint8_t AC; - switch(sector_block) { - case 0x00: { - AC = ((sector_trailer[7] >> 2) & 0x04) | ((sector_trailer[8] << 1) & 0x02) | - ((sector_trailer[8] >> 4) & 0x01); - break; - } - case 0x01: { - AC = ((sector_trailer[7] >> 3) & 0x04) | ((sector_trailer[8] >> 0) & 0x02) | - ((sector_trailer[8] >> 5) & 0x01); - break; - } - case 0x02: { - AC = ((sector_trailer[7] >> 4) & 0x04) | ((sector_trailer[8] >> 1) & 0x02) | - ((sector_trailer[8] >> 6) & 0x01); - break; - } - default: - return false; - } - - switch(action) { - case MfClassicActionDataRead: { - return ( - (key == MfClassicKeyA && !(AC == 0x03 || AC == 0x05 || AC == 0x07)) || - (key == MfClassicKeyB && !(AC == 0x07))); - } - case MfClassicActionDataWrite: { - return ( - (key == MfClassicKeyA && (AC == 0x00)) || - (key == MfClassicKeyB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03))); - } - case MfClassicActionDataInc: { - return ( - (key == MfClassicKeyA && (AC == 0x00)) || - (key == MfClassicKeyB && (AC == 0x00 || AC == 0x06))); - } - case MfClassicActionDataDec: { - return ( - (key == MfClassicKeyA && (AC == 0x00 || AC == 0x06 || AC == 0x01)) || - (key == MfClassicKeyB && (AC == 0x00 || AC == 0x06 || AC == 0x01))); - } - default: - return false; - } - - return false; -} - -static bool mf_classic_is_allowed_access( - MfClassicEmulator* emulator, - uint8_t block_num, - MfClassicKey key, - MfClassicAction action) { - if(mf_classic_is_sector_trailer(block_num)) { - return mf_classic_is_allowed_access_sector_trailer( - &emulator->data, block_num, key, action); - } else { - return mf_classic_is_allowed_access_data_block(&emulator->data, block_num, key, action); - } -} - -bool mf_classic_is_value_block(MfClassicData* data, uint8_t block_num) { - // Check if key A can write, if it can, it's transport configuration, not data block - return !mf_classic_is_allowed_access_data_block( - data, block_num, MfClassicKeyA, MfClassicActionDataWrite) && - (mf_classic_is_allowed_access_data_block( - data, block_num, MfClassicKeyB, MfClassicActionDataInc) || - mf_classic_is_allowed_access_data_block( - data, block_num, MfClassicKeyB, MfClassicActionDataDec)); -} - -bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { - UNUSED(ATQA1); - if((ATQA0 == 0x44 || ATQA0 == 0x04) && - (SAK == 0x08 || SAK == 0x88 || SAK == 0x09 || SAK == 0x89)) { - return true; - } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) { - //skylanders support - return true; - } else if( - ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) || - ((ATQA0 == 0x02 || ATQA0 == 0x04 || ATQA0 == 0x08) && (SAK == 0x38))) { - return true; - } else { - return false; - } -} - -MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { - UNUSED(ATQA1); - if((ATQA0 == 0x44 || ATQA0 == 0x04)) { - if((SAK == 0x08 || SAK == 0x88)) { - return MfClassicType1k; - } else if((SAK == 0x38)) { - return MfClassicType4k; - } else if((SAK == 0x09 || SAK == 0x89)) { - return MfClassicTypeMini; - } - } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) { - //skylanders support - return MfClassicType1k; - } else if( - ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) || - ((ATQA0 == 0x02 || ATQA0 == 0x08) && (SAK == 0x38))) { - return MfClassicType4k; - } - return MfClassicType1k; -} - -void mf_classic_reader_add_sector( - MfClassicReader* reader, - uint8_t sector, - uint64_t key_a, - uint64_t key_b) { - furi_assert(reader); - furi_assert(sector < MF_CLASSIC_SECTORS_MAX); - furi_assert((key_a != MF_CLASSIC_NO_KEY) || (key_b != MF_CLASSIC_NO_KEY)); - - if(reader->sectors_to_read < MF_CLASSIC_SECTORS_MAX) { - reader->sector_reader[reader->sectors_to_read].key_a = key_a; - reader->sector_reader[reader->sectors_to_read].key_b = key_b; - reader->sector_reader[reader->sectors_to_read].sector_num = sector; - reader->sectors_to_read++; - } -} - -bool mf_classic_block_to_value(const uint8_t* block, int32_t* value, uint8_t* addr) { - uint32_t v = *(uint32_t*)&block[0]; - uint32_t v_inv = *(uint32_t*)&block[4]; - uint32_t v1 = *(uint32_t*)&block[8]; - - bool val_checks = - ((v == v1) && (v == ~v_inv) && (block[12] == (~block[13] & 0xFF)) && - (block[14] == (~block[15] & 0xFF)) && (block[12] == block[14])); - if(value) { - *value = (int32_t)v; - } - if(addr) { - *addr = block[12]; - } - return val_checks; -} - -void mf_classic_value_to_block(int32_t value, uint8_t addr, uint8_t* block) { - uint32_t v_inv = ~((uint32_t)value); - - memcpy(block, &value, 4); //-V1086 - memcpy(block + 4, &v_inv, 4); //-V1086 - memcpy(block + 8, &value, 4); //-V1086 - - block[12] = addr; - block[13] = ~addr & 0xFF; - block[14] = addr; - block[15] = ~addr & 0xFF; -} - -void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector) { - furi_assert(auth_ctx); - auth_ctx->sector = sector; - auth_ctx->key_a = MF_CLASSIC_NO_KEY; - auth_ctx->key_b = MF_CLASSIC_NO_KEY; -} - -static bool mf_classic_auth( - FurryHalNfcTxRxContext* tx_rx, - uint32_t block, - uint64_t key, - MfClassicKey key_type, - Crypto1* crypto, - bool skip_activate, - uint32_t cuid) { - bool auth_success = false; - memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data)); - memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity)); - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - - do { - if(!skip_activate && !furry_hal_nfc_activate_nfca(200, &cuid)) break; - if(key_type == MfClassicKeyA) { - tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_A_CMD; - } else { - tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_B_CMD; - } - tx_rx->tx_data[1] = block; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRxNoCrc; - tx_rx->tx_bits = 2 * 8; - if(!furry_hal_nfc_tx_rx(tx_rx, 6)) break; - - uint32_t nt = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4); - crypto1_init(crypto, key); - crypto1_word(crypto, nt ^ cuid, 0); - uint8_t nr[4] = {}; - nfc_util_num2bytes(prng_successor(DWT->CYCCNT, 32), 4, nr); - for(uint8_t i = 0; i < 4; i++) { - tx_rx->tx_data[i] = crypto1_byte(crypto, nr[i], 0) ^ nr[i]; - tx_rx->tx_parity[0] |= - (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nr[i])) & 0x01) << (7 - i)); - } - nt = prng_successor(nt, 32); - for(uint8_t i = 4; i < 8; i++) { - nt = prng_successor(nt, 8); - tx_rx->tx_data[i] = crypto1_byte(crypto, 0x00, 0) ^ (nt & 0xff); - tx_rx->tx_parity[0] |= - (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nt & 0xff)) & 0x01) - << (7 - i)); - } - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - tx_rx->tx_bits = 8 * 8; - if(!furry_hal_nfc_tx_rx(tx_rx, 6)) break; - if(tx_rx->rx_bits == 32) { - crypto1_word(crypto, 0, 0); - auth_success = true; - } - } while(false); - - return auth_success; -} - -bool mf_classic_authenticate( - FurryHalNfcTxRxContext* tx_rx, - uint8_t block_num, - uint64_t key, - MfClassicKey key_type) { - furi_assert(tx_rx); - - Crypto1 crypto = {}; - bool key_found = mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0); - furry_hal_nfc_sleep(); - return key_found; -} - -bool mf_classic_authenticate_skip_activate( - FurryHalNfcTxRxContext* tx_rx, - uint8_t block_num, - uint64_t key, - MfClassicKey key_type, - bool skip_activate, - uint32_t cuid) { - furi_assert(tx_rx); - - Crypto1 crypto = {}; - bool key_found = - mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, skip_activate, cuid); - furry_hal_nfc_sleep(); - return key_found; -} - -bool mf_classic_auth_attempt( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - MfClassicAuthContext* auth_ctx, - uint64_t key) { - furi_assert(tx_rx); - furi_assert(auth_ctx); - bool found_key = false; - bool need_halt = (auth_ctx->key_a == MF_CLASSIC_NO_KEY) && - (auth_ctx->key_b == MF_CLASSIC_NO_KEY); - - if(auth_ctx->key_a == MF_CLASSIC_NO_KEY) { - // Try AUTH with key A - if(mf_classic_auth( - tx_rx, - mf_classic_get_sector_trailer_block_num_by_sector(auth_ctx->sector), - key, - MfClassicKeyA, - crypto, - false, - 0)) { - auth_ctx->key_a = key; - found_key = true; - } - } - - if(need_halt) { - furry_hal_nfc_sleep(); - } - - if(auth_ctx->key_b == MF_CLASSIC_NO_KEY) { - // Try AUTH with key B - if(mf_classic_auth( - tx_rx, - mf_classic_get_sector_trailer_block_num_by_sector(auth_ctx->sector), - key, - MfClassicKeyB, - crypto, - false, - 0)) { - auth_ctx->key_b = key; - found_key = true; - } - } - - return found_key; -} - -bool mf_classic_read_block( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - uint8_t block_num, - MfClassicBlock* block) { - furi_assert(tx_rx); - furi_assert(crypto); - furi_assert(block); - - bool read_block_success = false; - uint8_t plain_cmd[4] = {MF_CLASSIC_READ_BLOCK_CMD, block_num, 0x00, 0x00}; - nfca_append_crc16(plain_cmd, 2); - - crypto1_encrypt( - crypto, NULL, plain_cmd, sizeof(plain_cmd) * 8, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_bits = sizeof(plain_cmd) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - if(tx_rx->rx_bits == 8 * (MF_CLASSIC_BLOCK_SIZE + 2)) { - uint8_t block_received[MF_CLASSIC_BLOCK_SIZE + 2]; - crypto1_decrypt(crypto, tx_rx->rx_data, tx_rx->rx_bits, block_received); - uint16_t crc_calc = nfca_get_crc16(block_received, MF_CLASSIC_BLOCK_SIZE); - uint16_t crc_received = (block_received[MF_CLASSIC_BLOCK_SIZE + 1] << 8) | - block_received[MF_CLASSIC_BLOCK_SIZE]; - if(crc_received != crc_calc) { - FURI_LOG_E( - TAG, - "Incorrect CRC while reading block %d. Expected %04X, Received %04X", - block_num, - crc_received, - crc_calc); - } else { - memcpy(block->value, block_received, MF_CLASSIC_BLOCK_SIZE); - read_block_success = true; - } - } - } - return read_block_success; -} - -void mf_classic_read_sector(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num) { - furi_assert(tx_rx); - furi_assert(data); - - furry_hal_nfc_sleep(); - bool key_a_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyA); - bool key_b_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyB); - uint8_t start_block = mf_classic_get_first_block_num_of_sector(sec_num); - uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num); - MfClassicBlock block_tmp = {}; - uint64_t key = 0; - MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sec_num); - Crypto1 crypto = {}; - - uint8_t blocks_read = 0; - do { - if(!key_a_found) break; - FURI_LOG_D(TAG, "Try to read blocks with key A"); - key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a)); - if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) { - mf_classic_set_key_not_found(data, sec_num, MfClassicKeyA); - FURI_LOG_D(TAG, "Key %dA not found in read", sec_num); - break; - } - - for(size_t i = start_block; i < start_block + total_blocks; i++) { - if(!mf_classic_is_block_read(data, i)) { - if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { - mf_classic_set_block_read(data, i, &block_tmp); - blocks_read++; - } else if(i > start_block) { - // Try to re-auth to read block in case prevous block was protected from read - furry_hal_nfc_sleep(); - if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) { - mf_classic_set_key_not_found(data, sec_num, MfClassicKeyA); - FURI_LOG_D(TAG, "Key %dA not found in read", sec_num); - break; - } - if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { - mf_classic_set_block_read(data, i, &block_tmp); - blocks_read++; - } - } - } else { - blocks_read++; - } - } - FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks); - } while(false); - do { - if(blocks_read == total_blocks) break; - if(!key_b_found) break; - if(key_a_found) { - furry_hal_nfc_sleep(); - } - FURI_LOG_D(TAG, "Try to read blocks with key B"); - key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b)); - if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) { - mf_classic_set_key_not_found(data, sec_num, MfClassicKeyB); - FURI_LOG_D(TAG, "Key %dB not found in read", sec_num); - break; - } - - for(size_t i = start_block; i < start_block + total_blocks; i++) { - if(!mf_classic_is_block_read(data, i)) { - if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { - mf_classic_set_block_read(data, i, &block_tmp); - blocks_read++; - } else if(i > start_block) { - // Try to re-auth to read block in case prevous block was protected from read - furry_hal_nfc_sleep(); - if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) { - mf_classic_set_key_not_found(data, sec_num, MfClassicKeyB); - FURI_LOG_D(TAG, "Key %dB not found in read", sec_num); - break; - } - if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) { - mf_classic_set_block_read(data, i, &block_tmp); - blocks_read++; - } - } - } else { - blocks_read++; - } - } - FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks); - } while(false); -} - -static bool mf_classic_read_sector_with_reader( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - MfClassicSectorReader* sector_reader, - MfClassicSector* sector) { - furi_assert(tx_rx); - furi_assert(sector_reader); - furi_assert(sector); - - uint64_t key; - MfClassicKey key_type; - uint8_t first_block; - bool sector_read = false; - - furry_hal_nfc_sleep(); - do { - // Activate card - first_block = mf_classic_get_first_block_num_of_sector(sector_reader->sector_num); - if(sector_reader->key_a != MF_CLASSIC_NO_KEY) { - key = sector_reader->key_a; - key_type = MfClassicKeyA; - } else if(sector_reader->key_b != MF_CLASSIC_NO_KEY) { - key = sector_reader->key_b; - key_type = MfClassicKeyB; - } else { - break; - } - - // Auth to first block in sector - if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto, false, 0)) { - // Set key to MF_CLASSIC_NO_KEY to prevent further attempts - if(key_type == MfClassicKeyA) { - sector_reader->key_a = MF_CLASSIC_NO_KEY; - } else { - sector_reader->key_b = MF_CLASSIC_NO_KEY; - } - break; - } - sector->total_blocks = mf_classic_get_blocks_num_in_sector(sector_reader->sector_num); - - // Read blocks - for(uint8_t i = 0; i < sector->total_blocks; i++) { - if(mf_classic_read_block(tx_rx, crypto, first_block + i, §or->block[i])) continue; - if(i == 0) continue; - // Try to auth to read next block in case previous is locked - furry_hal_nfc_sleep(); - if(!mf_classic_auth(tx_rx, first_block + i, key, key_type, crypto, false, 0)) continue; - mf_classic_read_block(tx_rx, crypto, first_block + i, §or->block[i]); - } - // Save sector keys in last block - if(sector_reader->key_a != MF_CLASSIC_NO_KEY) { - nfc_util_num2bytes( - sector_reader->key_a, 6, §or->block[sector->total_blocks - 1].value[0]); - } - if(sector_reader->key_b != MF_CLASSIC_NO_KEY) { - nfc_util_num2bytes( - sector_reader->key_b, 6, §or->block[sector->total_blocks - 1].value[10]); - } - - sector_read = true; - } while(false); - - return sector_read; -} - -uint8_t mf_classic_read_card( - FurryHalNfcTxRxContext* tx_rx, - MfClassicReader* reader, - MfClassicData* data) { - furi_assert(tx_rx); - furi_assert(reader); - furi_assert(data); - - uint8_t sectors_read = 0; - data->type = reader->type; - data->key_a_mask = 0; - data->key_b_mask = 0; - MfClassicSector temp_sector = {}; - for(uint8_t i = 0; i < reader->sectors_to_read; i++) { - if(mf_classic_read_sector_with_reader( - tx_rx, &reader->crypto, &reader->sector_reader[i], &temp_sector)) { - uint8_t first_block = - mf_classic_get_first_block_num_of_sector(reader->sector_reader[i].sector_num); - for(uint8_t j = 0; j < temp_sector.total_blocks; j++) { - mf_classic_set_block_read(data, first_block + j, &temp_sector.block[j]); - } - if(reader->sector_reader[i].key_a != MF_CLASSIC_NO_KEY) { - mf_classic_set_key_found( - data, - reader->sector_reader[i].sector_num, - MfClassicKeyA, - reader->sector_reader[i].key_a); - } - if(reader->sector_reader[i].key_b != MF_CLASSIC_NO_KEY) { - mf_classic_set_key_found( - data, - reader->sector_reader[i].sector_num, - MfClassicKeyB, - reader->sector_reader[i].key_b); - } - sectors_read++; - } - } - - return sectors_read; -} - -uint8_t mf_classic_update_card(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data) { - furi_assert(tx_rx); - furi_assert(data); - - uint8_t total_sectors = mf_classic_get_total_sectors_num(data->type); - - for(size_t i = 0; i < total_sectors; i++) { - mf_classic_read_sector(tx_rx, data, i); - } - uint8_t sectors_read = 0; - uint8_t keys_found = 0; - mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); - FURI_LOG_D(TAG, "Read %d sectors and %d keys", sectors_read, keys_found); - - return sectors_read; -} - -bool mf_classic_emulator( - MfClassicEmulator* emulator, - FurryHalNfcTxRxContext* tx_rx, - bool is_reader_analyzer) { - furi_assert(emulator); - furi_assert(tx_rx); - uint8_t plain_data[MF_CLASSIC_MAX_DATA_SIZE]; - MfClassicKey access_key = MfClassicKeyA; - bool need_reset = false; - bool need_nack = false; - bool is_encrypted = false; - uint8_t sector = 0; - - // Used for decrement and increment - copy to block on transfer - uint8_t transfer_buf[MF_CLASSIC_BLOCK_SIZE]; - bool transfer_buf_valid = false; - - // Process commands - while(!need_reset && !need_nack) { //-V654 - memset(plain_data, 0, MF_CLASSIC_MAX_DATA_SIZE); - if(!is_encrypted) { - crypto1_reset(&emulator->crypto); - memcpy(plain_data, tx_rx->rx_data, tx_rx->rx_bits / 8); - } else { - if(!furry_hal_nfc_tx_rx(tx_rx, 300)) { - FURI_LOG_D( - TAG, - "Error in tx rx. Tx: %d bits, Rx: %d bits", - tx_rx->tx_bits, - tx_rx->rx_bits); - need_reset = true; - break; - } - crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data); - } - - // After increment, decrement or restore the only allowed command is transfer - uint8_t cmd = plain_data[0]; - if(transfer_buf_valid && cmd != MF_CLASSIC_TRANSFER_CMD) { - need_nack = true; - break; - } - - if(cmd == NFCA_CMD_HALT && plain_data[1] == 0x00) { - FURI_LOG_T(TAG, "Halt received"); - need_reset = true; - break; - } - - if(cmd == NFCA_CMD_RATS) { - // Mifare Classic doesn't support ATS, NACK it and start listening again - FURI_LOG_T(TAG, "RATS received"); - need_nack = true; - break; - } - - if(cmd == MF_CLASSIC_AUTH_KEY_A_CMD || cmd == MF_CLASSIC_AUTH_KEY_B_CMD) { - uint8_t block = plain_data[1]; - uint64_t key = 0; - uint8_t sector_trailer_block = mf_classic_get_sector_trailer_num_by_block(block); - sector = mf_classic_get_sector_by_block(block); - MfClassicSectorTrailer* sector_trailer = - (MfClassicSectorTrailer*)emulator->data.block[sector_trailer_block].value; - if(cmd == MF_CLASSIC_AUTH_KEY_A_CMD) { - if(mf_classic_is_key_found( - &emulator->data, mf_classic_get_sector_by_block(block), MfClassicKeyA) || - is_reader_analyzer) { - key = nfc_util_bytes2num(sector_trailer->key_a, 6); - access_key = MfClassicKeyA; - } else { - FURI_LOG_D(TAG, "Key not known"); - need_nack = true; - break; - } - } else { - if(mf_classic_is_key_found( - &emulator->data, mf_classic_get_sector_by_block(block), MfClassicKeyB) || - is_reader_analyzer) { - key = nfc_util_bytes2num(sector_trailer->key_b, 6); - access_key = MfClassicKeyB; - } else { - FURI_LOG_D(TAG, "Key not known"); - need_nack = true; - break; - } - } - - uint32_t nonce = prng_successor(DWT->CYCCNT, 32) ^ 0xAA; - uint8_t nt[4]; - uint8_t nt_keystream[4]; - nfc_util_num2bytes(nonce, 4, nt); - nfc_util_num2bytes(nonce ^ emulator->cuid, 4, nt_keystream); - crypto1_init(&emulator->crypto, key); - if(!is_encrypted) { - crypto1_word(&emulator->crypto, emulator->cuid ^ nonce, 0); - memcpy(tx_rx->tx_data, nt, sizeof(nt)); - tx_rx->tx_parity[0] = 0; - nfc_util_odd_parity(tx_rx->tx_data, tx_rx->tx_parity, sizeof(nt)); - tx_rx->tx_bits = sizeof(nt) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - } else { - crypto1_encrypt( - &emulator->crypto, - nt_keystream, - nt, - sizeof(nt) * 8, - tx_rx->tx_data, - tx_rx->tx_parity); - tx_rx->tx_bits = sizeof(nt) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - } - - if(!furry_hal_nfc_tx_rx(tx_rx, 500)) { - FURI_LOG_E(TAG, "Error in NT exchange"); - need_reset = true; - break; - } - - if(tx_rx->rx_bits != 64) { - need_reset = true; - break; - } - - uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4); - uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4); - - crypto1_word(&emulator->crypto, nr, 1); - uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); - if(cardRr != prng_successor(nonce, 64)) { - FURI_LOG_T( - TAG, - "Wrong AUTH on block %u! %08lX != %08lX", - block, - cardRr, - prng_successor(nonce, 64)); - // Don't send NACK, as the tag doesn't send it - need_reset = true; - break; - } - - uint32_t ans = prng_successor(nonce, 96); - uint8_t response[4] = {}; - nfc_util_num2bytes(ans, 4, response); - crypto1_encrypt( - &emulator->crypto, - NULL, - response, - sizeof(response) * 8, - tx_rx->tx_data, - tx_rx->tx_parity); - tx_rx->tx_bits = sizeof(response) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - - is_encrypted = true; - continue; - } - - if(!is_encrypted) { - FURI_LOG_T(TAG, "Invalid command before auth session established: %02X", cmd); - need_nack = true; - break; - } - - // Mifare Classic commands always have block number after command - uint8_t block = plain_data[1]; - if(mf_classic_get_sector_by_block(block) != sector) { - // Don't allow access to sectors other than authorized - FURI_LOG_T( - TAG, - "Trying to access block %u from not authorized sector (command: %02X)", - block, - cmd); - need_nack = true; - break; - } - - switch(cmd) { - case MF_CLASSIC_READ_BLOCK_CMD: { - uint8_t block_data[MF_CLASSIC_BLOCK_SIZE + 2] = {}; - memcpy(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE); - if(mf_classic_is_sector_trailer(block)) { - if(!mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionKeyARead)) { - memset(block_data, 0, 6); //-V1086 - } - if(!mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionKeyBRead)) { - memset(&block_data[10], 0, 6); - } - if(!mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionACRead)) { - memset(&block_data[6], 0, 4); - } - } else if( - !mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionDataRead) || - !mf_classic_is_block_read(&emulator->data, block)) { - need_nack = true; - break; - } - - nfca_append_crc16(block_data, 16); - - crypto1_encrypt( - &emulator->crypto, - NULL, - block_data, - sizeof(block_data) * 8, - tx_rx->tx_data, - tx_rx->tx_parity); - tx_rx->tx_bits = (MF_CLASSIC_BLOCK_SIZE + 2) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - break; - } - - case MF_CLASSIC_WRITE_BLOCK_CMD: { - // Send ACK - uint8_t ack = MF_CLASSIC_ACK_CMD; - crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - tx_rx->tx_bits = 4; - - if(!furry_hal_nfc_tx_rx(tx_rx, 300)) { - need_reset = true; - break; - } - - if(tx_rx->rx_bits != (MF_CLASSIC_BLOCK_SIZE + 2) * 8) { - need_reset = true; - break; - } - - crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data); - uint8_t block_data[MF_CLASSIC_BLOCK_SIZE] = {}; - memcpy(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE); - - if(!mf_classic_is_block_read(&emulator->data, block)) { - // Don't allow writing to the block for which we haven't read data yet - need_nack = true; - break; - } - - if(mf_classic_is_sector_trailer(block)) { - if(mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionKeyAWrite)) { - memcpy(block_data, plain_data, 6); //-V1086 - } - if(mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionKeyBWrite)) { - memcpy(&block_data[10], &plain_data[10], 6); - } - if(mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionACWrite)) { - memcpy(&block_data[6], &plain_data[6], 4); - } - } else { - if(mf_classic_is_allowed_access( - emulator, block, access_key, MfClassicActionDataWrite)) { - memcpy(block_data, plain_data, MF_CLASSIC_BLOCK_SIZE); - } else { - need_nack = true; - break; - } - } - - if(memcmp(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE) != 0) { - memcpy(emulator->data.block[block].value, block_data, MF_CLASSIC_BLOCK_SIZE); - emulator->data_changed = true; - } - - // Send ACK - ack = MF_CLASSIC_ACK_CMD; - crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - tx_rx->tx_bits = 4; - break; - } - - case MF_CLASSIC_DECREMENT_CMD: - case MF_CLASSIC_INCREMENT_CMD: - case MF_CLASSIC_RESTORE_CMD: { - MfClassicAction action = (cmd == MF_CLASSIC_INCREMENT_CMD) ? MfClassicActionDataInc : - MfClassicActionDataDec; - - if(!mf_classic_is_allowed_access(emulator, block, access_key, action)) { - need_nack = true; - break; - } - - int32_t prev_value; - uint8_t addr; - if(!mf_classic_block_to_value(emulator->data.block[block].value, &prev_value, &addr)) { - need_nack = true; - break; - } - - // Send ACK - uint8_t ack = MF_CLASSIC_ACK_CMD; - crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - tx_rx->tx_bits = 4; - - if(!furry_hal_nfc_tx_rx(tx_rx, 300)) { - need_reset = true; - break; - } - - if(tx_rx->rx_bits != (sizeof(int32_t) + 2) * 8) { - need_reset = true; - break; - } - - crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data); - int32_t value = *(int32_t*)&plain_data[0]; - if(value < 0) { - value = -value; - } - if(cmd == MF_CLASSIC_DECREMENT_CMD) { - value = -value; - } else if(cmd == MF_CLASSIC_RESTORE_CMD) { - value = 0; - } - - mf_classic_value_to_block(prev_value + value, addr, transfer_buf); - transfer_buf_valid = true; - // Commands do not ACK - tx_rx->tx_bits = 0; - break; - } - - case MF_CLASSIC_TRANSFER_CMD: { - if(!mf_classic_is_allowed_access(emulator, block, access_key, MfClassicActionDataDec)) { - need_nack = true; - break; - } - if(memcmp(transfer_buf, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE) != - 0) { - memcpy(emulator->data.block[block].value, transfer_buf, MF_CLASSIC_BLOCK_SIZE); - emulator->data_changed = true; - } - transfer_buf_valid = false; - - uint8_t ack = MF_CLASSIC_ACK_CMD; - crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - tx_rx->tx_bits = 4; - break; - } - - default: - FURI_LOG_T(TAG, "Unknown command: %02X", cmd); - need_nack = true; - break; - } - } - - if(need_nack && !need_reset) { - // Send NACK - uint8_t nack = transfer_buf_valid ? MF_CLASSIC_NACK_BUF_VALID_CMD : - MF_CLASSIC_NACK_BUF_INVALID_CMD; - if(is_encrypted) { - crypto1_encrypt(&emulator->crypto, NULL, &nack, 4, tx_rx->tx_data, tx_rx->tx_parity); - } else { - tx_rx->tx_data[0] = nack; - } - tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent; - tx_rx->tx_bits = 4; - furry_hal_nfc_tx_rx(tx_rx, 300); - need_reset = true; - } - - return !need_reset; -} - -void mf_classic_halt(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto) { - furi_assert(tx_rx); - - uint8_t plain_data[4] = {NFCA_CMD_HALT, 0x00, 0x00, 0x00}; - - nfca_append_crc16(plain_data, 2); - if(crypto) { - crypto1_encrypt( - crypto, NULL, plain_data, sizeof(plain_data) * 8, tx_rx->tx_data, tx_rx->tx_parity); - } else { - memcpy(tx_rx->tx_data, plain_data, sizeof(plain_data)); - nfc_util_odd_parity(tx_rx->tx_data, tx_rx->tx_parity, sizeof(plain_data)); - } - - tx_rx->tx_bits = sizeof(plain_data) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - furry_hal_nfc_tx_rx(tx_rx, 50); -} - -bool mf_classic_write_block( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - uint8_t block_num, - MfClassicBlock* src_block) { - furi_assert(tx_rx); - furi_assert(crypto); - furi_assert(src_block); - - bool write_success = false; - uint8_t plain_data[MF_CLASSIC_BLOCK_SIZE + 2] = {}; - uint8_t resp; - - do { - // Send write command - plain_data[0] = MF_CLASSIC_WRITE_BLOCK_CMD; - plain_data[1] = block_num; - nfca_append_crc16(plain_data, 2); - crypto1_encrypt(crypto, NULL, plain_data, 4 * 8, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_bits = 4 * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - if(tx_rx->rx_bits == 4) { - crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp); - if(resp != 0x0A) { - FURI_LOG_D(TAG, "NACK received on write cmd: %02X", resp); - break; - } - } else { - FURI_LOG_D(TAG, "Not ACK received"); - break; - } - } else { - FURI_LOG_D(TAG, "Failed to send write cmd"); - break; - } - - // Send data - memcpy(plain_data, src_block->value, MF_CLASSIC_BLOCK_SIZE); - nfca_append_crc16(plain_data, MF_CLASSIC_BLOCK_SIZE); - crypto1_encrypt( - crypto, - NULL, - plain_data, - (MF_CLASSIC_BLOCK_SIZE + 2) * 8, - tx_rx->tx_data, - tx_rx->tx_parity); - tx_rx->tx_bits = (MF_CLASSIC_BLOCK_SIZE + 2) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - if(tx_rx->rx_bits == 4) { - crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp); - if(resp != MF_CLASSIC_ACK_CMD) { - FURI_LOG_D(TAG, "NACK received on sending data"); - break; - } - } else { - FURI_LOG_D(TAG, "Not ACK received"); - break; - } - } else { - FURI_LOG_D(TAG, "Failed to send data"); - break; - } - - write_success = true; - } while(false); - - return write_success; -} - -bool mf_classic_auth_write_block( - FurryHalNfcTxRxContext* tx_rx, - MfClassicBlock* src_block, - uint8_t block_num, - MfClassicKey key_type, - uint64_t key) { - furi_assert(tx_rx); - furi_assert(src_block); - - Crypto1 crypto = {}; - bool write_success = false; - - do { - furry_hal_nfc_sleep(); - if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0)) { - FURI_LOG_D(TAG, "Auth fail"); - break; - } - - if(!mf_classic_write_block(tx_rx, &crypto, block_num, src_block)) { - FURI_LOG_D(TAG, "Write fail"); - break; - } - write_success = true; - - mf_classic_halt(tx_rx, &crypto); - } while(false); - - return write_success; -} - -bool mf_classic_transfer(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto, uint8_t block_num) { - furi_assert(tx_rx); - furi_assert(crypto); - - // Send transfer command - uint8_t plain_data[4] = {MF_CLASSIC_TRANSFER_CMD, block_num, 0, 0}; - uint8_t resp = 0; - bool transfer_success = false; - - nfca_append_crc16(plain_data, 2); - crypto1_encrypt( - crypto, NULL, plain_data, sizeof(plain_data) * 8, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_bits = sizeof(plain_data) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - - do { - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - if(tx_rx->rx_bits == 4) { - crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp); - if(resp != 0x0A) { - FURI_LOG_D(TAG, "NACK received on transfer cmd: %02X", resp); - break; - } - } else { - FURI_LOG_D(TAG, "Not ACK received"); - break; - } - } else { - FURI_LOG_D(TAG, "Failed to send transfer cmd"); - break; - } - - transfer_success = true; - } while(false); - - return transfer_success; -} - -bool mf_classic_value_cmd( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - uint8_t block_num, - uint8_t cmd, - int32_t d_value) { - furi_assert(tx_rx); - furi_assert(crypto); - furi_assert( - cmd == MF_CLASSIC_INCREMENT_CMD || cmd == MF_CLASSIC_DECREMENT_CMD || - cmd == MF_CLASSIC_RESTORE_CMD); - furi_assert(d_value >= 0); - - uint8_t plain_data[sizeof(d_value) + 2] = {}; - uint8_t resp = 0; - bool success = false; - - do { - // Send cmd - plain_data[0] = cmd; - plain_data[1] = block_num; - nfca_append_crc16(plain_data, 2); - crypto1_encrypt(crypto, NULL, plain_data, 4 * 8, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_bits = 4 * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - if(tx_rx->rx_bits == 4) { - crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp); - if(resp != 0x0A) { - FURI_LOG_D(TAG, "NACK received on write cmd: %02X", resp); - break; - } - } else { - FURI_LOG_D(TAG, "Not ACK received"); - break; - } - } else { - FURI_LOG_D(TAG, "Failed to send write cmd"); - break; - } - - // Send data - memcpy(plain_data, &d_value, sizeof(d_value)); - nfca_append_crc16(plain_data, sizeof(d_value)); - crypto1_encrypt( - crypto, NULL, plain_data, (sizeof(d_value) + 2) * 8, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_bits = (sizeof(d_value) + 2) * 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw; - // inc, dec, restore do not ACK, but they do NACK - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - if(tx_rx->rx_bits == 4) { - crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp); - if(resp != 0x0A) { - FURI_LOG_D(TAG, "NACK received on transfer cmd: %02X", resp); - break; - } - } else { - FURI_LOG_D(TAG, "Not NACK received"); - break; - } - } - - success = true; - - } while(false); - - return success; -} - -bool mf_classic_value_cmd_full( - FurryHalNfcTxRxContext* tx_rx, - MfClassicBlock* src_block, - uint8_t block_num, - MfClassicKey key_type, - uint64_t key, - int32_t d_value) { - furi_assert(tx_rx); - furi_assert(src_block); - - Crypto1 crypto = {}; - uint8_t cmd; - bool success = false; - - if(d_value > 0) { - cmd = MF_CLASSIC_INCREMENT_CMD; - } else if(d_value < 0) { - cmd = MF_CLASSIC_DECREMENT_CMD; - d_value = -d_value; - } else { - cmd = MF_CLASSIC_RESTORE_CMD; - } - - do { - furry_hal_nfc_sleep(); - if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0)) { - FURI_LOG_D(TAG, "Value cmd auth fail"); - break; - } - if(!mf_classic_value_cmd(tx_rx, &crypto, block_num, cmd, d_value)) { - FURI_LOG_D(TAG, "Value cmd inc/dec/res fail"); - break; - } - - if(!mf_classic_transfer(tx_rx, &crypto, block_num)) { - FURI_LOG_D(TAG, "Value cmd transfer fail"); - break; - } - - success = true; - - // Send Halt - mf_classic_halt(tx_rx, &crypto); - } while(false); - - return success; -} - -bool mf_classic_write_sector( - FurryHalNfcTxRxContext* tx_rx, - MfClassicData* dest_data, - MfClassicData* src_data, - uint8_t sec_num) { - furi_assert(tx_rx); - furi_assert(dest_data); - furi_assert(src_data); - - uint8_t first_block = mf_classic_get_first_block_num_of_sector(sec_num); - uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num); - MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(dest_data, sec_num); - bool key_a_found = mf_classic_is_key_found(dest_data, sec_num, MfClassicKeyA); - bool key_b_found = mf_classic_is_key_found(dest_data, sec_num, MfClassicKeyB); - - bool write_success = true; - for(size_t i = first_block; i < first_block + total_blocks; i++) { - // Compare blocks - if(memcmp(dest_data->block[i].value, src_data->block[i].value, MF_CLASSIC_BLOCK_SIZE) != - 0) { - if(mf_classic_is_value_block(dest_data, i)) { - bool key_a_inc_allowed = mf_classic_is_allowed_access_data_block( - dest_data, i, MfClassicKeyA, MfClassicActionDataInc); - bool key_b_inc_allowed = mf_classic_is_allowed_access_data_block( - dest_data, i, MfClassicKeyB, MfClassicActionDataInc); - bool key_a_dec_allowed = mf_classic_is_allowed_access_data_block( - dest_data, i, MfClassicKeyA, MfClassicActionDataDec); - bool key_b_dec_allowed = mf_classic_is_allowed_access_data_block( - dest_data, i, MfClassicKeyB, MfClassicActionDataDec); - - int32_t src_value, dst_value; - - mf_classic_block_to_value(src_data->block[i].value, &src_value, NULL); - mf_classic_block_to_value(dest_data->block[i].value, &dst_value, NULL); - - int32_t diff = src_value - dst_value; - - if(diff > 0) { - if(key_a_found && key_a_inc_allowed) { - FURI_LOG_I(TAG, "Incrementing block %d with key A by %ld", i, diff); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6); - if(!mf_classic_value_cmd_full( - tx_rx, &src_data->block[i], i, MfClassicKeyA, key, diff)) { - FURI_LOG_E(TAG, "Failed to increment block %d", i); - write_success = false; - break; - } - } else if(key_b_found && key_b_inc_allowed) { - FURI_LOG_I(TAG, "Incrementing block %d with key B by %ld", i, diff); - uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6); - if(!mf_classic_value_cmd_full( - tx_rx, &src_data->block[i], i, MfClassicKeyB, key, diff)) { - FURI_LOG_E(TAG, "Failed to increment block %d", i); - write_success = false; - break; - } - } else { - FURI_LOG_E(TAG, "Failed to increment block %d", i); - } - } else if(diff < 0) { - if(key_a_found && key_a_dec_allowed) { - FURI_LOG_I(TAG, "Decrementing block %d with key A by %ld", i, -diff); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6); - if(!mf_classic_value_cmd_full( - tx_rx, &src_data->block[i], i, MfClassicKeyA, key, diff)) { - FURI_LOG_E(TAG, "Failed to decrement block %d", i); - write_success = false; - break; - } - } else if(key_b_found && key_b_dec_allowed) { - FURI_LOG_I(TAG, "Decrementing block %d with key B by %ld", i, diff); - uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6); - if(!mf_classic_value_cmd_full( - tx_rx, &src_data->block[i], i, MfClassicKeyB, key, diff)) { - FURI_LOG_E(TAG, "Failed to decrement block %d", i); - write_success = false; - break; - } - } else { - FURI_LOG_E(TAG, "Failed to decrement block %d", i); - } - } else { - FURI_LOG_E(TAG, "Value block %d address changed, cannot write it", i); - } - } else { - bool key_a_write_allowed = mf_classic_is_allowed_access_data_block( - dest_data, i, MfClassicKeyA, MfClassicActionDataWrite); - bool key_b_write_allowed = mf_classic_is_allowed_access_data_block( - dest_data, i, MfClassicKeyB, MfClassicActionDataWrite); - - if(key_a_found && key_a_write_allowed) { - FURI_LOG_I(TAG, "Writing block %d with key A", i); - uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6); - if(!mf_classic_auth_write_block( - tx_rx, &src_data->block[i], i, MfClassicKeyA, key)) { - FURI_LOG_E(TAG, "Failed to write block %d", i); - write_success = false; - break; - } - } else if(key_b_found && key_b_write_allowed) { - FURI_LOG_I(TAG, "Writing block %d with key A", i); - uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6); - if(!mf_classic_auth_write_block( - tx_rx, &src_data->block[i], i, MfClassicKeyB, key)) { - FURI_LOG_E(TAG, "Failed to write block %d", i); - write_success = false; - break; - } - } else { - FURI_LOG_E(TAG, "Failed to find key with write access"); - write_success = false; - break; - } - } - } else { - FURI_LOG_D(TAG, "Blocks %d are equal", i); - } - } - - return write_success; -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.h deleted file mode 100644 index 43aa9b7b09e..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/protocols/mifare_classic.h +++ /dev/null @@ -1,251 +0,0 @@ -#pragma once - -#include "../furi_hal_nfc.h" - -#include "crypto1.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MF_CLASSIC_BLOCK_SIZE (16) -#define MF_CLASSIC_TOTAL_BLOCKS_MAX (256) -#define MF_MINI_TOTAL_SECTORS_NUM (5) -#define MF_CLASSIC_1K_TOTAL_SECTORS_NUM (16) -#define MF_CLASSIC_4K_TOTAL_SECTORS_NUM (40) - -#define MF_CLASSIC_SECTORS_MAX (40) -#define MF_CLASSIC_BLOCKS_IN_SECTOR_MAX (16) - -#define MF_CLASSIC_NO_KEY (0xFFFFFFFFFFFFFFFF) -#define MF_CLASSIC_MAX_DATA_SIZE (16) -#define MF_CLASSIC_KEY_SIZE (6) -#define MF_CLASSIC_ACCESS_BYTES_SIZE (4) - -typedef enum { - MfClassicType1k, - MfClassicType4k, - MfClassicTypeMini, -} MfClassicType; - -typedef enum { - MfClassicKeyA, - MfClassicKeyB, -} MfClassicKey; - -typedef enum { - MfClassicActionDataRead, - MfClassicActionDataWrite, - MfClassicActionDataInc, - MfClassicActionDataDec, - - MfClassicActionKeyARead, - MfClassicActionKeyAWrite, - MfClassicActionKeyBRead, - MfClassicActionKeyBWrite, - MfClassicActionACRead, - MfClassicActionACWrite, -} MfClassicAction; - -typedef struct { - uint8_t value[MF_CLASSIC_BLOCK_SIZE]; -} MfClassicBlock; - -typedef struct { - uint8_t key_a[MF_CLASSIC_KEY_SIZE]; - uint8_t access_bits[MF_CLASSIC_ACCESS_BYTES_SIZE]; - uint8_t key_b[MF_CLASSIC_KEY_SIZE]; -} MfClassicSectorTrailer; - -typedef struct { - uint8_t total_blocks; - MfClassicBlock block[MF_CLASSIC_BLOCKS_IN_SECTOR_MAX]; -} MfClassicSector; - -typedef struct { - MfClassicType type; - uint32_t block_read_mask[MF_CLASSIC_TOTAL_BLOCKS_MAX / 32]; - uint64_t key_a_mask; - uint64_t key_b_mask; - MfClassicBlock block[MF_CLASSIC_TOTAL_BLOCKS_MAX]; -} MfClassicData; - -typedef struct { - uint8_t sector; - uint64_t key_a; - uint64_t key_b; -} MfClassicAuthContext; - -typedef struct { - uint8_t sector_num; - uint64_t key_a; - uint64_t key_b; -} MfClassicSectorReader; - -typedef struct { - MfClassicType type; - Crypto1 crypto; - uint8_t sectors_to_read; - MfClassicSectorReader sector_reader[MF_CLASSIC_SECTORS_MAX]; -} MfClassicReader; - -typedef struct { - uint32_t cuid; - Crypto1 crypto; - MfClassicData data; - bool data_changed; -} MfClassicEmulator; - -const char* mf_classic_get_type_str(MfClassicType type); - -bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); - -MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); - -uint8_t mf_classic_get_total_sectors_num(MfClassicType type); - -uint16_t mf_classic_get_total_block_num(MfClassicType type); - -uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector); - -bool mf_classic_is_sector_trailer(uint8_t block); - -uint8_t mf_classic_get_sector_by_block(uint8_t block); - -bool mf_classic_is_allowed_access_sector_trailer( - MfClassicData* data, - uint8_t block_num, - MfClassicKey key, - MfClassicAction action); - -bool mf_classic_is_allowed_access_data_block( - MfClassicData* data, - uint8_t block_num, - MfClassicKey key, - MfClassicAction action); - -bool mf_classic_is_value_block(MfClassicData* data, uint8_t block_num); - -bool mf_classic_block_to_value(const uint8_t* block, int32_t* value, uint8_t* addr); - -void mf_classic_value_to_block(int32_t value, uint8_t addr, uint8_t* block); - -bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type); - -void mf_classic_set_key_found( - MfClassicData* data, - uint8_t sector_num, - MfClassicKey key_type, - uint64_t key); - -void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type); - -bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num); - -void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data); - -bool mf_classic_is_sector_data_read(MfClassicData* data, uint8_t sector_num); - -void mf_classic_set_sector_data_not_read(MfClassicData* data); - -bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num); - -bool mf_classic_is_card_read(MfClassicData* data); - -void mf_classic_get_read_sectors_and_keys( - MfClassicData* data, - uint8_t* sectors_read, - uint8_t* keys_found); - -MfClassicSectorTrailer* - mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector); - -void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector); - -bool mf_classic_authenticate( - FurryHalNfcTxRxContext* tx_rx, - uint8_t block_num, - uint64_t key, - MfClassicKey key_type); - -bool mf_classic_authenticate_skip_activate( - FurryHalNfcTxRxContext* tx_rx, - uint8_t block_num, - uint64_t key, - MfClassicKey key_type, - bool skip_activate, - uint32_t cuid); - -bool mf_classic_auth_attempt( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - MfClassicAuthContext* auth_ctx, - uint64_t key); - -void mf_classic_reader_add_sector( - MfClassicReader* reader, - uint8_t sector, - uint64_t key_a, - uint64_t key_b); - -bool mf_classic_read_block( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - uint8_t block_num, - MfClassicBlock* block); - -void mf_classic_read_sector(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num); - -uint8_t mf_classic_read_card( - FurryHalNfcTxRxContext* tx_rx, - MfClassicReader* reader, - MfClassicData* data); - -uint8_t mf_classic_update_card(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data); - -bool mf_classic_emulator( - MfClassicEmulator* emulator, - FurryHalNfcTxRxContext* tx_rx, - bool is_reader_analyzer); - -void mf_classic_halt(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto); - -bool mf_classic_write_block( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - uint8_t block_num, - MfClassicBlock* src_block); - -bool mf_classic_auth_write_block( - FurryHalNfcTxRxContext* tx_rx, - MfClassicBlock* src_block, - uint8_t block_num, - MfClassicKey key_type, - uint64_t key); - -bool mf_classic_transfer(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto, uint8_t block_num); - -bool mf_classic_value_cmd( - FurryHalNfcTxRxContext* tx_rx, - Crypto1* crypto, - uint8_t block_num, - uint8_t cmd, - int32_t d_value); - -bool mf_classic_value_cmd_full( - FurryHalNfcTxRxContext* tx_rx, - MfClassicBlock* src_block, - uint8_t block_num, - MfClassicKey key_type, - uint64_t key, - int32_t d_value); - -bool mf_classic_write_sector( - FurryHalNfcTxRxContext* tx_rx, - MfClassicData* dest_data, - MfClassicData* src_data, - uint8_t sec_num); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.c b/non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.c deleted file mode 100644 index 1c3cb4a586f..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.c +++ /dev/null @@ -1,236 +0,0 @@ -#include "pulse_reader.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -struct PulseReader { - uint32_t* timer_buffer; - uint32_t* gpio_buffer; - uint32_t size; - uint32_t pos; - uint32_t timer_value; - uint32_t gpio_value; - uint32_t gpio_mask; - uint32_t unit_multiplier; - uint32_t unit_divider; - uint32_t bit_time; - uint32_t dma_channel; - const GpioPin* gpio; - GpioPull pull; - LL_DMA_InitTypeDef dma_config_timer; - LL_DMA_InitTypeDef dma_config_gpio; -}; - -#define GPIO_PIN_MAP(pin, prefix) \ - (((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \ - ((pin) == (LL_GPIO_PIN_1)) ? prefix##1 : \ - ((pin) == (LL_GPIO_PIN_2)) ? prefix##2 : \ - ((pin) == (LL_GPIO_PIN_3)) ? prefix##3 : \ - ((pin) == (LL_GPIO_PIN_4)) ? prefix##4 : \ - ((pin) == (LL_GPIO_PIN_5)) ? prefix##5 : \ - ((pin) == (LL_GPIO_PIN_6)) ? prefix##6 : \ - ((pin) == (LL_GPIO_PIN_7)) ? prefix##7 : \ - ((pin) == (LL_GPIO_PIN_8)) ? prefix##8 : \ - ((pin) == (LL_GPIO_PIN_9)) ? prefix##9 : \ - ((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \ - ((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \ - ((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \ - ((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \ - ((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \ - prefix##15) - -#define GET_DMAMUX_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_DMAMUX_REQ_GEN_EXTI_LINE) - -PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size) { - PulseReader* signal = malloc(sizeof(PulseReader)); - signal->timer_buffer = malloc(size * sizeof(uint32_t)); - signal->gpio_buffer = malloc(size * sizeof(uint32_t)); - signal->dma_channel = LL_DMA_CHANNEL_4; - signal->gpio = gpio; - signal->pull = GpioPullNo; - signal->size = size; - signal->timer_value = 0; - signal->pos = 0; - - pulse_reader_set_timebase(signal, PulseReaderUnit64MHz); - pulse_reader_set_bittime(signal, 1); - - signal->dma_config_timer.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; - signal->dma_config_timer.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->CNT); - signal->dma_config_timer.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - signal->dma_config_timer.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; - signal->dma_config_timer.MemoryOrM2MDstAddress = (uint32_t)signal->timer_buffer; - signal->dma_config_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - signal->dma_config_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - signal->dma_config_timer.Mode = LL_DMA_MODE_CIRCULAR; - signal->dma_config_timer.PeriphRequest = - LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */ - signal->dma_config_timer.Priority = LL_DMA_PRIORITY_VERYHIGH; - - signal->dma_config_gpio.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; - signal->dma_config_gpio.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - signal->dma_config_gpio.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; - signal->dma_config_gpio.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - signal->dma_config_gpio.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - signal->dma_config_gpio.Mode = LL_DMA_MODE_CIRCULAR; - signal->dma_config_gpio.PeriphRequest = - LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */ - signal->dma_config_gpio.Priority = LL_DMA_PRIORITY_VERYHIGH; - - return signal; -} - -void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit) { - switch(unit) { - case PulseReaderUnit64MHz: - signal->unit_multiplier = 1; - signal->unit_divider = 1; - break; - case PulseReaderUnitPicosecond: - signal->unit_multiplier = 15625; - signal->unit_divider = 1; - break; - case PulseReaderUnitNanosecond: - signal->unit_multiplier = 15625; - signal->unit_divider = 1000; - break; - case PulseReaderUnitMicrosecond: - signal->unit_multiplier = 15625; - signal->unit_divider = 1000000; - break; - } -} - -void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time) { - signal->bit_time = bit_time; -} - -void pulse_reader_set_pull(PulseReader* signal, GpioPull pull) { - signal->pull = pull; -} - -void pulse_reader_free(PulseReader* signal) { - furi_assert(signal); - - free(signal->timer_buffer); - free(signal->gpio_buffer); - free(signal); -} - -uint32_t pulse_reader_samples(PulseReader* signal) { - uint32_t dma_pos = signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel); - - return ((signal->pos + signal->size) - dma_pos) % signal->size; -} - -void pulse_reader_stop(PulseReader* signal) { - LL_DMA_DisableChannel(DMA1, signal->dma_channel); - LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1); - LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); - LL_TIM_DisableCounter(TIM2); - furi_hal_bus_disable(FuriHalBusTIM2); - furi_hal_gpio_init_simple(signal->gpio, GpioModeAnalog); -} - -void pulse_reader_start(PulseReader* signal) { - /* configure DMA to read from a timer peripheral */ - signal->dma_config_timer.NbData = signal->size; - - signal->dma_config_gpio.PeriphOrM2MSrcAddress = (uint32_t) & (signal->gpio->port->IDR); - signal->dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t)signal->gpio_buffer; - signal->dma_config_gpio.NbData = signal->size; - - furi_hal_bus_enable(FuriHalBusTIM2); - - /* start counter */ - LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); - LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); - LL_TIM_SetPrescaler(TIM2, 0); - LL_TIM_SetAutoReload(TIM2, 0xFFFFFFFF); - LL_TIM_SetCounter(TIM2, 0); - LL_TIM_EnableCounter(TIM2); - - /* generator 0 gets fed by EXTI_LINEn */ - LL_DMAMUX_SetRequestSignalID( - NULL, LL_DMAMUX_REQ_GEN_0, GET_DMAMUX_EXTI_LINE(signal->gpio->pin)); - /* trigger on rising edge of the interrupt */ - LL_DMAMUX_SetRequestGenPolarity(NULL, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING); - /* now enable request generation again */ - LL_DMAMUX_EnableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); - - /* we need the EXTI to be configured as interrupt generating line, but no ISR registered */ - furi_hal_gpio_init_ex( - signal->gpio, GpioModeInterruptRiseFall, signal->pull, GpioSpeedVeryHigh, GpioAltFnUnused); - - /* capture current timer */ - signal->pos = 0; - signal->timer_value = TIM2->CNT; - signal->gpio_mask = signal->gpio->pin; - signal->gpio_value = signal->gpio->port->IDR & signal->gpio_mask; - - /* now set up DMA with these settings */ - LL_DMA_Init(DMA1, signal->dma_channel, &signal->dma_config_timer); - LL_DMA_Init(DMA1, signal->dma_channel + 1, &signal->dma_config_gpio); - LL_DMA_EnableChannel(DMA1, signal->dma_channel); - LL_DMA_EnableChannel(DMA1, signal->dma_channel + 1); -} - -uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) { - uint32_t start_time = DWT->CYCCNT; - uint32_t timeout_ticks = timeout_us * (F_TIM2 / 1000000); - - do { - /* get the DMA's next write position by reading "remaining length" register */ - uint32_t dma_pos = - signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel); - - /* the DMA has advanced in the ringbuffer */ - if(dma_pos != signal->pos) { - uint32_t delta = signal->timer_buffer[signal->pos] - signal->timer_value; - uint32_t last_gpio_value = signal->gpio_value; - - signal->gpio_value = signal->gpio_buffer[signal->pos]; - - /* check if the GPIO really toggled. if not, we lost an edge :( */ - if(((last_gpio_value ^ signal->gpio_value) & signal->gpio_mask) != signal->gpio_mask) { - signal->gpio_value ^= signal->gpio_mask; - return PULSE_READER_LOST_EDGE; - } - signal->timer_value = signal->timer_buffer[signal->pos]; - - signal->pos++; - signal->pos %= signal->size; - - uint32_t delta_unit = 0; - - /* probably larger values, so choose a wider data type */ - if(signal->unit_divider > 1) { - delta_unit = - (uint32_t)((uint64_t)delta * (uint64_t)signal->unit_multiplier / signal->unit_divider); - } else { - delta_unit = delta * signal->unit_multiplier; - } - - /* if to be scaled to bit times, save a few instructions. should be faster */ - if(signal->bit_time > 1) { - return (delta_unit + signal->bit_time / 2) / signal->bit_time; - } - - return delta_unit; - } - - /* check for timeout */ - uint32_t elapsed = DWT->CYCCNT - start_time; - - if(elapsed > timeout_ticks) { - return PULSE_READER_NO_EDGE; - } - } while(true); -} diff --git a/non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.h b/non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.h deleted file mode 100644 index 62c5f2fa46d..00000000000 --- a/non_catalog_apps/esubghz_chat/lib/nfclegacy/pulse_reader/pulse_reader.h +++ /dev/null @@ -1,122 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PULSE_READER_NO_EDGE (0xFFFFFFFFUL) -#define PULSE_READER_LOST_EDGE (0xFFFFFFFEUL) -#define F_TIM2 (64000000UL) - -/** - * unit of the edge durations to return - */ -typedef enum { - PulseReaderUnit64MHz, - PulseReaderUnitPicosecond, - PulseReaderUnitNanosecond, - PulseReaderUnitMicrosecond, -} PulseReaderUnit; - -/* using an anonymous type */ -typedef struct PulseReader PulseReader; - -/** Allocate a PulseReader object - * - * Allocates memory for a ringbuffer and initalizes the object - * - * @param[in] gpio the GPIO to use. will get configured as input. - * @param[in] size number of edges to buffer - */ -PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size); - -/** Free a PulseReader object - * - * Frees all memory of the given object - * - * @param[in] signal previously allocated PulseReader object. - */ -void pulse_reader_free(PulseReader* signal); - -/** Start signal capturing - * - * Initializes DMA1, TIM2 and DMAMUX_REQ_GEN_0 to automatically capture timer values. - * Ensure that interrupts are always enabled, as the used EXTI line is handled as one. - * - * @param[in] signal previously allocated PulseReader object. - */ -void pulse_reader_start(PulseReader* signal); - -/** Stop signal capturing - * - * Frees DMA1, TIM2 and DMAMUX_REQ_GEN_0 - * - * @param[in] signal previously allocated PulseReader object. - */ -void pulse_reader_stop(PulseReader* signal); - -/** Recevie a sample from ringbuffer - * - * Waits for the specified time until a new edge gets detected. - * If not configured otherwise, the pulse duration will be in picosecond resolution. - * If a bittime was configured, the return value will contain the properly rounded - * number of bit times measured. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] timeout_us time to wait for a signal [µs] - * - * @returns the scaled value of the pulse duration - */ -uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us); - -/** Get available samples - * - * Get the number of available samples in the ringbuffer - * - * @param[in] signal previously allocated PulseReader object. - * - * @returns the number of samples in buffer - */ -uint32_t pulse_reader_samples(PulseReader* signal); - -/** Set timebase - * - * Set the timebase to be used when returning pulse duration. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] unit PulseReaderUnit64MHz or PulseReaderUnitPicosecond - */ -void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit); - -/** Set bit time - * - * Set the number of timebase units per bit. - * When set, the pulse_reader_receive() will return an already rounded - * bit count value instead of the raw duration. - * - * Set to 1 to return duration again. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] bit_time - */ -void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time); - -/** Set GPIO pull direction - * - * Some GPIOs need pulldown, others don't. By default the - * pull direction is GpioPullNo. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] pull GPIO pull direction - */ -void pulse_reader_set_pull(PulseReader* signal, GpioPull pull); - -#ifdef __cplusplus -} -#endif From 27544eb845e3bd23391394e8ea5817effefb213b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:28:12 +0300 Subject: [PATCH 19/36] free up some space in mifare nested too --- base_pack/mifare_nested/application.fam | 2 +- .../lib/nfclegacy/helpers/nfc_debug_log.c | 71 - .../lib/nfclegacy/helpers/nfc_debug_log.h | 17 - .../lib/nfclegacy/helpers/nfc_debug_pcap.c | 128 -- .../lib/nfclegacy/helpers/nfc_debug_pcap.h | 17 - .../lib/nfclegacy/helpers/nfc_generators.c | 548 ----- .../lib/nfclegacy/helpers/nfc_generators.h | 29 - .../lib/nfclegacy/helpers/reader_analyzer.c | 265 --- .../lib/nfclegacy/helpers/reader_analyzer.h | 43 - .../mifare_nested/lib/nfclegacy/nfc_device.c | 217 +- .../mifare_nested/lib/nfclegacy/nfc_device.h | 14 - .../mifare_nested/lib/nfclegacy/nfc_types.c | 36 +- .../mifare_nested/lib/nfclegacy/nfc_types.h | 2 - .../mifare_nested/lib/nfclegacy/nfc_worker.c | 441 +--- .../mifare_nested/lib/nfclegacy/nfc_worker.h | 25 - .../lib/nfclegacy/nfc_worker_i.h | 14 +- .../nfclegacy/protocols/mifare_ultralight.c | 1946 ----------------- .../nfclegacy/protocols/mifare_ultralight.h | 269 --- .../lib/nfclegacy/pulse_reader/pulse_reader.c | 236 -- .../lib/nfclegacy/pulse_reader/pulse_reader.h | 122 -- 20 files changed, 27 insertions(+), 4415 deletions(-) delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.c delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.h delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.c delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.h delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.c delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.h delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.c delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.h delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.c delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.h delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.c delete mode 100644 base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.h diff --git a/base_pack/mifare_nested/application.fam b/base_pack/mifare_nested/application.fam index 5d72e246186..f7fc9a2083a 100644 --- a/base_pack/mifare_nested/application.fam +++ b/base_pack/mifare_nested/application.fam @@ -18,5 +18,5 @@ App( fap_author="AloneLiberty & xMasterX", fap_description="Recover Mifare Classic keys", fap_weburl="https://github.com/AloneLiberty/FlipperNested", - fap_version="1.6.5", + fap_version="1.6.6", ) diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.c b/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.c deleted file mode 100644 index 0bfbc2c62f6..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "nfc_debug_log.h" - -#include -#include - -#define TAG "NfcDebugLog" - -#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.txt") - -struct NfcDebugLog { - Stream* file_stream; - FuriString* data_str; -}; - -NfcDebugLog* nfc_debug_log_alloc() { - NfcDebugLog* instance = malloc(sizeof(NfcDebugLog)); - - Storage* storage = furi_record_open(RECORD_STORAGE); - instance->file_stream = buffered_file_stream_alloc(storage); - - if(!buffered_file_stream_open( - instance->file_stream, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) { - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - instance->file_stream = NULL; - } - - if(!instance->file_stream) { - free(instance); - instance = NULL; - } else { - instance->data_str = furi_string_alloc(); - } - furi_record_close(RECORD_STORAGE); - - return instance; -} - -void nfc_debug_log_free(NfcDebugLog* instance) { - furi_assert(instance); - furi_assert(instance->file_stream); - furi_assert(instance->data_str); - - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - furi_string_free(instance->data_str); - - free(instance); -} - -void nfc_debug_log_process_data( - NfcDebugLog* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - furi_assert(instance); - furi_assert(instance->file_stream); - furi_assert(instance->data_str); - furi_assert(data); - UNUSED(crc_dropped); - - furi_string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T'); - uint16_t data_len = len; - for(size_t i = 0; i < data_len; i++) { - furi_string_cat_printf(instance->data_str, " %02x", data[i]); - } - furi_string_push_back(instance->data_str, '\n'); - - stream_write_string(instance->file_stream, instance->data_str); -} diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.h b/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.h deleted file mode 100644 index 261b8008b8e..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_log.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -typedef struct NfcDebugLog NfcDebugLog; - -NfcDebugLog* nfc_debug_log_alloc(); - -void nfc_debug_log_free(NfcDebugLog* instance); - -void nfc_debug_log_process_data( - NfcDebugLog* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped); diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.c b/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.c deleted file mode 100644 index 10b19994c51..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.c +++ /dev/null @@ -1,128 +0,0 @@ -#include "nfc_debug_pcap.h" - -#include -#include -#include "../furi_hal_nfc.h" -#include - -#define TAG "NfcDebugPcap" - -#define PCAP_MAGIC 0xa1b2c3d4 -#define PCAP_MAJOR 2 -#define PCAP_MINOR 4 -#define DLT_ISO_14443 264 - -#define DATA_PICC_TO_PCD 0xFF -#define DATA_PCD_TO_PICC 0xFE -#define DATA_PICC_TO_PCD_CRC_DROPPED 0xFB -#define DATA_PCD_TO_PICC_CRC_DROPPED 0xFA - -#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.pcap") - -struct NfcDebugPcap { - Stream* file_stream; -}; - -static Stream* nfc_debug_pcap_open(Storage* storage) { - Stream* stream = NULL; - stream = buffered_file_stream_alloc(storage); - if(!buffered_file_stream_open(stream, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) { - buffered_file_stream_close(stream); - stream_free(stream); - stream = NULL; - } else { - if(!stream_tell(stream)) { - struct { - uint32_t magic; - uint16_t major, minor; - uint32_t reserved[2]; - uint32_t snaplen; - uint32_t link_type; - } __attribute__((__packed__)) pcap_hdr = { - .magic = PCAP_MAGIC, - .major = PCAP_MAJOR, - .minor = PCAP_MINOR, - .snaplen = FURRY_HAL_NFC_DATA_BUFF_SIZE, - .link_type = DLT_ISO_14443, - }; - if(stream_write(stream, (uint8_t*)&pcap_hdr, sizeof(pcap_hdr)) != sizeof(pcap_hdr)) { - FURI_LOG_E(TAG, "Failed to write pcap header"); - buffered_file_stream_close(stream); - stream_free(stream); - stream = NULL; - } - } - } - return stream; -} - -NfcDebugPcap* nfc_debug_pcap_alloc() { - NfcDebugPcap* instance = malloc(sizeof(NfcDebugPcap)); - - Storage* storage = furi_record_open(RECORD_STORAGE); - instance->file_stream = nfc_debug_pcap_open(storage); - if(!instance->file_stream) { - free(instance); - instance = NULL; - } - furi_record_close(RECORD_STORAGE); - - return instance; -} - -void nfc_debug_pcap_free(NfcDebugPcap* instance) { - furi_assert(instance); - furi_assert(instance->file_stream); - - buffered_file_stream_close(instance->file_stream); - stream_free(instance->file_stream); - - free(instance); -} - -void nfc_debug_pcap_process_data( - NfcDebugPcap* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - furi_assert(instance); - furi_assert(data); - - uint8_t event = 0; - if(reader_to_tag) { - if(crc_dropped) { - event = DATA_PCD_TO_PICC_CRC_DROPPED; - } else { - event = DATA_PCD_TO_PICC; - } - } else { - if(crc_dropped) { - event = DATA_PICC_TO_PCD_CRC_DROPPED; - } else { - event = DATA_PICC_TO_PCD; - } - } - - struct { - // https://wiki.wireshark.org/Development/LibpcapFileFormat#record-packet-header - uint32_t ts_sec; - uint32_t ts_usec; - uint32_t incl_len; - uint32_t orig_len; - // https://www.kaiser.cx/posts/pcap-iso14443/#_packet_data - uint8_t version; - uint8_t event; - uint16_t len; - } __attribute__((__packed__)) pkt_hdr = { - .ts_sec = furi_hal_rtc_get_timestamp(), - .ts_usec = 0, - .incl_len = len + 4, - .orig_len = len + 4, - .version = 0, - .event = event, - .len = len << 8 | len >> 8, - }; - stream_write(instance->file_stream, (uint8_t*)&pkt_hdr, sizeof(pkt_hdr)); - stream_write(instance->file_stream, data, len); -} diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.h b/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.h deleted file mode 100644 index eeddc56112c..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_debug_pcap.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -typedef struct NfcDebugPcap NfcDebugPcap; - -NfcDebugPcap* nfc_debug_pcap_alloc(); - -void nfc_debug_pcap_free(NfcDebugPcap* instance); - -void nfc_debug_pcap_process_data( - NfcDebugPcap* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped); diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.c b/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.c deleted file mode 100644 index 5ab6280680b..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.c +++ /dev/null @@ -1,548 +0,0 @@ -#include -#include "nfc_generators.h" - -#define NXP_MANUFACTURER_ID (0x04) - -static const uint8_t version_bytes_mf0ulx1[] = {0x00, 0x04, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03}; -static const uint8_t version_bytes_ntag21x[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x03}; -static const uint8_t version_bytes_ntag_i2c[] = {0x00, 0x04, 0x04, 0x05, 0x02, 0x00, 0x00, 0x03}; -static const uint8_t default_data_ntag203[] = - {0xE1, 0x10, 0x12, 0x00, 0x01, 0x03, 0xA0, 0x10, 0x44, 0x03, 0x00, 0xFE}; -static const uint8_t default_data_ntag213[] = {0x01, 0x03, 0xA0, 0x0C, 0x34, 0x03, 0x00, 0xFE}; -static const uint8_t default_data_ntag215_216[] = {0x03, 0x00, 0xFE}; -static const uint8_t default_data_ntag_i2c[] = {0xE1, 0x10, 0x00, 0x00, 0x03, 0x00, 0xFE}; -static const uint8_t default_config_ntag_i2c[] = {0x01, 0x00, 0xF8, 0x48, 0x08, 0x01, 0x00, 0x00}; - -static void nfc_generate_common_start(NfcDeviceData* data) { - nfc_device_data_clear(data); -} - -static void nfc_generate_mf_ul_uid(uint8_t* uid) { - uid[0] = NXP_MANUFACTURER_ID; - furi_hal_random_fill_buf(&uid[1], 6); - // I'm not sure how this is generated, but the upper nybble always seems to be 8 - uid[6] &= 0x0F; - uid[6] |= 0x80; -} - -static void nfc_generate_mf_classic_uid(uint8_t* uid, uint8_t length) { - uid[0] = NXP_MANUFACTURER_ID; - furi_hal_random_fill_buf(&uid[1], length - 1); -} - -static void nfc_generate_mf_classic_block_0( - uint8_t* block, - uint8_t uid_len, - uint8_t sak, - uint8_t atqa0, - uint8_t atqa1) { - // Block length is always 16 bytes, and the UID can be either 4 or 7 bytes - furi_assert(uid_len == 4 || uid_len == 7); - furi_assert(block); - - if(uid_len == 4) { - // Calculate BCC - block[uid_len] = 0; - - for(int i = 0; i < uid_len; i++) { - block[uid_len] ^= block[i]; - } - } else { - uid_len -= 1; - } - - block[uid_len + 1] = sak; - block[uid_len + 2] = atqa0; - block[uid_len + 3] = atqa1; - - for(int i = uid_len + 4; i < 16; i++) { - block[i] = 0xFF; - } -} - -static void nfc_generate_mf_classic_sector_trailer(MfClassicData* data, uint8_t block) { - // All keys are set to FFFF FFFF FFFFh at chip delivery and the bytes 6, 7 and 8 are set to FF0780h. - MfClassicSectorTrailer* sec_tr = (MfClassicSectorTrailer*)data->block[block].value; - sec_tr->access_bits[0] = 0xFF; - sec_tr->access_bits[1] = 0x07; - sec_tr->access_bits[2] = 0x80; - sec_tr->access_bits[3] = 0x69; // Nice - - memset(sec_tr->key_a, 0xff, sizeof(sec_tr->key_a)); - memset(sec_tr->key_b, 0xff, sizeof(sec_tr->key_b)); - - mf_classic_set_block_read(data, block, &data->block[block]); - mf_classic_set_key_found( - data, mf_classic_get_sector_by_block(block), MfClassicKeyA, 0xFFFFFFFFFFFF); - mf_classic_set_key_found( - data, mf_classic_get_sector_by_block(block), MfClassicKeyB, 0xFFFFFFFFFFFF); -} - -static void nfc_generate_mf_ul_common(NfcDeviceData* data) { - data->nfc_data.type = FurryHalNfcTypeA; - data->nfc_data.interface = FurryHalNfcInterfaceRf; - data->nfc_data.uid_len = 7; - nfc_generate_mf_ul_uid(data->nfc_data.uid); - data->nfc_data.atqa[0] = 0x44; - data->nfc_data.atqa[1] = 0x00; - data->nfc_data.sak = 0x00; - data->protocol = NfcDeviceProtocolMifareUl; -} - -static void - nfc_generate_mf_classic_common(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { - data->nfc_data.type = FurryHalNfcTypeA; - data->nfc_data.interface = FurryHalNfcInterfaceRf; - data->nfc_data.uid_len = uid_len; - data->nfc_data.atqa[0] = 0x44; - data->nfc_data.atqa[1] = 0x00; - data->nfc_data.sak = 0x08; - data->protocol = NfcDeviceProtocolMifareClassic; - data->mf_classic_data.type = type; -} - -static void nfc_generate_calc_bcc(uint8_t* uid, uint8_t* bcc0, uint8_t* bcc1) { - *bcc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; - *bcc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; -} - -static void nfc_generate_mf_ul_copy_uid_with_bcc(NfcDeviceData* data) { - MfUltralightData* mful = &data->mf_ul_data; - memcpy(mful->data, data->nfc_data.uid, 3); - memcpy(&mful->data[4], &data->nfc_data.uid[3], 4); - nfc_generate_calc_bcc(data->nfc_data.uid, &mful->data[3], &mful->data[8]); -} - -static void nfc_generate_mf_ul_orig(NfcDeviceData* data) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUnknown; - mful->data_size = 16 * 4; - mful->data_read = mful->data_size; - nfc_generate_mf_ul_copy_uid_with_bcc(data); - // TODO: what's internal byte on page 2? - memset(&mful->data[4 * 4], 0xFF, 4); -} - -static void nfc_generate_mf_ul_ntag203(NfcDeviceData* data) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG203; - mful->data_size = 42 * 4; - mful->data_read = mful->data_size; - nfc_generate_mf_ul_copy_uid_with_bcc(data); - mful->data[9] = 0x48; // Internal byte - memcpy(&mful->data[3 * 4], default_data_ntag203, sizeof(default_data_ntag203)); -} - -static void nfc_generate_mf_ul_with_config_common(NfcDeviceData* data, uint8_t num_pages) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->data_size = num_pages * 4; - mful->data_read = mful->data_size; - nfc_generate_mf_ul_copy_uid_with_bcc(data); - uint16_t config_index = (num_pages - 4) * 4; - mful->data[config_index] = 0x04; // STRG_MOD_EN - mful->data[config_index + 3] = 0xFF; // AUTH0 - mful->data[config_index + 5] = 0x05; // VCTID - memset(&mful->data[config_index + 8], 0xFF, 4); // Default PWD - if(num_pages > 20) mful->data[config_index - 1] = MF_UL_TEARING_FLAG_DEFAULT; -} - -static void nfc_generate_mf_ul_ev1_common(NfcDeviceData* data, uint8_t num_pages) { - nfc_generate_mf_ul_with_config_common(data, num_pages); - MfUltralightData* mful = &data->mf_ul_data; - memcpy(&mful->version, version_bytes_mf0ulx1, sizeof(version_bytes_mf0ulx1)); - for(size_t i = 0; i < 3; ++i) { - mful->tearing[i] = MF_UL_TEARING_FLAG_DEFAULT; - } - // TODO: what's internal byte on page 2? -} - -static void nfc_generate_mf_ul_11(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 20); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL11; - mful->version.prod_subtype = 0x01; - mful->version.storage_size = 0x0B; - mful->data[16 * 4] = 0x00; // Low capacitance version does not have STRG_MOD_EN -} - -static void nfc_generate_mf_ul_h11(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 20); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL11; - mful->version.prod_subtype = 0x02; - mful->version.storage_size = 0x0B; -} - -static void nfc_generate_mf_ul_21(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 41); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL21; - mful->version.prod_subtype = 0x01; - mful->version.storage_size = 0x0E; - mful->data[37 * 4] = 0x00; // Low capacitance version does not have STRG_MOD_EN -} - -static void nfc_generate_mf_ul_h21(NfcDeviceData* data) { - nfc_generate_mf_ul_ev1_common(data, 41); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeUL21; - mful->version.prod_subtype = 0x02; - mful->version.storage_size = 0x0E; -} - -static void nfc_generate_ntag21x_common(NfcDeviceData* data, uint8_t num_pages) { - nfc_generate_mf_ul_with_config_common(data, num_pages); - MfUltralightData* mful = &data->mf_ul_data; - memcpy(&mful->version, version_bytes_ntag21x, sizeof(version_bytes_mf0ulx1)); - mful->data[9] = 0x48; // Internal byte - // Capability container - mful->data[12] = 0xE1; - mful->data[13] = 0x10; -} - -static void nfc_generate_ntag213(NfcDeviceData* data) { - nfc_generate_ntag21x_common(data, 45); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG213; - mful->version.storage_size = 0x0F; - mful->data[14] = 0x12; - // Default contents - memcpy(&mful->data[16], default_data_ntag213, sizeof(default_data_ntag213)); -} - -static void nfc_generate_ntag215(NfcDeviceData* data) { - nfc_generate_ntag21x_common(data, 135); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG215; - mful->version.storage_size = 0x11; - mful->data[14] = 0x3E; - // Default contents - memcpy(&mful->data[16], default_data_ntag215_216, sizeof(default_data_ntag215_216)); -} - -static void nfc_generate_ntag216(NfcDeviceData* data) { - nfc_generate_ntag21x_common(data, 231); - MfUltralightData* mful = &data->mf_ul_data; - mful->type = MfUltralightTypeNTAG216; - mful->version.storage_size = 0x13; - mful->data[14] = 0x6D; - // Default contents - memcpy(&mful->data[16], default_data_ntag215_216, sizeof(default_data_ntag215_216)); -} - -static void - nfc_generate_ntag_i2c_common(NfcDeviceData* data, MfUltralightType type, uint16_t num_pages) { - nfc_generate_common_start(data); - nfc_generate_mf_ul_common(data); - - MfUltralightData* mful = &data->mf_ul_data; - mful->type = type; - memcpy(&mful->version, version_bytes_ntag_i2c, sizeof(version_bytes_ntag_i2c)); - mful->data_size = num_pages * 4; - mful->data_read = mful->data_size; - memcpy(mful->data, data->nfc_data.uid, data->nfc_data.uid_len); - mful->data[7] = data->nfc_data.sak; - mful->data[8] = data->nfc_data.atqa[0]; - mful->data[9] = data->nfc_data.atqa[1]; - - uint16_t config_register_page; - uint16_t session_register_page; - - // Sync with mifare_ultralight.c - switch(type) { - case MfUltralightTypeNTAGI2C1K: - config_register_page = 227; - session_register_page = 229; - break; - case MfUltralightTypeNTAGI2C2K: - config_register_page = 481; - session_register_page = 483; - break; - case MfUltralightTypeNTAGI2CPlus1K: - case MfUltralightTypeNTAGI2CPlus2K: - config_register_page = 232; - session_register_page = 234; - break; - default: - furi_crash("Unknown MFUL"); - break; - } - - memcpy( - &mful->data[config_register_page * 4], - default_config_ntag_i2c, - sizeof(default_config_ntag_i2c)); - memcpy( - &mful->data[session_register_page * 4], - default_config_ntag_i2c, - sizeof(default_config_ntag_i2c)); -} - -static void nfc_generate_ntag_i2c_1k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_common(data, MfUltralightTypeNTAGI2C1K, 231); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x01; - mful->version.storage_size = 0x13; - - memcpy(&mful->data[12], default_data_ntag_i2c, sizeof(default_data_ntag_i2c)); - mful->data[14] = 0x6D; // Size of tag in CC -} - -static void nfc_generate_ntag_i2c_2k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_common(data, MfUltralightTypeNTAGI2C2K, 485); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x01; - mful->version.storage_size = 0x15; - - memcpy(&mful->data[12], default_data_ntag_i2c, sizeof(default_data_ntag_i2c)); - mful->data[14] = 0xEA; // Size of tag in CC -} - -static void nfc_generate_ntag_i2c_plus_common( - NfcDeviceData* data, - MfUltralightType type, - uint16_t num_pages) { - nfc_generate_ntag_i2c_common(data, type, num_pages); - - MfUltralightData* mful = &data->mf_ul_data; - uint16_t config_index = 227 * 4; - mful->data[config_index + 3] = 0xFF; // AUTH0 - memset(&mful->data[config_index + 8], 0xFF, 4); // Default PWD -} - -static void nfc_generate_ntag_i2c_plus_1k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_plus_common(data, MfUltralightTypeNTAGI2CPlus1K, 236); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x02; - mful->version.storage_size = 0x13; -} - -static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) { - nfc_generate_ntag_i2c_plus_common(data, MfUltralightTypeNTAGI2CPlus2K, 492); - MfUltralightData* mful = &data->mf_ul_data; - mful->version.prod_ver_minor = 0x02; - mful->version.storage_size = 0x15; -} - -void nfc_generate_mf_classic_ext( - NfcDeviceData* data, - uint8_t uid_len, - MfClassicType type, - bool random_uid, - uint8_t* uid) { - nfc_generate_common_start(data); - if(random_uid) { - nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len); - } else { - memcpy(data->mf_classic_data.block[0].value, uid, uid_len); - } - nfc_generate_mf_classic_common(data, uid_len, type); - - // Set the UID - if(random_uid) { - data->nfc_data.uid[0] = NXP_MANUFACTURER_ID; - for(int i = 1; i < uid_len; i++) { - data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i]; - } - } else { - for(int i = 0; i < uid_len; i++) { - data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i]; - } - } - - MfClassicData* mfc = &data->mf_classic_data; - mf_classic_set_block_read(mfc, 0, &mfc->block[0]); - - if(type == MfClassicType4k) { - // Set every block to 0xFF - for(uint16_t i = 1; i < 256; i += 1) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc, i); - } else { - memset(&mfc->block[i].value, 0xFF, 16); - } - mf_classic_set_block_read(mfc, i, &mfc->block[i]); - } - // Set SAK to 18 - data->nfc_data.sak = 0x18; - } else if(type == MfClassicType1k) { - // Set every block to 0xFF - for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc, i); - } else { - memset(&mfc->block[i].value, 0xFF, 16); - } - mf_classic_set_block_read(mfc, i, &mfc->block[i]); - } - // Set SAK to 08 - data->nfc_data.sak = 0x08; - } else if(type == MfClassicTypeMini) { - // Set every block to 0xFF - for(uint16_t i = 1; i < MF_MINI_TOTAL_SECTORS_NUM * 4; i += 1) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc, i); - } else { - memset(&mfc->block[i].value, 0xFF, 16); - } - mf_classic_set_block_read(mfc, i, &mfc->block[i]); - } - // Set SAK to 09 - data->nfc_data.sak = 0x09; - } - - nfc_generate_mf_classic_block_0( - data->mf_classic_data.block[0].value, - uid_len, - data->nfc_data.sak, - data->nfc_data.atqa[0], - data->nfc_data.atqa[1]); - - mfc->type = type; -} - -void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) { - uint8_t uid = 0; - nfc_generate_mf_classic_ext(data, uid_len, type, true, &uid); -} - -static void nfc_generate_mf_mini(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 4, MfClassicTypeMini); -} - -static void nfc_generate_mf_classic_1k_4b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 4, MfClassicType1k); -} - -static void nfc_generate_mf_classic_1k_7b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 7, MfClassicType1k); -} - -static void nfc_generate_mf_classic_4k_4b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 4, MfClassicType4k); -} - -static void nfc_generate_mf_classic_4k_7b_uid(NfcDeviceData* data) { - nfc_generate_mf_classic(data, 7, MfClassicType4k); -} - -static const NfcGenerator mf_ul_generator = { - .name = "Mifare Ultralight", - .generator_func = nfc_generate_mf_ul_orig, -}; - -static const NfcGenerator mf_ul_11_generator = { - .name = "Mifare Ultralight EV1 11", - .generator_func = nfc_generate_mf_ul_11, -}; - -static const NfcGenerator mf_ul_h11_generator = { - .name = "Mifare Ultralight EV1 H11", - .generator_func = nfc_generate_mf_ul_h11, -}; - -static const NfcGenerator mf_ul_21_generator = { - .name = "Mifare Ultralight EV1 21", - .generator_func = nfc_generate_mf_ul_21, -}; - -static const NfcGenerator mf_ul_h21_generator = { - .name = "Mifare Ultralight EV1 H21", - .generator_func = nfc_generate_mf_ul_h21, -}; - -static const NfcGenerator ntag203_generator = { - .name = "NTAG203", - .generator_func = nfc_generate_mf_ul_ntag203, -}; - -static const NfcGenerator ntag213_generator = { - .name = "NTAG213", - .generator_func = nfc_generate_ntag213, -}; - -static const NfcGenerator ntag215_generator = { - .name = "NTAG215", - .generator_func = nfc_generate_ntag215, -}; - -static const NfcGenerator ntag216_generator = { - .name = "NTAG216", - .generator_func = nfc_generate_ntag216, -}; - -static const NfcGenerator ntag_i2c_1k_generator = { - .name = "NTAG I2C 1k", - .generator_func = nfc_generate_ntag_i2c_1k, -}; - -static const NfcGenerator ntag_i2c_2k_generator = { - .name = "NTAG I2C 2k", - .generator_func = nfc_generate_ntag_i2c_2k, -}; - -static const NfcGenerator ntag_i2c_plus_1k_generator = { - .name = "NTAG I2C Plus 1k", - .generator_func = nfc_generate_ntag_i2c_plus_1k, -}; - -static const NfcGenerator ntag_i2c_plus_2k_generator = { - .name = "NTAG I2C Plus 2k", - .generator_func = nfc_generate_ntag_i2c_plus_2k, -}; - -static const NfcGenerator mifare_mini_generator = { - .name = "Mifare Mini", - .generator_func = nfc_generate_mf_mini, -}; - -static const NfcGenerator mifare_classic_1k_4b_uid_generator = { - .name = "Mifare Classic 1k 4byte UID", - .generator_func = nfc_generate_mf_classic_1k_4b_uid, -}; - -static const NfcGenerator mifare_classic_1k_7b_uid_generator = { - .name = "Mifare Classic 1k 7byte UID", - .generator_func = nfc_generate_mf_classic_1k_7b_uid, -}; - -static const NfcGenerator mifare_classic_4k_4b_uid_generator = { - .name = "Mifare Classic 4k 4byte UID", - .generator_func = nfc_generate_mf_classic_4k_4b_uid, -}; - -static const NfcGenerator mifare_classic_4k_7b_uid_generator = { - .name = "Mifare Classic 4k 7byte UID", - .generator_func = nfc_generate_mf_classic_4k_7b_uid, -}; - -const NfcGenerator* const nfc_generators[] = { - &mf_ul_generator, - &mf_ul_11_generator, - &mf_ul_h11_generator, - &mf_ul_21_generator, - &mf_ul_h21_generator, - &ntag203_generator, - &ntag213_generator, - &ntag215_generator, - &ntag216_generator, - &ntag_i2c_1k_generator, - &ntag_i2c_2k_generator, - &ntag_i2c_plus_1k_generator, - &ntag_i2c_plus_2k_generator, - &mifare_mini_generator, - &mifare_classic_1k_4b_uid_generator, - &mifare_classic_1k_7b_uid_generator, - &mifare_classic_4k_4b_uid_generator, - &mifare_classic_4k_7b_uid_generator, - NULL, -}; diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.h b/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.h deleted file mode 100644 index 5102d0bc309..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/nfc_generators.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "../nfc_device.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*NfcGeneratorFunc)(NfcDeviceData* data); - -typedef struct { - const char* name; - NfcGeneratorFunc generator_func; -} NfcGenerator; - -extern const NfcGenerator* const nfc_generators[]; - -void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type); - -void nfc_generate_mf_classic_ext( - NfcDeviceData* data, - uint8_t uid_len, - MfClassicType type, - bool random_uid, - uint8_t* uid); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.c b/base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.c deleted file mode 100644 index a3d82c67525..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.c +++ /dev/null @@ -1,265 +0,0 @@ -#include "reader_analyzer.h" -#include "../protocols/nfc_util.h" -#include "../protocols/mifare_classic.h" -#include - -#include "mfkey32.h" -#include "nfc_debug_pcap.h" -#include "nfc_debug_log.h" - -#define TAG "ReaderAnalyzer" - -#define READER_ANALYZER_MAX_BUFF_SIZE (1024) - -typedef struct { - bool reader_to_tag; - bool crc_dropped; - uint16_t len; -} ReaderAnalyzerHeader; - -typedef enum { - ReaderAnalyzerNfcDataMfClassic, -} ReaderAnalyzerNfcData; - -struct ReaderAnalyzer { - FurryHalNfcDevData nfc_data; - - bool alive; - FuriStreamBuffer* stream; - FuriThread* thread; - - ReaderAnalyzerParseDataCallback callback; - void* context; - - ReaderAnalyzerMode mode; - Mfkey32* mfkey32; - NfcDebugLog* debug_log; - NfcDebugPcap* pcap; -}; - -const FurryHalNfcDevData reader_analyzer_nfc_data[] = { - [ReaderAnalyzerNfcDataMfClassic] = - {.sak = 0x08, - .atqa = {0x44, 0x00}, - .interface = FurryHalNfcInterfaceRf, - .type = FurryHalNfcTypeA, - .uid_len = 7, - .uid = {0x04, 0x77, 0x70, 0x2A, 0x23, 0x4F, 0x80}, - .cuid = 0x2A234F80}, -}; - -void reader_analyzer_parse(ReaderAnalyzer* instance, uint8_t* buffer, size_t size) { - if(size < sizeof(ReaderAnalyzerHeader)) return; - - size_t bytes_i = 0; - while(bytes_i < size) { - ReaderAnalyzerHeader* header = (ReaderAnalyzerHeader*)&buffer[bytes_i]; - uint16_t len = header->len; - if(bytes_i + len > size) break; - bytes_i += sizeof(ReaderAnalyzerHeader); - if(instance->mfkey32) { - mfkey32_process_data( - instance->mfkey32, - &buffer[bytes_i], - len, - header->reader_to_tag, - header->crc_dropped); - } - if(instance->pcap) { - nfc_debug_pcap_process_data( - instance->pcap, &buffer[bytes_i], len, header->reader_to_tag, header->crc_dropped); - } - if(instance->debug_log) { - nfc_debug_log_process_data( - instance->debug_log, - &buffer[bytes_i], - len, - header->reader_to_tag, - header->crc_dropped); - } - bytes_i += len; - } -} - -int32_t reader_analyzer_thread(void* context) { - ReaderAnalyzer* reader_analyzer = context; - uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {}; - - while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) { - size_t ret = furi_stream_buffer_receive( - reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50); - if(ret) { - reader_analyzer_parse(reader_analyzer, buffer, ret); - } - } - - return 0; -} - -ReaderAnalyzer* reader_analyzer_alloc() { - ReaderAnalyzer* instance = malloc(sizeof(ReaderAnalyzer)); - - instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; - instance->alive = false; - instance->stream = - furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); - - instance->thread = - furi_thread_alloc_ex("ReaderAnalyzerWorker", 2048, reader_analyzer_thread, instance); - furi_thread_set_priority(instance->thread, FuriThreadPriorityLow); - - return instance; -} - -static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) { - furi_assert(context); - ReaderAnalyzer* instance = context; - - if(event == Mfkey32EventParamCollected) { - if(instance->callback) { - instance->callback(ReaderAnalyzerEventMfkeyCollected, instance->context); - } - } -} - -void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) { - furi_assert(instance); - - furi_stream_buffer_reset(instance->stream); - if(mode & ReaderAnalyzerModeDebugLog) { - instance->debug_log = nfc_debug_log_alloc(); - } - if(mode & ReaderAnalyzerModeMfkey) { - instance->mfkey32 = mfkey32_alloc(instance->nfc_data.cuid); - if(instance->mfkey32) { - mfkey32_set_callback(instance->mfkey32, reader_analyzer_mfkey_callback, instance); - } - } - if(mode & ReaderAnalyzerModeDebugPcap) { - instance->pcap = nfc_debug_pcap_alloc(); - } - - instance->alive = true; - furi_thread_start(instance->thread); -} - -void reader_analyzer_stop(ReaderAnalyzer* instance) { - furi_assert(instance); - - instance->alive = false; - furi_thread_join(instance->thread); - - if(instance->debug_log) { - nfc_debug_log_free(instance->debug_log); - instance->debug_log = NULL; - } - if(instance->mfkey32) { - mfkey32_free(instance->mfkey32); - instance->mfkey32 = NULL; - } - if(instance->pcap) { - nfc_debug_pcap_free(instance->pcap); - instance->pcap = NULL; - } -} - -void reader_analyzer_free(ReaderAnalyzer* instance) { - furi_assert(instance); - - reader_analyzer_stop(instance); - furi_thread_free(instance->thread); - furi_stream_buffer_free(instance->stream); - free(instance); -} - -void reader_analyzer_set_callback( - ReaderAnalyzer* instance, - ReaderAnalyzerParseDataCallback callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - - instance->callback = callback; - instance->context = context; -} - -NfcProtocol - reader_analyzer_guess_protocol(ReaderAnalyzer* instance, uint8_t* buff_rx, uint16_t len) { - furi_assert(instance); - furi_assert(buff_rx); - UNUSED(len); - NfcProtocol protocol = NfcDeviceProtocolUnknown; - - if((buff_rx[0] == 0x60) || (buff_rx[0] == 0x61)) { - protocol = NfcDeviceProtocolMifareClassic; - } - - return protocol; -} - -FurryHalNfcDevData* reader_analyzer_get_nfc_data(ReaderAnalyzer* instance) { - furi_assert(instance); - instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; - return &instance->nfc_data; -} - -void reader_analyzer_set_nfc_data(ReaderAnalyzer* instance, FurryHalNfcDevData* nfc_data) { - furi_assert(instance); - furi_assert(nfc_data); - - memcpy(&instance->nfc_data, nfc_data, sizeof(FurryHalNfcDevData)); -} - -static void reader_analyzer_write( - ReaderAnalyzer* instance, - uint8_t* data, - uint16_t len, - bool reader_to_tag, - bool crc_dropped) { - ReaderAnalyzerHeader header = { - .reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len}; - size_t data_sent = 0; - data_sent = furi_stream_buffer_send( - instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever); - if(data_sent != sizeof(ReaderAnalyzerHeader)) { - FURI_LOG_W(TAG, "Sent %zu out of %zu bytes", data_sent, sizeof(ReaderAnalyzerHeader)); - } - data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever); - if(data_sent != len) { - FURI_LOG_W(TAG, "Sent %zu out of %u bytes", data_sent, len); - } -} - -static void - reader_analyzer_write_rx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) { - UNUSED(crc_dropped); - ReaderAnalyzer* reader_analyzer = context; - uint16_t bytes = bits < 8 ? 1 : bits / 8; - reader_analyzer_write(reader_analyzer, data, bytes, false, crc_dropped); -} - -static void - reader_analyzer_write_tx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) { - UNUSED(crc_dropped); - ReaderAnalyzer* reader_analyzer = context; - uint16_t bytes = bits < 8 ? 1 : bits / 8; - reader_analyzer_write(reader_analyzer, data, bytes, true, crc_dropped); -} - -void reader_analyzer_prepare_tx_rx( - ReaderAnalyzer* instance, - FurryHalNfcTxRxContext* tx_rx, - bool is_picc) { - furi_assert(instance); - furi_assert(tx_rx); - - if(is_picc) { - tx_rx->sniff_tx = reader_analyzer_write_rx; - tx_rx->sniff_rx = reader_analyzer_write_tx; - } else { - tx_rx->sniff_rx = reader_analyzer_write_rx; - tx_rx->sniff_tx = reader_analyzer_write_tx; - } - - tx_rx->sniff_context = instance; -} diff --git a/base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.h b/base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.h deleted file mode 100644 index 5b9124a733d..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/helpers/reader_analyzer.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include "../nfc_device.h" - -typedef enum { - ReaderAnalyzerModeDebugLog = 0x01, - ReaderAnalyzerModeMfkey = 0x02, - ReaderAnalyzerModeDebugPcap = 0x04, -} ReaderAnalyzerMode; - -typedef enum { - ReaderAnalyzerEventMfkeyCollected, -} ReaderAnalyzerEvent; - -typedef struct ReaderAnalyzer ReaderAnalyzer; - -typedef void (*ReaderAnalyzerParseDataCallback)(ReaderAnalyzerEvent event, void* context); - -ReaderAnalyzer* reader_analyzer_alloc(); - -void reader_analyzer_free(ReaderAnalyzer* instance); - -void reader_analyzer_set_callback( - ReaderAnalyzer* instance, - ReaderAnalyzerParseDataCallback callback, - void* context); - -void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode); - -void reader_analyzer_stop(ReaderAnalyzer* instance); - -NfcProtocol - reader_analyzer_guess_protocol(ReaderAnalyzer* instance, uint8_t* buff_rx, uint16_t len); - -FurryHalNfcDevData* reader_analyzer_get_nfc_data(ReaderAnalyzer* instance); - -void reader_analyzer_set_nfc_data(ReaderAnalyzer* instance, FurryHalNfcDevData* nfc_data); - -void reader_analyzer_prepare_tx_rx( - ReaderAnalyzer* instance, - FurryHalNfcTxRxContext* tx_rx, - bool is_picc); diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_device.c b/base_pack/mifare_nested/lib/nfclegacy/nfc_device.c index 47dcea74e20..ee9f1bcd917 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_device.c +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_device.c @@ -18,7 +18,6 @@ static const uint32_t nfc_keys_file_version = 1; // Protocols format versions static const uint32_t nfc_mifare_classic_data_format_version = 2; -static const uint32_t nfc_mifare_ultralight_data_format_version = 1; NfcDevice* nfc_device_alloc() { NfcDevice* nfc_dev = malloc(sizeof(NfcDevice)); @@ -47,16 +46,8 @@ void nfc_device_free(NfcDevice* nfc_dev) { static void nfc_device_prepare_format_string(NfcDevice* dev, FuriString* format_string) { if(dev->format == NfcDeviceSaveFormatUid) { furi_string_set(format_string, "UID"); - } else if(dev->format == NfcDeviceSaveFormatBankCard) { - furi_string_set(format_string, "Bank card"); - } else if(dev->format == NfcDeviceSaveFormatMifareUl) { - furi_string_set(format_string, nfc_mf_ul_type(dev->dev_data.mf_ul_data.type, true)); } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { furi_string_set(format_string, "Mifare Classic"); - } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { - furi_string_set(format_string, "Mifare DESFire"); - } else if(dev->format == NfcDeviceSaveFormatNfcV) { - furi_string_set(format_string, "ISO15693"); } else { furi_string_set(format_string, "Unknown"); } @@ -68,172 +59,14 @@ static bool nfc_device_parse_format_string(NfcDevice* dev, FuriString* format_st dev->dev_data.protocol = NfcDeviceProtocolUnknown; return true; } - if(furi_string_start_with_str(format_string, "Bank card")) { - dev->format = NfcDeviceSaveFormatBankCard; - dev->dev_data.protocol = NfcDeviceProtocolEMV; - return true; - } - // Check Mifare Ultralight types - for(MfUltralightType type = MfUltralightTypeUnknown; type < MfUltralightTypeNum; type++) { - if(furi_string_equal(format_string, nfc_mf_ul_type(type, true))) { - dev->format = NfcDeviceSaveFormatMifareUl; - dev->dev_data.protocol = NfcDeviceProtocolMifareUl; - dev->dev_data.mf_ul_data.type = type; - return true; - } - } + // Check Mifare if(furi_string_start_with_str(format_string, "Mifare Classic")) { dev->format = NfcDeviceSaveFormatMifareClassic; dev->dev_data.protocol = NfcDeviceProtocolMifareClassic; return true; } - if(furi_string_start_with_str(format_string, "Mifare DESFire")) { - dev->format = NfcDeviceSaveFormatMifareDesfire; - dev->dev_data.protocol = NfcDeviceProtocolMifareDesfire; - return true; - } - if(furi_string_start_with_str(format_string, "ISO15693")) { - dev->format = NfcDeviceSaveFormatNfcV; - dev->dev_data.protocol = NfcDeviceProtocolNfcV; - return true; - } - return false; -} - -static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { - bool saved = false; - MfUltralightData* data = &dev->dev_data.mf_ul_data; - FuriString* temp_str; - temp_str = furi_string_alloc(); - - // Save Mifare Ultralight specific data - do { - if(!flipper_format_write_comment_cstr(file, "Mifare Ultralight specific data")) break; - if(!flipper_format_write_uint32( - file, "Data format version", &nfc_mifare_ultralight_data_format_version, 1)) - break; - if(!flipper_format_write_hex(file, "Signature", data->signature, sizeof(data->signature))) - break; - if(!flipper_format_write_hex( - file, "Mifare version", (uint8_t*)&data->version, sizeof(data->version))) - break; - // Write conters and tearing flags data - bool counters_saved = true; - for(uint8_t i = 0; i < 3; i++) { - furi_string_printf(temp_str, "Counter %d", i); - if(!flipper_format_write_uint32( - file, furi_string_get_cstr(temp_str), &data->counter[i], 1)) { - counters_saved = false; - break; - } - furi_string_printf(temp_str, "Tearing %d", i); - if(!flipper_format_write_hex( - file, furi_string_get_cstr(temp_str), &data->tearing[i], 1)) { - counters_saved = false; - break; - } - } - if(!counters_saved) break; - // Write pages data - uint32_t pages_total = data->data_size / 4; - if(!flipper_format_write_uint32(file, "Pages total", &pages_total, 1)) break; - uint32_t pages_read = data->data_read / 4; - if(!flipper_format_write_uint32(file, "Pages read", &pages_read, 1)) break; - bool pages_saved = true; - for(uint16_t i = 0; i < data->data_size; i += 4) { - furi_string_printf(temp_str, "Page %d", i / 4); - if(!flipper_format_write_hex(file, furi_string_get_cstr(temp_str), &data->data[i], 4)) { - pages_saved = false; - break; - } - } - if(!pages_saved) break; - - // Write authentication counter - uint32_t auth_counter = data->curr_authlim; - if(!flipper_format_write_uint32(file, "Failed authentication attempts", &auth_counter, 1)) - break; - - saved = true; - } while(false); - - furi_string_free(temp_str); - return saved; -} - -bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { - bool parsed = false; - MfUltralightData* data = &dev->dev_data.mf_ul_data; - FuriString* temp_str; - temp_str = furi_string_alloc(); - uint32_t data_format_version = 0; - - do { - // Read Mifare Ultralight format version - if(!flipper_format_read_uint32(file, "Data format version", &data_format_version, 1)) { - if(!flipper_format_rewind(file)) break; - } - - // Read signature - if(!flipper_format_read_hex(file, "Signature", data->signature, sizeof(data->signature))) - break; - // Read Mifare version - if(!flipper_format_read_hex( - file, "Mifare version", (uint8_t*)&data->version, sizeof(data->version))) - break; - // Read counters and tearing flags - bool counters_parsed = true; - for(uint8_t i = 0; i < 3; i++) { - furi_string_printf(temp_str, "Counter %d", i); - if(!flipper_format_read_uint32( - file, furi_string_get_cstr(temp_str), &data->counter[i], 1)) { - counters_parsed = false; - break; - } - furi_string_printf(temp_str, "Tearing %d", i); - if(!flipper_format_read_hex( - file, furi_string_get_cstr(temp_str), &data->tearing[i], 1)) { - counters_parsed = false; - break; - } - } - if(!counters_parsed) break; - // Read pages - uint32_t pages_total = 0; - if(!flipper_format_read_uint32(file, "Pages total", &pages_total, 1)) break; - uint32_t pages_read = 0; - if(data_format_version < nfc_mifare_ultralight_data_format_version) { - pages_read = pages_total; - } else { - if(!flipper_format_read_uint32(file, "Pages read", &pages_read, 1)) break; - } - data->data_size = pages_total * 4; - data->data_read = pages_read * 4; - if(data->data_size > MF_UL_MAX_DUMP_SIZE || data->data_read > MF_UL_MAX_DUMP_SIZE) break; - bool pages_parsed = true; - for(uint16_t i = 0; i < pages_total; i++) { - furi_string_printf(temp_str, "Page %d", i); - if(!flipper_format_read_hex( - file, furi_string_get_cstr(temp_str), &data->data[i * 4], 4)) { - pages_parsed = false; - break; - } - } - if(!pages_parsed) break; - - // Read authentication counter - uint32_t auth_counter; - if(!flipper_format_read_uint32(file, "Failed authentication attempts", &auth_counter, 1)) - auth_counter = 0; - data->curr_authlim = auth_counter; - - data->auth_success = mf_ul_is_full_capture(data); - - parsed = true; - } while(false); - furi_string_free(temp_str); - return parsed; + return false; } static void nfc_device_write_mifare_classic_block( @@ -626,19 +459,17 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) { if(!flipper_format_write_comment_cstr(file, "UID is common for all formats")) break; if(!flipper_format_write_hex(file, "UID", data->uid, data->uid_len)) break; - if(dev->format != NfcDeviceSaveFormatNfcV) { - // Write ATQA, SAK - if(!flipper_format_write_comment_cstr(file, "ISO14443 specific fields")) break; - // Save ATQA in MSB order for correct companion apps display - uint8_t atqa[2] = {data->atqa[1], data->atqa[0]}; - if(!flipper_format_write_hex(file, "ATQA", atqa, 2)) break; - if(!flipper_format_write_hex(file, "SAK", &data->sak, 1)) break; - } + //if(dev->format != NfcDeviceSaveFormatNfcV) { + // Write ATQA, SAK + if(!flipper_format_write_comment_cstr(file, "ISO14443 specific fields")) break; + // Save ATQA in MSB order for correct companion apps display + uint8_t atqa[2] = {data->atqa[1], data->atqa[0]}; + if(!flipper_format_write_hex(file, "ATQA", atqa, 2)) break; + if(!flipper_format_write_hex(file, "SAK", &data->sak, 1)) break; + //} // Save more data if necessary - if(dev->format == NfcDeviceSaveFormatMifareUl) { - if(!nfc_device_save_mifare_ul_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { + if(dev->format == NfcDeviceSaveFormatMifareClassic) { // Save data if(!nfc_device_save_mifare_classic_data(file, dev)) break; // Save keys cache @@ -716,17 +547,17 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia if(!(data_cnt == 4 || data_cnt == 7 || data_cnt == 8)) break; data->uid_len = data_cnt; if(!flipper_format_read_hex(file, "UID", data->uid, data->uid_len)) break; - if(dev->format != NfcDeviceSaveFormatNfcV) { - if(version == version_with_lsb_atqa) { - if(!flipper_format_read_hex(file, "ATQA", data->atqa, 2)) break; - } else { - uint8_t atqa[2] = {}; - if(!flipper_format_read_hex(file, "ATQA", atqa, 2)) break; - data->atqa[0] = atqa[1]; - data->atqa[1] = atqa[0]; - } - if(!flipper_format_read_hex(file, "SAK", &data->sak, 1)) break; + //if(dev->format != NfcDeviceSaveFormatNfcV) { + if(version == version_with_lsb_atqa) { + if(!flipper_format_read_hex(file, "ATQA", data->atqa, 2)) break; + } else { + uint8_t atqa[2] = {}; + if(!flipper_format_read_hex(file, "ATQA", atqa, 2)) break; + data->atqa[0] = atqa[1]; + data->atqa[1] = atqa[0]; } + if(!flipper_format_read_hex(file, "SAK", &data->sak, 1)) break; + //} // Load CUID uint8_t* cuid_start = data->uid; if(data->uid_len == 7) { @@ -735,9 +566,7 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia data->cuid = (cuid_start[0] << 24) | (cuid_start[1] << 16) | (cuid_start[2] << 8) | (cuid_start[3]); // Parse other data - if(dev->format == NfcDeviceSaveFormatMifareUl) { - if(!nfc_device_load_mifare_ul_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { + if(dev->format == NfcDeviceSaveFormatMifareClassic) { if(!nfc_device_load_mifare_classic_data(file, dev)) break; } parsed = true; @@ -782,8 +611,6 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog) { void nfc_device_data_clear(NfcDeviceData* dev_data) { if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { memset(&dev_data->mf_classic_data, 0, sizeof(MfClassicData)); - } else if(dev_data->protocol == NfcDeviceProtocolMifareUl) { - mf_ul_reset(&dev_data->mf_ul_data); } memset(&dev_data->nfc_data, 0, sizeof(FurryHalNfcDevData)); diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_device.h b/base_pack/mifare_nested/lib/nfclegacy/nfc_device.h index ebfcdaa6282..3b1b468e551 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_device.h +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_device.h @@ -7,7 +7,6 @@ #include "./furi_hal_nfc.h" #include "helpers/mf_classic_dict.h" -#include "protocols/mifare_ultralight.h" #include "protocols/mifare_classic.h" #ifdef __cplusplus @@ -26,20 +25,12 @@ typedef void (*NfcLoadingCallback)(void* context, bool state); typedef enum { NfcDeviceProtocolUnknown, - NfcDeviceProtocolEMV, - NfcDeviceProtocolMifareUl, NfcDeviceProtocolMifareClassic, - NfcDeviceProtocolMifareDesfire, - NfcDeviceProtocolNfcV } NfcProtocol; typedef enum { NfcDeviceSaveFormatUid, - NfcDeviceSaveFormatBankCard, - NfcDeviceSaveFormatMifareUl, NfcDeviceSaveFormatMifareClassic, - NfcDeviceSaveFormatMifareDesfire, - NfcDeviceSaveFormatNfcV, } NfcDeviceSaveFormat; typedef struct { @@ -55,9 +46,6 @@ typedef struct { typedef enum { NfcReadModeAuto, NfcReadModeMfClassic, - NfcReadModeMfUltralight, - NfcReadModeMfDesfire, - NfcReadModeEMV, NfcReadModeNFCA, } NfcReadMode; @@ -68,10 +56,8 @@ typedef struct { union { NfcReaderRequestData reader_data; NfcMfClassicDictAttackData mf_classic_dict_attack_data; - MfUltralightAuth mf_ul_auth; }; union { - MfUltralightData mf_ul_data; MfClassicData mf_classic_data; }; FuriString* parsed_data; diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_types.c b/base_pack/mifare_nested/lib/nfclegacy/nfc_types.c index c3ebb7a4636..34a42145db6 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_types.c +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_types.c @@ -15,47 +15,13 @@ const char* nfc_get_dev_type(FurryHalNfcType type) { } const char* nfc_guess_protocol(NfcProtocol protocol) { - if(protocol == NfcDeviceProtocolEMV) { - return "EMV bank card"; - } else if(protocol == NfcDeviceProtocolMifareUl) { - return "Mifare Ultral/NTAG"; - } else if(protocol == NfcDeviceProtocolMifareClassic) { + if(protocol == NfcDeviceProtocolMifareClassic) { return "Mifare Classic"; - } else if(protocol == NfcDeviceProtocolMifareDesfire) { - return "Mifare DESFire"; } else { return "Unrecognized"; } } -const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) { - if(type == MfUltralightTypeNTAG213) { - return "NTAG213"; - } else if(type == MfUltralightTypeNTAG215) { - return "NTAG215"; - } else if(type == MfUltralightTypeNTAG216) { - return "NTAG216"; - } else if(type == MfUltralightTypeNTAGI2C1K) { - return "NTAG I2C 1K"; - } else if(type == MfUltralightTypeNTAGI2C2K) { - return "NTAG I2C 2K"; - } else if(type == MfUltralightTypeNTAGI2CPlus1K) { - return "NTAG I2C Plus 1K"; - } else if(type == MfUltralightTypeNTAGI2CPlus2K) { - return "NTAG I2C Plus 2K"; - } else if(type == MfUltralightTypeNTAG203) { - return "NTAG203"; - } else if(type == MfUltralightTypeULC) { - return "Mifare Ultralight C"; - } else if(type == MfUltralightTypeUL11 && full_name) { - return "Mifare Ultralight 11"; - } else if(type == MfUltralightTypeUL21 && full_name) { - return "Mifare Ultralight 21"; - } else { - return "Mifare Ultralight"; - } -} - const char* nfc_mf_classic_type(MfClassicType type) { if(type == MfClassicTypeMini) { return "Mifare Mini 0.3K"; diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_types.h b/base_pack/mifare_nested/lib/nfclegacy/nfc_types.h index 4cdfac50c4e..99506ac4862 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_types.h +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_types.h @@ -10,8 +10,6 @@ const char* nfc_get_dev_type(FurryHalNfcType type); const char* nfc_guess_protocol(NfcProtocol protocol); -const char* nfc_mf_ul_type(MfUltralightType type, bool full_name); - const char* nfc_mf_classic_type(MfClassicType type); #ifdef __cplusplus diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.c b/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.c index aebd8b65908..db82a804dba 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.c +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.c @@ -23,8 +23,6 @@ NfcWorker* nfc_worker_alloc() { } nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); - nfc_worker->reader_analyzer = reader_analyzer_alloc(nfc_worker->storage); - return nfc_worker; } @@ -35,8 +33,6 @@ void nfc_worker_free(NfcWorker* nfc_worker) { furi_record_close(RECORD_STORAGE); - reader_analyzer_free(nfc_worker->reader_analyzer); - free(nfc_worker); } @@ -94,20 +90,14 @@ int32_t nfc_worker_task(void* context) { } } else if(nfc_worker->state == NfcWorkerStateUidEmulate) { nfc_worker_emulate_uid(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) { - nfc_worker_emulate_mf_ultralight(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { nfc_worker_emulate_mf_classic(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateMfClassicWrite) { nfc_worker_write_mf_classic(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateMfClassicUpdate) { nfc_worker_update_mf_classic(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) { - nfc_worker_mf_ultralight_read_auth(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) { nfc_worker_mf_classic_dict_attack(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateAnalyzeReader) { - nfc_worker_analyze_reader(nfc_worker); } furry_hal_nfc_sleep(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); @@ -115,43 +105,10 @@ int32_t nfc_worker_task(void* context) { return 0; } -static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FurryHalNfcTxRxContext* tx_rx) { - bool read_success = false; - MfUltralightReader reader = {}; - MfUltralightData data = {}; - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - - do { - furry_hal_nfc_sleep(); - - // Otherwise, try to read as usual - if(!furry_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 200)) break; - if(!mf_ul_read_card(tx_rx, &reader, &data)) break; - // Copy data - nfc_worker->dev_data->mf_ul_data = data; - read_success = true; - } while(false); - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } - - return read_success; -} - static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FurryHalNfcTxRxContext* tx_rx) { furi_assert(nfc_worker->callback); bool read_success = false; - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - do { // Try to read card with key cache FURI_LOG_I(TAG, "Search for key cache ..."); @@ -166,9 +123,6 @@ static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FurryHalNfcTxRxCon } } while(false); - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } return read_success; } @@ -177,11 +131,7 @@ static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FurryHalNfcTxRxContext* bool card_read = false; furry_hal_nfc_sleep(); - if(mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - FURI_LOG_I(TAG, "Mifare Ultralight / NTAG detected"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl; - card_read = nfc_worker_read_mf_ultralight(nfc_worker, tx_rx); - } else if(mf_classic_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + if(mf_classic_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { FURI_LOG_I(TAG, "Mifare Classic detected"); nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; nfc_worker->dev_data->mf_classic_data.type = @@ -219,18 +169,9 @@ void nfc_worker_read(NfcWorker* nfc_worker) { card_not_detected_notified = false; if(nfc_data->type == FurryHalNfcTypeA) { if(nfc_worker_read_nfca(nfc_worker, &tx_rx)) { - if(dev_data->protocol == NfcDeviceProtocolMifareUl) { - event = NfcWorkerEventReadMfUltralight; - break; - } else if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { + if(dev_data->protocol == NfcDeviceProtocolMifareClassic) { event = NfcWorkerEventReadMfClassicDone; break; - } else if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) { - event = NfcWorkerEventReadMfDesfire; - break; - } else if(dev_data->protocol == NfcDeviceProtocolEMV) { - event = NfcWorkerEventReadBankCard; - break; } else if(dev_data->protocol == NfcDeviceProtocolUnknown) { event = NfcWorkerEventReadUidNfcA; break; @@ -298,13 +239,6 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) { event = NfcWorkerEventReadMfClassicDictAttackRequired; break; } - } else if(read_mode == NfcReadModeMfUltralight) { - FURI_LOG_I(TAG, "Mifare Ultralight / NTAG"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl; - if(nfc_worker_read_mf_ultralight(nfc_worker, &tx_rx)) { - event = NfcWorkerEventReadMfUltralight; - break; - } } else if(read_mode == NfcReadModeNFCA) { nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; event = NfcWorkerEventReadUidNfcA; @@ -351,50 +285,6 @@ void nfc_worker_emulate_uid(NfcWorker* nfc_worker) { } } -void nfc_worker_mf_ultralight_auth_received_callback(MfUltralightAuth auth, void* context) { - furi_assert(context); - - NfcWorker* nfc_worker = context; - nfc_worker->dev_data->mf_ul_auth = auth; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventMfUltralightPwdAuth, nfc_worker->context); - } -} - -void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) { - FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - MfUltralightEmulator emulator = {}; - mf_ul_prepare_emulation(&emulator, &nfc_worker->dev_data->mf_ul_data); - - // TODO rework with reader analyzer - emulator.auth_received_callback = nfc_worker_mf_ultralight_auth_received_callback; - emulator.context = nfc_worker; - - rfal_platform_spi_acquire(); - - while(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) { - mf_ul_reset_emulation(&emulator, true); - furry_hal_nfc_emulate_nfca( - nfc_data->uid, - nfc_data->uid_len, - nfc_data->atqa, - nfc_data->sak, - mf_ul_prepare_emulation_response, - &emulator, - 5000); - // Check if data was modified - if(emulator.data_changed) { - nfc_worker->dev_data->mf_ul_data = emulator.data; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - emulator.data_changed = false; - } - } - - rfal_platform_spi_release(); -} - static bool nfc_worker_mf_get_b_key_from_sector_trailer( FurryHalNfcTxRxContext* tx_rx, uint16_t sector, @@ -642,330 +532,3 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context); } } - -void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) { - FurryHalNfcTxRxContext tx_rx = {}; - FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - MfClassicEmulator emulator = { - .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), - .data = nfc_worker->dev_data->mf_classic_data, - .data_changed = false, - }; - NfcaSignal* nfca_signal = nfca_signal_alloc(); - tx_rx.nfca_signal = nfca_signal; - - rfal_platform_spi_acquire(); - - furry_hal_nfc_listen_start(nfc_data); - while(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { //-V1044 - if(furry_hal_nfc_listen_rx(&tx_rx, 300)) { - if(!mf_classic_emulator(&emulator, &tx_rx, false)) { - furry_hal_nfc_listen_start(nfc_data); - } - } - } - if(emulator.data_changed) { - nfc_worker->dev_data->mf_classic_data = emulator.data; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - emulator.data_changed = false; - } - - nfca_signal_free(nfca_signal); - - rfal_platform_spi_release(); -} - -void nfc_worker_write_mf_classic(NfcWorker* nfc_worker) { - FurryHalNfcTxRxContext tx_rx = {}; - bool card_found_notified = false; - FurryHalNfcDevData nfc_data = {}; - MfClassicData* src_data = &nfc_worker->dev_data->mf_classic_data; - MfClassicData dest_data = *src_data; - - while(nfc_worker->state == NfcWorkerStateMfClassicWrite) { - if(furry_hal_nfc_detect(&nfc_data, 200)) { - if(!card_found_notified) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - card_found_notified = true; - } - furry_hal_nfc_sleep(); - - FURI_LOG_I(TAG, "Check low level nfc data"); - if(memcmp(&nfc_data, &nfc_worker->dev_data->nfc_data, sizeof(FurryHalNfcDevData)) != - 0) { - FURI_LOG_E(TAG, "Wrong card"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - FURI_LOG_I(TAG, "Check mf classic type"); - MfClassicType type = - mf_classic_get_classic_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak); - if(type != nfc_worker->dev_data->mf_classic_data.type) { - FURI_LOG_E(TAG, "Wrong mf classic type"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - // Set blocks not read - mf_classic_set_sector_data_not_read(&dest_data); - FURI_LOG_I(TAG, "Updating card sectors"); - uint8_t total_sectors = mf_classic_get_total_sectors_num(type); - bool write_success = true; - for(uint8_t i = 0; i < total_sectors; i++) { - FURI_LOG_I(TAG, "Reading sector %d", i); - mf_classic_read_sector(&tx_rx, &dest_data, i); - bool old_data_read = mf_classic_is_sector_data_read(src_data, i); - bool new_data_read = mf_classic_is_sector_data_read(&dest_data, i); - if(old_data_read != new_data_read) { - FURI_LOG_E(TAG, "Failed to update sector %d", i); - write_success = false; - break; - } - if(nfc_worker->state != NfcWorkerStateMfClassicWrite) break; - if(!mf_classic_write_sector(&tx_rx, &dest_data, src_data, i)) { - FURI_LOG_E(TAG, "Failed to write %d sector", i); - write_success = false; - break; - } - } - if(nfc_worker->state != NfcWorkerStateMfClassicWrite) break; - if(write_success) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - break; - } else { - nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context); - break; - } - - } else { - if(card_found_notified) { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - card_found_notified = false; - } - } - furi_delay_ms(300); - } -} - -void nfc_worker_update_mf_classic(NfcWorker* nfc_worker) { - FurryHalNfcTxRxContext tx_rx = {}; - bool card_found_notified = false; - FurryHalNfcDevData nfc_data = {}; - MfClassicData* old_data = &nfc_worker->dev_data->mf_classic_data; - MfClassicData new_data = *old_data; - - while(nfc_worker->state == NfcWorkerStateMfClassicUpdate) { - if(furry_hal_nfc_detect(&nfc_data, 200)) { - if(!card_found_notified) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - card_found_notified = true; - } - furry_hal_nfc_sleep(); - - FURI_LOG_I(TAG, "Check low level nfc data"); - if(memcmp(&nfc_data, &nfc_worker->dev_data->nfc_data, sizeof(FurryHalNfcDevData)) != - 0) { - FURI_LOG_E(TAG, "Low level nfc data mismatch"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - FURI_LOG_I(TAG, "Check MF classic type"); - MfClassicType type = - mf_classic_get_classic_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak); - if(type != nfc_worker->dev_data->mf_classic_data.type) { - FURI_LOG_E(TAG, "MF classic type mismatch"); - nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context); - break; - } - - // Set blocks not read - mf_classic_set_sector_data_not_read(&new_data); - FURI_LOG_I(TAG, "Updating card sectors"); - uint8_t total_sectors = mf_classic_get_total_sectors_num(type); - bool update_success = true; - for(uint8_t i = 0; i < total_sectors; i++) { - FURI_LOG_I(TAG, "Reading sector %d", i); - mf_classic_read_sector(&tx_rx, &new_data, i); - bool old_data_read = mf_classic_is_sector_data_read(old_data, i); - bool new_data_read = mf_classic_is_sector_data_read(&new_data, i); - if(old_data_read != new_data_read) { - FURI_LOG_E(TAG, "Failed to update sector %d", i); - update_success = false; - break; - } - if(nfc_worker->state != NfcWorkerStateMfClassicUpdate) break; - } - if(nfc_worker->state != NfcWorkerStateMfClassicUpdate) break; - - // Check updated data - if(update_success) { - *old_data = new_data; - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - break; - } - } else { - if(card_found_notified) { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - card_found_notified = false; - } - } - furi_delay_ms(300); - } -} - -void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) { - furi_assert(nfc_worker); - furi_assert(nfc_worker->callback); - - MfUltralightData* data = &nfc_worker->dev_data->mf_ul_data; - FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - FurryHalNfcTxRxContext tx_rx = {}; - MfUltralightReader reader = {}; - mf_ul_reset(data); - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, &tx_rx, true); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - - uint32_t key = 0; - uint16_t pack = 0; - while(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) { - furry_hal_nfc_sleep(); - if(furry_hal_nfc_detect(nfc_data, 300) && nfc_data->type == FurryHalNfcTypeA) { - if(mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); - if(data->auth_method == MfUltralightAuthMethodManual || - data->auth_method == MfUltralightAuthMethodAuto) { - nfc_worker->callback(NfcWorkerEventMfUltralightPassKey, nfc_worker->context); - key = nfc_util_bytes2num(data->auth_key, 4); - } else if(data->auth_method == MfUltralightAuthMethodAmeebo) { - key = mf_ul_pwdgen_amiibo(nfc_data); - } else if(data->auth_method == MfUltralightAuthMethodXiaomi) { - key = mf_ul_pwdgen_xiaomi(nfc_data); - } else { - FURI_LOG_E(TAG, "Incorrect auth method"); - break; - } - - data->auth_success = mf_ultralight_authenticate(&tx_rx, key, &pack); - - if(!data->auth_success) { - // Reset card - furry_hal_nfc_sleep(); - if(!furry_hal_nfc_activate_nfca(300, NULL)) { - nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context); - break; - } - } - - mf_ul_read_card(&tx_rx, &reader, data); - if(data->auth_success) { - MfUltralightConfigPages* config_pages = mf_ultralight_get_config_pages(data); - if(config_pages != NULL) { - config_pages->auth_data.pwd.value = REVERSE_BYTES_U32(key); - config_pages->auth_data.pack.value = pack; - } - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - break; - } else { - nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context); - break; - } - } else { - nfc_worker->callback(NfcWorkerEventWrongCardDetected, nfc_worker->context); - furi_delay_ms(10); - } - } else { - nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); - furi_delay_ms(10); - } - } - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } -} - -static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* context) { - furi_assert(context); - NfcWorker* nfc_worker = context; - - if((nfc_worker->state == NfcWorkerStateAnalyzeReader) && - (event == ReaderAnalyzerEventMfkeyCollected)) { - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context); - } - } -} - -void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { - furi_assert(nfc_worker); - furi_assert(nfc_worker->callback); - - FurryHalNfcTxRxContext tx_rx = {}; - - ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer; - FurryHalNfcDevData* nfc_data = NULL; - if(nfc_worker->dev_data->protocol == NfcDeviceProtocolMifareClassic) { - nfc_data = &nfc_worker->dev_data->nfc_data; - reader_analyzer_set_nfc_data(reader_analyzer, nfc_data); - } else { - nfc_data = reader_analyzer_get_nfc_data(reader_analyzer); - } - MfClassicEmulator emulator = { - .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), - .data = nfc_worker->dev_data->mf_classic_data, - .data_changed = false, - }; - NfcaSignal* nfca_signal = nfca_signal_alloc(); - tx_rx.nfca_signal = nfca_signal; - reader_analyzer_prepare_tx_rx(reader_analyzer, &tx_rx, true); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeMfkey); - reader_analyzer_set_callback(reader_analyzer, nfc_worker_reader_analyzer_callback, nfc_worker); - - rfal_platform_spi_acquire(); - - FURI_LOG_D(TAG, "Start reader analyzer"); - - uint8_t reader_no_data_received_cnt = 0; - bool reader_no_data_notified = true; - - while(nfc_worker->state == NfcWorkerStateAnalyzeReader) { - furry_hal_nfc_listen_start(nfc_data); - if(furry_hal_nfc_listen_rx(&tx_rx, 300)) { - if(reader_no_data_notified) { - nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context); - } - reader_no_data_received_cnt = 0; - reader_no_data_notified = false; - NfcProtocol protocol = - reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8); - if(protocol == NfcDeviceProtocolMifareClassic) { - if(!mf_classic_emulator(&emulator, &tx_rx, true)) { - furry_hal_nfc_listen_start(nfc_data); - } - } - } else { - reader_no_data_received_cnt++; - if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) { - nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context); - reader_no_data_received_cnt = 0; - reader_no_data_notified = true; - } - FURI_LOG_D(TAG, "No data from reader"); - continue; - } - furi_delay_ms(1); - } - - rfal_platform_spi_release(); - - reader_analyzer_stop(nfc_worker->reader_analyzer); - - nfca_signal_free(nfca_signal); -} diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.h b/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.h index 7733b791914..70469a489da 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.h +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_worker.h @@ -15,17 +15,10 @@ typedef enum { // Main worker states NfcWorkerStateRead, NfcWorkerStateUidEmulate, - NfcWorkerStateMfUltralightEmulate, NfcWorkerStateMfClassicEmulate, NfcWorkerStateMfClassicWrite, NfcWorkerStateMfClassicUpdate, - NfcWorkerStateReadMfUltralightReadAuth, NfcWorkerStateMfClassicDictAttack, - NfcWorkerStateAnalyzeReader, - NfcWorkerStateNfcVEmulate, - NfcWorkerStateNfcVUnlock, - NfcWorkerStateNfcVUnlockAndSave, - NfcWorkerStateNfcVSniff, // Debug NfcWorkerStateEmulateApdu, NfcWorkerStateField, @@ -42,13 +35,9 @@ typedef enum { NfcWorkerEventReadUidNfcV, NfcWorkerEventReadUidNfcF, NfcWorkerEventReadUidNfcA, - NfcWorkerEventReadMfUltralight, - NfcWorkerEventReadMfDesfire, NfcWorkerEventReadMfClassicDone, NfcWorkerEventReadMfClassicLoadKeyCache, NfcWorkerEventReadMfClassicDictAttackRequired, - NfcWorkerEventReadBankCard, - NfcWorkerEventReadNfcV, // Nfc worker common events NfcWorkerEventSuccess, @@ -71,17 +60,6 @@ typedef enum { // Write Mifare Classic events NfcWorkerEventWrongCard, - // Detect Reader events - NfcWorkerEventDetectReaderDetected, - NfcWorkerEventDetectReaderLost, - NfcWorkerEventDetectReaderMfkeyCollected, - - // Mifare Ultralight events - NfcWorkerEventMfUltralightPassKey, // NFC worker requesting manual key - NfcWorkerEventMfUltralightPwdAuth, // Reader sent auth command - NfcWorkerEventNfcVPassKey, // NFC worker requesting manual key - NfcWorkerEventNfcVCommandExecuted, - NfcWorkerEventNfcVContentChanged, } NfcWorkerEvent; typedef bool (*NfcWorkerCallback)(NfcWorkerEvent event, void* context); @@ -100,9 +78,6 @@ void nfc_worker_start( void* context); void nfc_worker_stop(NfcWorker* nfc_worker); -void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker); -void nfc_worker_nfcv_emulate(NfcWorker* nfc_worker); -void nfc_worker_nfcv_sniff(NfcWorker* nfc_worker); #ifdef __cplusplus } diff --git a/base_pack/mifare_nested/lib/nfclegacy/nfc_worker_i.h b/base_pack/mifare_nested/lib/nfclegacy/nfc_worker_i.h index d0fd50d9cd7..4dd6f94c7fe 100644 --- a/base_pack/mifare_nested/lib/nfclegacy/nfc_worker_i.h +++ b/base_pack/mifare_nested/lib/nfclegacy/nfc_worker_i.h @@ -7,10 +7,8 @@ #include "protocols/nfc_util.h" #include "protocols/mifare_common.h" -#include "protocols/mifare_ultralight.h" #include "protocols/mifare_classic.h" #include "protocols/nfca.h" -#include "helpers/reader_analyzer.h" struct NfcWorker { FuriThread* thread; @@ -23,8 +21,6 @@ struct NfcWorker { void* context; NfcWorkerState state; - - ReaderAnalyzer* reader_analyzer; }; void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state); @@ -37,8 +33,6 @@ void nfc_worker_read_type(NfcWorker* nfc_worker); void nfc_worker_emulate_uid(NfcWorker* nfc_worker); -void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker); - void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker); void nfc_worker_write_mf_classic(NfcWorker* nfc_worker); @@ -47,10 +41,4 @@ void nfc_worker_update_mf_classic(NfcWorker* nfc_worker); void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker); -void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker); - -void nfc_worker_mf_ul_auth_attack(NfcWorker* nfc_worker); - -void nfc_worker_emulate_apdu(NfcWorker* nfc_worker); - -void nfc_worker_analyze_reader(NfcWorker* nfc_worker); +void nfc_worker_emulate_apdu(NfcWorker* nfc_worker); \ No newline at end of file diff --git a/base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.c b/base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.c deleted file mode 100644 index 1074d437104..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.c +++ /dev/null @@ -1,1946 +0,0 @@ -#include -#include -#include "mifare_ultralight.h" -#include "nfc_util.h" -#include -#include "../furi_hal_nfc.h" - -#define TAG "MfUltralight" - -// Algorithms from: https://github.com/RfidResearchGroup/proxmark3/blob/0f6061c16f072372b7d4d381911f1542afbc3a69/common/generator.c#L110 -uint32_t mf_ul_pwdgen_xiaomi(FurryHalNfcDevData* data) { - uint8_t hash[20]; - mbedtls_sha1(data->uid, data->uid_len, hash); - - uint32_t pwd = 0; - pwd |= (hash[hash[0] % 20]) << 24; - pwd |= (hash[(hash[0] + 5) % 20]) << 16; - pwd |= (hash[(hash[0] + 13) % 20]) << 8; - pwd |= (hash[(hash[0] + 17) % 20]); - - return pwd; -} - -uint32_t mf_ul_pwdgen_amiibo(FurryHalNfcDevData* data) { - uint8_t* uid = data->uid; - - uint32_t pwd = 0; - pwd |= (uid[1] ^ uid[3] ^ 0xAA) << 24; - pwd |= (uid[2] ^ uid[4] ^ 0x55) << 16; - pwd |= (uid[3] ^ uid[5] ^ 0xAA) << 8; - pwd |= uid[4] ^ uid[6] ^ 0x55; - - return pwd; -} - -bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { - if((ATQA0 == 0x44) && (ATQA1 == 0x00) && (SAK == 0x00)) { - return true; - } - return false; -} - -void mf_ul_reset(MfUltralightData* data) { - furi_assert(data); - data->type = MfUltralightTypeUnknown; - memset(&data->version, 0, sizeof(MfUltralightVersion)); - memset(data->signature, 0, sizeof(data->signature)); - memset(data->counter, 0, sizeof(data->counter)); - memset(data->tearing, 0, sizeof(data->tearing)); - memset(data->data, 0, sizeof(data->data)); - data->data_size = 0; - data->data_read = 0; - data->curr_authlim = 0; - data->auth_success = false; -} - -static MfUltralightFeatures mf_ul_get_features(MfUltralightType type) { - switch(type) { - case MfUltralightTypeUL11: - case MfUltralightTypeUL21: - return MfUltralightSupportFastRead | MfUltralightSupportCompatWrite | - MfUltralightSupportReadCounter | MfUltralightSupportIncrCounter | - MfUltralightSupportAuth | MfUltralightSupportSignature | - MfUltralightSupportTearingFlags | MfUltralightSupportVcsl; - case MfUltralightTypeNTAG213: - case MfUltralightTypeNTAG215: - case MfUltralightTypeNTAG216: - return MfUltralightSupportFastRead | MfUltralightSupportCompatWrite | - MfUltralightSupportReadCounter | MfUltralightSupportAuth | - MfUltralightSupportSignature | MfUltralightSupportSingleCounter | - MfUltralightSupportAsciiMirror; - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2C2K: - return MfUltralightSupportFastRead | MfUltralightSupportSectorSelect; - case MfUltralightTypeNTAGI2CPlus1K: - case MfUltralightTypeNTAGI2CPlus2K: - return MfUltralightSupportFastRead | MfUltralightSupportAuth | - MfUltralightSupportFastWrite | MfUltralightSupportSignature | - MfUltralightSupportSectorSelect; - case MfUltralightTypeNTAG203: - return MfUltralightSupportCompatWrite | MfUltralightSupportCounterInMemory; - case MfUltralightTypeULC: - return MfUltralightSupportCompatWrite | MfUltralightSupport3DesAuth; - default: - // Assumed original MFUL 512-bit - return MfUltralightSupportCompatWrite; - } -} - -static void mf_ul_set_default_version(MfUltralightReader* reader, MfUltralightData* data) { - data->type = MfUltralightTypeUnknown; - reader->pages_to_read = 16; -} - -static void mf_ul_set_version_ntag203(MfUltralightReader* reader, MfUltralightData* data) { - data->type = MfUltralightTypeNTAG203; - reader->pages_to_read = 42; -} - -static void mf_ul_set_version_ulc(MfUltralightReader* reader, MfUltralightData* data) { - data->type = MfUltralightTypeULC; - reader->pages_to_read = 48; -} - -bool mf_ultralight_read_version( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data) { - bool version_read = false; - - do { - FURI_LOG_D(TAG, "Reading version"); - tx_rx->tx_data[0] = MF_UL_GET_VERSION_CMD; - tx_rx->tx_bits = 8; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(!furry_hal_nfc_tx_rx(tx_rx, 50) || tx_rx->rx_bits != 64) { - FURI_LOG_D(TAG, "Failed reading version"); - mf_ul_set_default_version(reader, data); - furry_hal_nfc_sleep(); - furry_hal_nfc_activate_nfca(300, NULL); - break; - } - MfUltralightVersion* version = (MfUltralightVersion*)tx_rx->rx_data; - data->version = *version; - if(version->storage_size == 0x0B || version->storage_size == 0x00) { - data->type = MfUltralightTypeUL11; - reader->pages_to_read = 20; - } else if(version->storage_size == 0x0E) { - data->type = MfUltralightTypeUL21; - reader->pages_to_read = 41; - } else if(version->storage_size == 0x0F) { - data->type = MfUltralightTypeNTAG213; - reader->pages_to_read = 45; - } else if(version->storage_size == 0x11) { - data->type = MfUltralightTypeNTAG215; - reader->pages_to_read = 135; - } else if(version->prod_subtype == 5 && version->prod_ver_major == 2) { - // NTAG I2C - bool known = false; - if(version->prod_ver_minor == 1) { - if(version->storage_size == 0x13) { - data->type = MfUltralightTypeNTAGI2C1K; - reader->pages_to_read = 231; - known = true; - } else if(version->storage_size == 0x15) { - data->type = MfUltralightTypeNTAGI2C2K; - reader->pages_to_read = 485; - known = true; - } - } else if(version->prod_ver_minor == 2) { - if(version->storage_size == 0x13) { - data->type = MfUltralightTypeNTAGI2CPlus1K; - reader->pages_to_read = 236; - known = true; - } else if(version->storage_size == 0x15) { - data->type = MfUltralightTypeNTAGI2CPlus2K; - reader->pages_to_read = 492; - known = true; - } - } - - if(!known) { - mf_ul_set_default_version(reader, data); - } - } else if(version->storage_size == 0x13) { - data->type = MfUltralightTypeNTAG216; - reader->pages_to_read = 231; - } else { - mf_ul_set_default_version(reader, data); - break; - } - version_read = true; - } while(false); - - reader->supported_features = mf_ul_get_features(data->type); - return version_read; -} - -bool mf_ultralight_authenticate(FurryHalNfcTxRxContext* tx_rx, uint32_t key, uint16_t* pack) { - furi_assert(pack); - bool authenticated = false; - - do { - FURI_LOG_D(TAG, "Authenticating"); - tx_rx->tx_data[0] = MF_UL_PWD_AUTH; - nfc_util_num2bytes(key, 4, &tx_rx->tx_data[1]); - tx_rx->tx_bits = 40; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(!furry_hal_nfc_tx_rx(tx_rx, 50)) { - FURI_LOG_D(TAG, "Tag did not respond to authentication"); - break; - } - - // PACK - if(tx_rx->rx_bits < 2 * 8) { - FURI_LOG_D(TAG, "Authentication failed"); - break; - } - - *pack = (tx_rx->rx_data[1] << 8) | tx_rx->rx_data[0]; - - FURI_LOG_I(TAG, "Auth success. Password: %08lX. PACK: %04X", key, *pack); - authenticated = true; - } while(false); - - return authenticated; -} - -static int16_t mf_ultralight_page_addr_to_tag_addr(uint8_t sector, uint8_t page) { - return sector * 256 + page; -} - -static int16_t mf_ultralight_ntag_i2c_addr_lin_to_tag_1k( - int16_t linear_address, - uint8_t* sector, - int16_t* valid_pages) { - // 0 - 226: sector 0 - // 227 - 228: config registers - // 229 - 230: session registers - - if(linear_address > 230) { - *valid_pages = 0; - return -1; - } else if(linear_address >= 229) { - *sector = 3; - *valid_pages = 2 - (linear_address - 229); - return linear_address - 229 + 248; - } else if(linear_address >= 227) { - *sector = 0; - *valid_pages = 2 - (linear_address - 227); - return linear_address - 227 + 232; - } else { - *sector = 0; - *valid_pages = 227 - linear_address; - return linear_address; - } -} - -static int16_t mf_ultralight_ntag_i2c_addr_lin_to_tag_2k( - int16_t linear_address, - uint8_t* sector, - int16_t* valid_pages) { - // 0 - 255: sector 0 - // 256 - 480: sector 1 - // 481 - 482: config registers - // 483 - 484: session registers - - if(linear_address > 484) { - *valid_pages = 0; - return -1; - } else if(linear_address >= 483) { - *sector = 3; - *valid_pages = 2 - (linear_address - 483); - return linear_address - 483 + 248; - } else if(linear_address >= 481) { - *sector = 1; - *valid_pages = 2 - (linear_address - 481); - return linear_address - 481 + 232; - } else if(linear_address >= 256) { - *sector = 1; - *valid_pages = 225 - (linear_address - 256); - return linear_address - 256; - } else { - *sector = 0; - *valid_pages = 256 - linear_address; - return linear_address; - } -} - -static int16_t mf_ultralight_ntag_i2c_addr_lin_to_tag_plus_1k( - int16_t linear_address, - uint8_t* sector, - int16_t* valid_pages) { - // 0 - 233: sector 0 + registers - // 234 - 235: session registers - - if(linear_address > 235) { - *valid_pages = 0; - return -1; - } else if(linear_address >= 234) { - *sector = 0; - *valid_pages = 2 - (linear_address - 234); - return linear_address - 234 + 236; - } else { - *sector = 0; - *valid_pages = 234 - linear_address; - return linear_address; - } -} - -static int16_t mf_ultralight_ntag_i2c_addr_lin_to_tag_plus_2k( - int16_t linear_address, - uint8_t* sector, - int16_t* valid_pages) { - // 0 - 233: sector 0 + registers - // 234 - 235: session registers - // 236 - 491: sector 1 - - if(linear_address > 491) { - *valid_pages = 0; - return -1; - } else if(linear_address >= 236) { - *sector = 1; - *valid_pages = 256 - (linear_address - 236); - return linear_address - 236; - } else if(linear_address >= 234) { - *sector = 0; - *valid_pages = 2 - (linear_address - 234); - return linear_address - 234 + 236; - } else { - *sector = 0; - *valid_pages = 234 - linear_address; - return linear_address; - } -} - -static int16_t mf_ultralight_ntag_i2c_addr_lin_to_tag( - MfUltralightData* data, - MfUltralightReader* reader, - int16_t linear_address, - uint8_t* sector, - int16_t* valid_pages) { - switch(data->type) { - case MfUltralightTypeNTAGI2C1K: - return mf_ultralight_ntag_i2c_addr_lin_to_tag_1k(linear_address, sector, valid_pages); - - case MfUltralightTypeNTAGI2C2K: - return mf_ultralight_ntag_i2c_addr_lin_to_tag_2k(linear_address, sector, valid_pages); - - case MfUltralightTypeNTAGI2CPlus1K: - return mf_ultralight_ntag_i2c_addr_lin_to_tag_plus_1k(linear_address, sector, valid_pages); - - case MfUltralightTypeNTAGI2CPlus2K: - return mf_ultralight_ntag_i2c_addr_lin_to_tag_plus_2k(linear_address, sector, valid_pages); - - default: - *sector = 0xff; - *valid_pages = reader->pages_to_read - linear_address; - return linear_address; - } -} - -static int16_t - mf_ultralight_ntag_i2c_addr_tag_to_lin_1k(uint8_t page, uint8_t sector, uint16_t* valid_pages) { - bool valid = false; - int16_t translated_page; - if(sector == 0) { - if(page <= 226) { - *valid_pages = 227 - page; - translated_page = page; - valid = true; - } else if(page >= 232 && page <= 233) { - *valid_pages = 2 - (page - 232); - translated_page = page - 232 + 227; - valid = true; - } - } else if(sector == 3) { - if(page >= 248 && page <= 249) { - *valid_pages = 2 - (page - 248); - translated_page = page - 248 + 229; - valid = true; - } - } - - if(!valid) { - *valid_pages = 0; - translated_page = -1; - } - return translated_page; -} - -static int16_t - mf_ultralight_ntag_i2c_addr_tag_to_lin_2k(uint8_t page, uint8_t sector, uint16_t* valid_pages) { - bool valid = false; - int16_t translated_page; - if(sector == 0) { - *valid_pages = 256 - page; - translated_page = page; - valid = true; - } else if(sector == 1) { - if(page <= 224) { - *valid_pages = 225 - page; - translated_page = 256 + page; - valid = true; - } else if(page >= 232 && page <= 233) { - *valid_pages = 2 - (page - 232); - translated_page = page - 232 + 481; - valid = true; - } - } else if(sector == 3) { - if(page >= 248 && page <= 249) { - *valid_pages = 2 - (page - 248); - translated_page = page - 248 + 483; - valid = true; - } - } - - if(!valid) { - *valid_pages = 0; - translated_page = -1; - } - return translated_page; -} - -static int16_t mf_ultralight_ntag_i2c_addr_tag_to_lin_plus_1k( - uint8_t page, - uint8_t sector, - uint16_t* valid_pages) { - bool valid = false; - int16_t translated_page; - if(sector == 0) { - if(page <= 233) { - *valid_pages = 234 - page; - translated_page = page; - valid = true; - } else if(page >= 236 && page <= 237) { - *valid_pages = 2 - (page - 236); - translated_page = page - 236 + 234; - valid = true; - } - } else if(sector == 3) { - if(page >= 248 && page <= 249) { - *valid_pages = 2 - (page - 248); - translated_page = page - 248 + 234; - valid = true; - } - } - - if(!valid) { - *valid_pages = 0; - translated_page = -1; - } - return translated_page; -} - -static int16_t mf_ultralight_ntag_i2c_addr_tag_to_lin_plus_2k( - uint8_t page, - uint8_t sector, - uint16_t* valid_pages) { - bool valid = false; - int16_t translated_page; - if(sector == 0) { - if(page <= 233) { - *valid_pages = 234 - page; - translated_page = page; - valid = true; - } else if(page >= 236 && page <= 237) { - *valid_pages = 2 - (page - 236); - translated_page = page - 236 + 234; - valid = true; - } - } else if(sector == 1) { - *valid_pages = 256 - page; - translated_page = page + 236; - valid = true; - } else if(sector == 3) { - if(page >= 248 && page <= 249) { - *valid_pages = 2 - (page - 248); - translated_page = page - 248 + 234; - valid = true; - } - } - - if(!valid) { - *valid_pages = 0; - translated_page = -1; - } - return translated_page; -} - -static int16_t mf_ultralight_ntag_i2c_addr_tag_to_lin( - MfUltralightData* data, - uint8_t page, - uint8_t sector, - uint16_t* valid_pages) { - switch(data->type) { - case MfUltralightTypeNTAGI2C1K: - return mf_ultralight_ntag_i2c_addr_tag_to_lin_1k(page, sector, valid_pages); - - case MfUltralightTypeNTAGI2C2K: - return mf_ultralight_ntag_i2c_addr_tag_to_lin_2k(page, sector, valid_pages); - - case MfUltralightTypeNTAGI2CPlus1K: - return mf_ultralight_ntag_i2c_addr_tag_to_lin_plus_1k(page, sector, valid_pages); - - case MfUltralightTypeNTAGI2CPlus2K: - return mf_ultralight_ntag_i2c_addr_tag_to_lin_plus_2k(page, sector, valid_pages); - - default: - *valid_pages = data->data_size / 4 - page; - return page; - } -} - -MfUltralightConfigPages* mf_ultralight_get_config_pages(MfUltralightData* data) { - if(data->type >= MfUltralightTypeUL11 && data->type <= MfUltralightTypeNTAG216) { - return (MfUltralightConfigPages*)&data->data[data->data_size - 4 * 4]; - } else if( - data->type >= MfUltralightTypeNTAGI2CPlus1K && - data->type <= MfUltralightTypeNTAGI2CPlus2K) { - return (MfUltralightConfigPages*)&data->data[0xe3 * 4]; //-V641 - } else { - return NULL; - } -} - -static uint16_t mf_ultralight_calc_auth_count(MfUltralightData* data) { - if(mf_ul_get_features(data->type) & MfUltralightSupportAuth) { - MfUltralightConfigPages* config = mf_ultralight_get_config_pages(data); - uint16_t scaled_authlim = config->access.authlim; - // NTAG I2C Plus uses 2^AUTHLIM attempts rather than the direct number - if(scaled_authlim > 0 && data->type >= MfUltralightTypeNTAGI2CPlus1K && - data->type <= MfUltralightTypeNTAGI2CPlus2K) { - scaled_authlim = 1 << scaled_authlim; - } - return scaled_authlim; - } - - return 0; -} - -// NTAG21x will NAK if NFC_CNT_EN unset, so preempt -static bool mf_ultralight_should_read_counters(MfUltralightData* data) { - if(data->type < MfUltralightTypeNTAG213 || data->type > MfUltralightTypeNTAG216) return true; - - MfUltralightConfigPages* config = mf_ultralight_get_config_pages(data); - return config->access.nfc_cnt_en; -} - -static bool mf_ultralight_sector_select(FurryHalNfcTxRxContext* tx_rx, uint8_t sector) { - FURI_LOG_D(TAG, "Selecting sector %u", sector); - tx_rx->tx_data[0] = MF_UL_SECTOR_SELECT; - tx_rx->tx_data[1] = 0xff; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(!furry_hal_nfc_tx_rx(tx_rx, 50)) { - FURI_LOG_D(TAG, "Failed to issue sector select command"); - return false; - } - - tx_rx->tx_data[0] = sector; - tx_rx->tx_data[1] = 0x00; - tx_rx->tx_data[2] = 0x00; - tx_rx->tx_data[3] = 0x00; - tx_rx->tx_bits = 32; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - // This is NOT a typo! The tag ACKs by not sending a response within 1ms. - if(furry_hal_nfc_tx_rx(tx_rx, 20)) { - // TODO: what gets returned when an actual NAK is received? - FURI_LOG_D(TAG, "Sector %u select NAK'd", sector); - return false; - } - - return true; -} - -bool mf_ultralight_read_pages_direct( - FurryHalNfcTxRxContext* tx_rx, - uint8_t start_index, - uint8_t* data) { - FURI_LOG_D(TAG, "Reading pages %d - %d", start_index, start_index + 3); - tx_rx->tx_data[0] = MF_UL_READ_CMD; - tx_rx->tx_data[1] = start_index; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(!furry_hal_nfc_tx_rx(tx_rx, 50) || tx_rx->rx_bits < 16 * 8) { - FURI_LOG_D(TAG, "Failed to read pages %d - %d", start_index, start_index + 3); - return false; - } - memcpy(data, tx_rx->rx_data, 16); //-V1086 - return true; -} - -bool mf_ultralight_read_pages( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data) { - uint8_t pages_read_cnt = 0; - uint8_t curr_sector_index = 0xff; - reader->pages_read = 0; - for(size_t i = 0; i < reader->pages_to_read; i += pages_read_cnt) { - uint8_t tag_sector; - int16_t valid_pages; - int16_t tag_page = mf_ultralight_ntag_i2c_addr_lin_to_tag( - data, reader, (int16_t)i, &tag_sector, &valid_pages); - - furi_assert(tag_page != -1); - if(curr_sector_index != tag_sector) { - if(!mf_ultralight_sector_select(tx_rx, tag_sector)) return false; - curr_sector_index = tag_sector; - } - - FURI_LOG_D( - TAG, "Reading pages %zu - %zu", i, i + (valid_pages > 4 ? 4 : valid_pages) - 1U); - tx_rx->tx_data[0] = MF_UL_READ_CMD; - tx_rx->tx_data[1] = tag_page; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - - if(!furry_hal_nfc_tx_rx(tx_rx, 50) || tx_rx->rx_bits < 16 * 8) { - FURI_LOG_D( - TAG, - "Failed to read pages %zu - %zu", - i, - i + (valid_pages > 4 ? 4 : valid_pages) - 1U); - break; - } - - if(valid_pages > 4) { - pages_read_cnt = 4; - } else { - pages_read_cnt = valid_pages; - } - reader->pages_read += pages_read_cnt; - memcpy(&data->data[i * 4], tx_rx->rx_data, pages_read_cnt * 4); - } - data->data_size = reader->pages_to_read * 4; - data->data_read = reader->pages_read * 4; - - return reader->pages_read > 0; -} - -bool mf_ultralight_fast_read_pages( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data) { - uint8_t curr_sector_index = 0xff; - reader->pages_read = 0; - while(reader->pages_read < reader->pages_to_read) { - uint8_t tag_sector; - int16_t valid_pages; - int16_t tag_page = mf_ultralight_ntag_i2c_addr_lin_to_tag( - data, reader, reader->pages_read, &tag_sector, &valid_pages); - - furi_assert(tag_page != -1); - if(curr_sector_index != tag_sector) { - if(!mf_ultralight_sector_select(tx_rx, tag_sector)) return false; - curr_sector_index = tag_sector; - } - - FURI_LOG_D( - TAG, "Reading pages %d - %d", reader->pages_read, reader->pages_read + valid_pages - 1); - tx_rx->tx_data[0] = MF_UL_FAST_READ_CMD; - tx_rx->tx_data[1] = tag_page; - tx_rx->tx_data[2] = valid_pages - 1; - tx_rx->tx_bits = 24; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - memcpy(&data->data[reader->pages_read * 4], tx_rx->rx_data, valid_pages * 4); - reader->pages_read += valid_pages; - data->data_size = reader->pages_read * 4; - } else { - FURI_LOG_D( - TAG, - "Failed to read pages %d - %d", - reader->pages_read, - reader->pages_read + valid_pages - 1); - break; - } - } - - return reader->pages_read == reader->pages_to_read; -} - -bool mf_ultralight_read_signature(FurryHalNfcTxRxContext* tx_rx, MfUltralightData* data) { - bool signature_read = false; - - FURI_LOG_D(TAG, "Reading signature"); - tx_rx->tx_data[0] = MF_UL_READ_SIG; - tx_rx->tx_data[1] = 0; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(furry_hal_nfc_tx_rx(tx_rx, 50)) { - memcpy(data->signature, tx_rx->rx_data, sizeof(data->signature)); - signature_read = true; - } else { - FURI_LOG_D(TAG, "Failed redaing signature"); - } - - return signature_read; -} - -bool mf_ultralight_read_counters(FurryHalNfcTxRxContext* tx_rx, MfUltralightData* data) { - uint8_t counter_read = 0; - - FURI_LOG_D(TAG, "Reading counters"); - bool is_single_counter = (mf_ul_get_features(data->type) & MfUltralightSupportSingleCounter) != - 0; - for(size_t i = is_single_counter ? 2 : 0; i < 3; i++) { - tx_rx->tx_data[0] = MF_UL_READ_CNT; - tx_rx->tx_data[1] = i; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(!furry_hal_nfc_tx_rx(tx_rx, 50)) { - FURI_LOG_D(TAG, "Failed to read %d counter", i); - break; - } - data->counter[i] = (tx_rx->rx_data[2] << 16) | (tx_rx->rx_data[1] << 8) | - tx_rx->rx_data[0]; - counter_read++; - } - - return counter_read == (is_single_counter ? 1 : 3); -} - -bool mf_ultralight_read_tearing_flags(FurryHalNfcTxRxContext* tx_rx, MfUltralightData* data) { - uint8_t flag_read = 0; - - FURI_LOG_D(TAG, "Reading tearing flags"); - for(size_t i = 0; i < 3; i++) { - tx_rx->tx_data[0] = MF_UL_CHECK_TEARING; - tx_rx->tx_data[1] = i; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - if(!furry_hal_nfc_tx_rx(tx_rx, 50)) { - FURI_LOG_D(TAG, "Failed to read %d tearing flag", i); - break; - } - data->tearing[i] = tx_rx->rx_data[0]; - flag_read++; - } - - return flag_read == 2; -} - -static bool mf_ul_probe_3des_auth(FurryHalNfcTxRxContext* tx_rx) { - tx_rx->tx_data[0] = MF_UL_AUTHENTICATE_1; - tx_rx->tx_data[1] = 0; - tx_rx->tx_bits = 16; - tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault; - bool rc = furry_hal_nfc_tx_rx(tx_rx, 50) && tx_rx->rx_bits == 9 * 8 && - tx_rx->rx_data[0] == 0xAF; - - // Reset just in case, we're not going to finish authenticating and need to if tag doesn't support auth - furry_hal_nfc_sleep(); - furry_hal_nfc_activate_nfca(300, NULL); - - return rc; -} - -bool mf_ul_read_card( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data) { - furi_assert(tx_rx); - furi_assert(reader); - furi_assert(data); - - bool card_read = false; - - // Read Mifare Ultralight version - if(mf_ultralight_read_version(tx_rx, reader, data)) { - if(reader->supported_features & MfUltralightSupportSignature) { - // Read Signature - mf_ultralight_read_signature(tx_rx, data); - } - } else { - uint8_t dummy[16]; - // No GET_VERSION command, check if AUTHENTICATE command available (detect UL C). - if(mf_ul_probe_3des_auth(tx_rx)) { - mf_ul_set_version_ulc(reader, data); - } else if(mf_ultralight_read_pages_direct(tx_rx, 41, dummy)) { - // No AUTHENTICATE, check for NTAG203 by reading last page (41) - mf_ul_set_version_ntag203(reader, data); - } else { - // We're really an original Mifare Ultralight, reset tag for safety - furry_hal_nfc_sleep(); - furry_hal_nfc_activate_nfca(300, NULL); - } - - reader->supported_features = mf_ul_get_features(data->type); - } - - card_read = mf_ultralight_read_pages(tx_rx, reader, data); - - if(card_read) { - if(reader->supported_features & MfUltralightSupportReadCounter && - mf_ultralight_should_read_counters(data)) { - mf_ultralight_read_counters(tx_rx, data); - } - if(reader->supported_features & MfUltralightSupportTearingFlags) { - mf_ultralight_read_tearing_flags(tx_rx, data); - } - data->curr_authlim = 0; - - if(reader->pages_read == reader->pages_to_read && - reader->supported_features & MfUltralightSupportAuth && !data->auth_success) { - MfUltralightConfigPages* config = mf_ultralight_get_config_pages(data); - if(config->access.authlim == 0) { - // Attempt to auth with default PWD - uint16_t pack; - data->auth_success = mf_ultralight_authenticate(tx_rx, MF_UL_DEFAULT_PWD, &pack); - if(data->auth_success) { - config->auth_data.pwd.value = MF_UL_DEFAULT_PWD; - config->auth_data.pack.value = pack; - } else { - furry_hal_nfc_sleep(); - furry_hal_nfc_activate_nfca(300, NULL); - } - } - } - } - - if(reader->pages_read != reader->pages_to_read) { - if(reader->supported_features & MfUltralightSupportAuth) { - // Probably password protected, fix AUTH0 and PROT so before AUTH0 - // can be written and since AUTH0 won't be readable, like on the - // original card - MfUltralightConfigPages* config = mf_ultralight_get_config_pages(data); - config->auth0 = reader->pages_read; - config->access.prot = true; - } - } - - return card_read; -} - -static void mf_ul_protect_auth_data_on_read_command_i2c( - uint8_t* tx_buff, - uint8_t start_page, - uint8_t end_page, - MfUltralightEmulator* emulator) { - if(emulator->data.type >= MfUltralightTypeNTAGI2CPlus1K) { - // Blank out PWD and PACK - if(start_page <= 229 && end_page >= 229) { - uint16_t offset = (229 - start_page) * 4; - uint8_t count = 4; - if(end_page >= 230) count += 2; - memset(&tx_buff[offset], 0, count); - } - - // Handle AUTH0 for sector 0 - if(!emulator->auth_success) { - if(emulator->config_cache.access.prot) { - uint8_t auth0 = emulator->config_cache.auth0; - if(auth0 < end_page) { - // start_page is always < auth0; otherwise is NAK'd already - uint8_t page_offset = auth0 - start_page; - uint8_t page_count = end_page - auth0; - memset(&tx_buff[page_offset * 4], 0, page_count * 4); - } - } - } - } -} - -static void mf_ul_ntag_i2c_fill_cross_area_read( - uint8_t* tx_buff, - uint8_t start_page, - uint8_t end_page, - MfUltralightEmulator* emulator) { - // For copying config or session registers in fast read - int16_t tx_page_offset; - int16_t data_page_offset; - uint8_t page_length; - bool apply = false; - MfUltralightType type = emulator->data.type; - if(emulator->curr_sector == 0) { - if(type == MfUltralightTypeNTAGI2C1K) { - if(start_page <= 233 && end_page >= 232) { - tx_page_offset = start_page - 232; - data_page_offset = 227; - page_length = 2; - apply = true; - } - } else if(type == MfUltralightTypeNTAGI2CPlus1K || type == MfUltralightTypeNTAGI2CPlus2K) { - if(start_page <= 237 && end_page >= 236) { - tx_page_offset = start_page - 236; - data_page_offset = 234; - page_length = 2; - apply = true; - } - } - } else if(emulator->curr_sector == 1) { - if(type == MfUltralightTypeNTAGI2C2K) { - if(start_page <= 233 && end_page >= 232) { - tx_page_offset = start_page - 232; - data_page_offset = 483; - page_length = 2; - apply = true; - } - } - } - - if(apply) { - while(tx_page_offset < 0 && page_length > 0) { //-V614 - ++tx_page_offset; - ++data_page_offset; - --page_length; - } - memcpy( - &tx_buff[tx_page_offset * 4], - &emulator->data.data[data_page_offset * 4], - page_length * 4); - } -} - -static bool mf_ul_check_auth(MfUltralightEmulator* emulator, uint8_t start_page, bool is_write) { - if(!emulator->auth_success) { - if(start_page >= emulator->config_cache.auth0 && - (emulator->config_cache.access.prot || is_write)) - return false; - } - - if(is_write && emulator->config_cache.access.cfglck) { - uint16_t config_start_page = emulator->page_num - 4; - if(start_page == config_start_page || start_page == config_start_page + 1) return false; - } - - return true; -} - -static bool mf_ul_ntag_i2c_plus_check_auth( - MfUltralightEmulator* emulator, - uint8_t start_page, - bool is_write) { - if(!emulator->auth_success) { - // Check NFC_PROT - if(emulator->curr_sector == 0 && (emulator->config_cache.access.prot || is_write)) { - if(start_page >= emulator->config_cache.auth0) return false; - } else if(emulator->curr_sector == 1) { - // We don't have to specifically check for type because this is done - // by address translator - uint8_t pt_i2c = emulator->data.data[231 * 4]; - // Check 2K_PROT - if(pt_i2c & 0x08) return false; - } - } - - if(emulator->curr_sector == 1) { - // Check NFC_DIS_SEC1 - if(emulator->config_cache.access.nfc_dis_sec1) return false; - } - - return true; -} - -static int16_t mf_ul_get_dynamic_lock_page_addr(MfUltralightData* data) { - switch(data->type) { - case MfUltralightTypeNTAG203: - return 0x28; - case MfUltralightTypeUL21: - case MfUltralightTypeNTAG213: - case MfUltralightTypeNTAG215: - case MfUltralightTypeNTAG216: - return data->data_size / 4 - 5; - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2CPlus1K: - case MfUltralightTypeNTAGI2CPlus2K: - return 0xe2; - case MfUltralightTypeNTAGI2C2K: - return 0x1e0; - default: - return -1; // No dynamic lock bytes - } -} - -// Returns true if page not locked -// write_page is tag address -static bool mf_ul_check_lock(MfUltralightEmulator* emulator, int16_t write_page) { - if(write_page < 2) return false; // Page 0-1 is always locked - if(write_page == 2) return true; // Page 2 does not have a lock flag - - // Check static lock bytes - if(write_page <= 15) { - uint16_t static_lock_bytes = emulator->data.data[10] | (emulator->data.data[11] << 8); - return (static_lock_bytes & (1 << write_page)) == 0; - } - - // Check dynamic lock bytes - - // Check max page - switch(emulator->data.type) { - case MfUltralightTypeNTAG203: - // Counter page can be locked and is after dynamic locks - if(write_page == 40) return true; - break; - case MfUltralightTypeUL21: - case MfUltralightTypeNTAG213: - case MfUltralightTypeNTAG215: - case MfUltralightTypeNTAG216: - if(write_page >= emulator->page_num - 5) return true; - break; - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2CPlus1K: - if(write_page > 225) return true; - break; - case MfUltralightTypeNTAGI2C2K: - if(write_page > 479) return true; - break; - case MfUltralightTypeNTAGI2CPlus2K: - if(write_page >= 226 && write_page <= 255) return true; - if(write_page >= 512) return true; - break; - default: - furi_crash("Unknown MFUL"); - return true; - } - - int16_t dynamic_lock_index = mf_ul_get_dynamic_lock_page_addr(&emulator->data); - if(dynamic_lock_index == -1) return true; - // Run address through converter because NTAG I2C 2K is special - uint16_t valid_pages; // unused - dynamic_lock_index = - mf_ultralight_ntag_i2c_addr_tag_to_lin( - &emulator->data, dynamic_lock_index & 0xff, dynamic_lock_index >> 8, &valid_pages) * - 4; - - uint16_t dynamic_lock_bytes = emulator->data.data[dynamic_lock_index] | - (emulator->data.data[dynamic_lock_index + 1] << 8); - uint8_t shift; - - switch(emulator->data.type) { - // low byte LSB range, MSB range - case MfUltralightTypeNTAG203: - if(write_page >= 16 && write_page <= 27) //-V560 - shift = (write_page - 16) / 4 + 1; - else if(write_page >= 28 && write_page <= 39) //-V560 - shift = (write_page - 28) / 4 + 5; - else if(write_page == 41) - shift = 12; - else { - furi_crash("Unknown MFUL"); - } - - break; - case MfUltralightTypeUL21: - case MfUltralightTypeNTAG213: - // 16-17, 30-31 - shift = (write_page - 16) / 2; - break; - case MfUltralightTypeNTAG215: - case MfUltralightTypeNTAG216: - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2CPlus1K: - // 16-31, 128-129 - // 16-31, 128-143 - shift = (write_page - 16) / 16; - break; - case MfUltralightTypeNTAGI2C2K: - // 16-47, 240-271 - shift = (write_page - 16) / 32; - break; - case MfUltralightTypeNTAGI2CPlus2K: - // 16-47, 256-271 - if(write_page >= 208 && write_page <= 225) - shift = 6; - else if(write_page >= 256 && write_page <= 271) - shift = 7; - else - shift = (write_page - 16) / 32; - break; - default: - furi_crash("Unknown MFUL"); - break; - } - - return (dynamic_lock_bytes & (1 << shift)) == 0; -} - -static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, FuriString* str) { - // Locals to improve readability - uint8_t mirror_page = emulator->config->mirror_page; - uint8_t mirror_byte = emulator->config->mirror.mirror_byte; - MfUltralightMirrorConf mirror_conf = emulator->config_cache.mirror.mirror_conf; - uint16_t last_user_page_index = emulator->page_num - 6; - bool uid_printed = false; - - if(mirror_conf == MfUltralightMirrorUid || mirror_conf == MfUltralightMirrorUidCounter) { - // UID range check - if(mirror_page < 4 || mirror_page > last_user_page_index - 3 || - (mirror_page == last_user_page_index - 3 && mirror_byte > 2)) { - if(mirror_conf == MfUltralightMirrorUid) return; - // NTAG21x has the peculiar behavior when UID+counter selected, if UID does not fit but - // counter will fit, it will actually mirror the counter - furi_string_cat(str, " "); - } else { - for(int i = 0; i < 3; ++i) { - furi_string_cat_printf(str, "%02X", emulator->data.data[i]); - } - // Skip BCC0 - for(int i = 4; i < 8; ++i) { - furi_string_cat_printf(str, "%02X", emulator->data.data[i]); - } - uid_printed = true; - } - - uint16_t next_byte_offset = mirror_page * 4 + mirror_byte + 14; - if(mirror_conf == MfUltralightMirrorUidCounter) ++next_byte_offset; - mirror_page = next_byte_offset / 4; - mirror_byte = next_byte_offset % 4; - } - - if(mirror_conf == MfUltralightMirrorCounter || mirror_conf == MfUltralightMirrorUidCounter) { - // Counter is only printed if counter enabled - if(emulator->config_cache.access.nfc_cnt_en) { - // Counter protection check - if(emulator->config_cache.access.nfc_cnt_pwd_prot && !emulator->auth_success) return; - // Counter range check - if(mirror_page < 4) return; - if(mirror_page > last_user_page_index - 1) return; - if(mirror_page == last_user_page_index - 1 && mirror_byte > 2) return; - - if(mirror_conf == MfUltralightMirrorUidCounter) - furi_string_cat(str, uid_printed ? "x" : " "); - - furi_string_cat_printf(str, "%06lX", emulator->data.counter[2]); - } - } -} - -static void mf_ul_increment_single_counter(MfUltralightEmulator* emulator) { - if(!emulator->read_counter_incremented && emulator->config_cache.access.nfc_cnt_en) { - if(emulator->data.counter[2] < 0xFFFFFF) { - ++emulator->data.counter[2]; - emulator->data_changed = true; - } - emulator->read_counter_incremented = true; - } -} - -static bool - mf_ul_emulate_ntag203_counter_write(MfUltralightEmulator* emulator, uint8_t* page_buff) { - // We'll reuse the existing counters for other NTAGs as staging - // Counter 0 stores original value, data is new value - uint32_t counter_value; - if(emulator->data.tearing[0] == MF_UL_TEARING_FLAG_DEFAULT) { - counter_value = emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] | - (emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] << 8); - } else { - // We've had a reset here, so load from original value - counter_value = emulator->data.counter[0]; - } - // Although the datasheet says increment by 0 is always possible, this is not the case on - // an actual tag. If the counter is at 0xFFFF, any writes are locked out. - if(counter_value == 0xFFFF) return false; - uint32_t increment = page_buff[0] | (page_buff[1] << 8); - if(counter_value == 0) { - counter_value = increment; - } else { - // Per datasheet specifying > 0x000F is supposed to NAK, but actual tag doesn't - increment &= 0x000F; - if(counter_value + increment > 0xFFFF) return false; - counter_value += increment; - } - // Commit to new value counter - emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] = (uint8_t)counter_value; - emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] = (uint8_t)(counter_value >> 8); - emulator->data.tearing[0] = MF_UL_TEARING_FLAG_DEFAULT; - if(counter_value == 0xFFFF) { - // Tag will lock out counter if final number is 0xFFFF, even if you try to roll it back - emulator->data.counter[1] = 0xFFFF; - } - emulator->data_changed = true; - return true; -} - -static void mf_ul_emulate_write( - MfUltralightEmulator* emulator, - int16_t tag_addr, - int16_t write_page, - uint8_t* page_buff) { - // Assumption: all access checks have been completed - - if(tag_addr == 2) { - // Handle static locks - uint16_t orig_static_locks = emulator->data.data[write_page * 4 + 2] | - (emulator->data.data[write_page * 4 + 3] << 8); - uint16_t new_static_locks = page_buff[2] | (page_buff[3] << 8); - if(orig_static_locks & 1) new_static_locks &= ~0x08; - if(orig_static_locks & 2) new_static_locks &= ~0xF0; - if(orig_static_locks & 4) new_static_locks &= 0xFF; - new_static_locks |= orig_static_locks; - page_buff[0] = emulator->data.data[write_page * 4]; - page_buff[1] = emulator->data.data[write_page * 4 + 1]; - page_buff[2] = new_static_locks & 0xff; - page_buff[3] = new_static_locks >> 8; - } else if(tag_addr == 3) { - // Handle OTP/capability container - *(uint32_t*)page_buff |= *(uint32_t*)&emulator->data.data[write_page * 4]; - } else if(tag_addr == mf_ul_get_dynamic_lock_page_addr(&emulator->data)) { - // Handle dynamic locks - if(emulator->data.type == MfUltralightTypeNTAG203) { - // NTAG203 lock bytes are a bit different from the others - uint8_t orig_page_lock_byte = emulator->data.data[write_page * 4]; - uint8_t orig_cnt_lock_byte = emulator->data.data[write_page * 4 + 1]; - uint8_t new_page_lock_byte = page_buff[0]; - uint8_t new_cnt_lock_byte = page_buff[1]; - - if(orig_page_lock_byte & 0x01) // Block lock bits 1-3 - new_page_lock_byte &= ~0x0E; - if(orig_page_lock_byte & 0x10) // Block lock bits 5-7 - new_page_lock_byte &= ~0xE0; - for(uint8_t i = 0; i < 4; ++i) { - if(orig_cnt_lock_byte & (1 << i)) // Block lock counter bit - new_cnt_lock_byte &= ~(1 << (4 + i)); - } - - new_page_lock_byte |= orig_page_lock_byte; - new_cnt_lock_byte |= orig_cnt_lock_byte; - page_buff[0] = new_page_lock_byte; - page_buff[1] = new_cnt_lock_byte; - } else { - uint16_t orig_locks = emulator->data.data[write_page * 4] | - (emulator->data.data[write_page * 4 + 1] << 8); - uint8_t orig_block_locks = emulator->data.data[write_page * 4 + 2]; - uint16_t new_locks = page_buff[0] | (page_buff[1] << 8); - uint8_t new_block_locks = page_buff[2]; - - int block_lock_count; - switch(emulator->data.type) { - case MfUltralightTypeUL21: - block_lock_count = 5; - break; - case MfUltralightTypeNTAG213: - block_lock_count = 6; - break; - case MfUltralightTypeNTAG215: - block_lock_count = 4; - break; - case MfUltralightTypeNTAG216: - case MfUltralightTypeNTAGI2C1K: - case MfUltralightTypeNTAGI2CPlus1K: - block_lock_count = 7; - break; - case MfUltralightTypeNTAGI2C2K: - case MfUltralightTypeNTAGI2CPlus2K: - block_lock_count = 8; - break; - default: - furi_crash("Unknown MFUL"); - break; - } - - for(int i = 0; i < block_lock_count; ++i) { - if(orig_block_locks & (1 << i)) new_locks &= ~(3 << (2 * i)); - } - - new_locks |= orig_locks; - new_block_locks |= orig_block_locks; - - page_buff[0] = new_locks & 0xff; - page_buff[1] = new_locks >> 8; - page_buff[2] = new_block_locks; - if(emulator->data.type >= MfUltralightTypeUL21 && //-V1016 - emulator->data.type <= MfUltralightTypeNTAG216) - page_buff[3] = MF_UL_TEARING_FLAG_DEFAULT; - else - page_buff[3] = 0; - } - } - - memcpy(&emulator->data.data[write_page * 4], page_buff, 4); - emulator->data_changed = true; -} - -bool mf_ul_emulation_supported(MfUltralightData* data) { - return data->type != MfUltralightTypeULC; -} - -void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle) { - emulator->comp_write_cmd_started = false; - emulator->sector_select_cmd_started = false; - emulator->curr_sector = 0; - emulator->ntag_i2c_plus_sector3_lockout = false; - emulator->auth_success = false; - if(is_power_cycle) { - if(emulator->config != NULL) emulator->config_cache = *emulator->config; - - if(emulator->supported_features & MfUltralightSupportSingleCounter) { - emulator->read_counter_incremented = false; - } - - if(emulator->data.type == MfUltralightTypeNTAG203) { - // Apply lockout if counter ever reached 0xFFFF - if(emulator->data.counter[1] == 0xFFFF) { - emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] = 0xFF; - emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] = 0xFF; - } - // Copy original counter value from data - emulator->data.counter[0] = - emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4] | - (emulator->data.data[MF_UL_NTAG203_COUNTER_PAGE * 4 + 1] << 8); - } - } else { - if(emulator->config != NULL) { - // ACCESS (less CFGLCK) and AUTH0 are updated when reactivated - // MIRROR_CONF is not; don't know about STRG_MOD_EN, but we're not using that anyway - emulator->config_cache.access.value = (emulator->config->access.value & 0xBF) | - (emulator->config_cache.access.value & 0x40); - emulator->config_cache.auth0 = emulator->config->auth0; - } - } - if(emulator->data.type == MfUltralightTypeNTAG203) { - // Mark counter as dirty - emulator->data.tearing[0] = 0; - } -} - -void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data) { - FURI_LOG_D(TAG, "Prepare emulation"); - emulator->data = *data; - emulator->supported_features = mf_ul_get_features(data->type); - emulator->config = mf_ultralight_get_config_pages(&emulator->data); - emulator->page_num = emulator->data.data_size / 4; - emulator->data_changed = false; - memset(&emulator->auth_attempt, 0, sizeof(MfUltralightAuth)); - mf_ul_reset_emulation(emulator, true); -} - -bool mf_ul_prepare_emulation_response( - uint8_t* buff_rx, - uint16_t buff_rx_len, - uint8_t* buff_tx, - uint16_t* buff_tx_len, - uint32_t* data_type, - void* context) { - furi_assert(context); - MfUltralightEmulator* emulator = context; - uint16_t tx_bytes = 0; - uint16_t tx_bits = 0; - bool command_parsed = false; - bool send_ack = false; - bool respond_nothing = false; - bool reset_idle = false; - -#ifdef FURI_DEBUG - FuriString* debug_buf; - debug_buf = furi_string_alloc(); - for(int i = 0; i < (buff_rx_len + 7) / 8; ++i) { - furi_string_cat_printf(debug_buf, "%02x ", buff_rx[i]); - } - furi_string_trim(debug_buf); - FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, furi_string_get_cstr(debug_buf)); - furi_string_reset(debug_buf); -#endif - - // Check composite commands - if(emulator->comp_write_cmd_started) { - if(buff_rx_len == 16 * 8) { - if(emulator->data.type == MfUltralightTypeNTAG203 && - emulator->comp_write_page_addr == MF_UL_NTAG203_COUNTER_PAGE) { - send_ack = mf_ul_emulate_ntag203_counter_write(emulator, buff_rx); - command_parsed = send_ack; - } else { - mf_ul_emulate_write( - emulator, - emulator->comp_write_page_addr, - emulator->comp_write_page_addr, - buff_rx); - send_ack = true; - command_parsed = true; - } - } - emulator->comp_write_cmd_started = false; - } else if(emulator->sector_select_cmd_started) { - if(buff_rx_len == 4 * 8) { - if(buff_rx[0] <= 0xFE) { - emulator->curr_sector = buff_rx[0] > 3 ? 0 : buff_rx[0]; - emulator->ntag_i2c_plus_sector3_lockout = false; - command_parsed = true; - respond_nothing = true; - FURI_LOG_D(TAG, "Changing sector to %d", emulator->curr_sector); - } - } - emulator->sector_select_cmd_started = false; - } else if(buff_rx_len >= 8) { - uint8_t cmd = buff_rx[0]; - if(cmd == MF_UL_GET_VERSION_CMD) { - if(emulator->data.type >= MfUltralightTypeUL11) { - if(buff_rx_len == 1 * 8) { - tx_bytes = sizeof(emulator->data.version); - memcpy(buff_tx, &emulator->data.version, tx_bytes); - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } - } else if(cmd == MF_UL_READ_CMD) { - if(buff_rx_len == (1 + 1) * 8) { - int16_t start_page = buff_rx[1]; - tx_bytes = 16; - if(emulator->data.type < MfUltralightTypeNTAGI2C1K) { - if(start_page < emulator->page_num) { - do { - uint8_t copied_pages = 0; - uint8_t src_page = start_page; - uint8_t last_page_plus_one = start_page + 4; - uint8_t pwd_page = emulator->page_num - 2; - FuriString* ascii_mirror = NULL; - size_t ascii_mirror_len = 0; - const char* ascii_mirror_cptr = NULL; - uint8_t ascii_mirror_curr_page = 0; - uint8_t ascii_mirror_curr_byte = 0; - if(last_page_plus_one > emulator->page_num) - last_page_plus_one = emulator->page_num; - if(emulator->supported_features & MfUltralightSupportAuth) { - if(!mf_ul_check_auth(emulator, start_page, false)) break; - if(!emulator->auth_success && emulator->config_cache.access.prot && - emulator->config_cache.auth0 < last_page_plus_one) - last_page_plus_one = emulator->config_cache.auth0; - } - if(emulator->supported_features & MfUltralightSupportSingleCounter) - mf_ul_increment_single_counter(emulator); - if(emulator->supported_features & MfUltralightSupportAsciiMirror && - emulator->config_cache.mirror.mirror_conf != - MfUltralightMirrorNone) { - ascii_mirror_curr_byte = emulator->config->mirror.mirror_byte; - ascii_mirror_curr_page = emulator->config->mirror_page; - // Try to avoid wasting time making mirror if we won't copy it - // Conservatively check with UID+counter mirror size - if(last_page_plus_one > ascii_mirror_curr_page && - start_page + 3 >= ascii_mirror_curr_page && - start_page <= ascii_mirror_curr_page + 6) { - ascii_mirror = furi_string_alloc(); - mf_ul_make_ascii_mirror(emulator, ascii_mirror); - ascii_mirror_len = furi_string_utf8_length(ascii_mirror); - ascii_mirror_cptr = furi_string_get_cstr(ascii_mirror); - // Move pointer to where it should be to start copying - if(ascii_mirror_len > 0 && - ascii_mirror_curr_page < start_page && - ascii_mirror_curr_byte != 0) { - uint8_t diff = 4 - ascii_mirror_curr_byte; - ascii_mirror_len -= diff; - ascii_mirror_cptr += diff; - ascii_mirror_curr_byte = 0; - ++ascii_mirror_curr_page; - } - while(ascii_mirror_len > 0 && - ascii_mirror_curr_page < start_page) { - uint8_t diff = ascii_mirror_len > 4 ? 4 : ascii_mirror_len; - ascii_mirror_len -= diff; - ascii_mirror_cptr += diff; - ++ascii_mirror_curr_page; - } - } - } - - uint8_t* dest_ptr = buff_tx; - while(copied_pages < 4) { - // Copy page - memcpy(dest_ptr, &emulator->data.data[src_page * 4], 4); - - // Note: don't have to worry about roll-over with ASCII mirror because - // lowest valid page for it is 4, while roll-over will at best read - // pages 0-2 - if(ascii_mirror_len > 0 && src_page == ascii_mirror_curr_page) { - // Copy ASCII mirror - size_t copy_len = 4 - ascii_mirror_curr_byte; - if(copy_len > ascii_mirror_len) copy_len = ascii_mirror_len; - for(size_t i = 0; i < copy_len; ++i) { - if(*ascii_mirror_cptr != ' ') - dest_ptr[ascii_mirror_curr_byte] = - (uint8_t)*ascii_mirror_cptr; - ++ascii_mirror_curr_byte; - ++ascii_mirror_cptr; - } - ascii_mirror_len -= copy_len; - // Don't care if this is inaccurate after ascii_mirror_len = 0 - ascii_mirror_curr_byte = 0; - ++ascii_mirror_curr_page; - } - - if(emulator->supported_features & MfUltralightSupportAuth) { - if(src_page == pwd_page || src_page == pwd_page + 1) { - // Blank out PWD and PACK pages - memset(dest_ptr, 0, 4); - } - } - - dest_ptr += 4; - ++copied_pages; - ++src_page; - if(src_page >= last_page_plus_one) src_page = 0; - } - if(ascii_mirror != NULL) { - furi_string_free(ascii_mirror); - } - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } while(false); - } - } else { - uint16_t valid_pages; - start_page = mf_ultralight_ntag_i2c_addr_tag_to_lin( - &emulator->data, start_page, emulator->curr_sector, &valid_pages); - if(start_page != -1) { - if(emulator->data.type < MfUltralightTypeNTAGI2CPlus1K || - mf_ul_ntag_i2c_plus_check_auth(emulator, buff_rx[1], false)) { - if(emulator->data.type >= MfUltralightTypeNTAGI2CPlus1K && - emulator->curr_sector == 3 && valid_pages == 1) { - // Rewind back a sector to match behavior on a real tag - --start_page; - ++valid_pages; - } - - uint16_t copy_count = (valid_pages > 4 ? 4 : valid_pages) * 4; - FURI_LOG_D( - TAG, - "NTAG I2C Emu: page valid, %02x:%02x -> %d, %d", - emulator->curr_sector, - buff_rx[1], - start_page, - valid_pages); - memcpy(buff_tx, &emulator->data.data[start_page * 4], copy_count); - // For NTAG I2C, there's no roll-over; remainder is filled by null bytes - if(copy_count < tx_bytes) - memset(&buff_tx[copy_count], 0, tx_bytes - copy_count); - // Special case: NTAG I2C Plus sector 0 page 233 read crosses into page 236 - if(start_page == 233) - memcpy( - &buff_tx[12], &emulator->data.data[(start_page + 1) * 4], 4); - mf_ul_protect_auth_data_on_read_command_i2c( - buff_tx, start_page, start_page + copy_count / 4 - 1, emulator); - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } else { - FURI_LOG_D( - TAG, - "NTAG I2C Emu: page invalid, %02x:%02x", - emulator->curr_sector, - buff_rx[1]); - if(emulator->data.type >= MfUltralightTypeNTAGI2CPlus1K && - emulator->curr_sector == 3 && - !emulator->ntag_i2c_plus_sector3_lockout) { - // NTAG I2C Plus has a weird behavior where if you read sector 3 - // at an invalid address, it responds with zeroes then locks - // the read out, while if you read the mirrored session registers, - // it returns both session registers on either pages - memset(buff_tx, 0, tx_bytes); - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - emulator->ntag_i2c_plus_sector3_lockout = true; - } - } - } - if(!command_parsed) tx_bytes = 0; - } - } else if(cmd == MF_UL_FAST_READ_CMD) { - if(emulator->supported_features & MfUltralightSupportFastRead) { - if(buff_rx_len == (1 + 2) * 8) { - int16_t start_page = buff_rx[1]; - uint8_t end_page = buff_rx[2]; - if(start_page <= end_page) { - tx_bytes = ((end_page + 1) - start_page) * 4; - if(emulator->data.type < MfUltralightTypeNTAGI2C1K) { - if((start_page < emulator->page_num) && - (end_page < emulator->page_num)) { - do { - if(emulator->supported_features & MfUltralightSupportAuth) { - // NAK if not authenticated and requested pages cross over AUTH0 - if(!emulator->auth_success && - emulator->config_cache.access.prot && - (start_page >= emulator->config_cache.auth0 || - end_page >= emulator->config_cache.auth0)) - break; - } - if(emulator->supported_features & - MfUltralightSupportSingleCounter) - mf_ul_increment_single_counter(emulator); - - // Copy requested pages - memcpy( - buff_tx, &emulator->data.data[start_page * 4], tx_bytes); - - if(emulator->supported_features & - MfUltralightSupportAsciiMirror && - emulator->config_cache.mirror.mirror_conf != - MfUltralightMirrorNone) { - // Copy ASCII mirror - // Less stringent check here, because expecting FAST_READ to - // only be issued once rather than repeatedly - FuriString* ascii_mirror; - ascii_mirror = furi_string_alloc(); - mf_ul_make_ascii_mirror(emulator, ascii_mirror); - size_t ascii_mirror_len = - furi_string_utf8_length(ascii_mirror); - const char* ascii_mirror_cptr = - furi_string_get_cstr(ascii_mirror); - int16_t mirror_start_offset = - (emulator->config->mirror_page - start_page) * 4 + - emulator->config->mirror.mirror_byte; - if(mirror_start_offset < 0) { - if(mirror_start_offset < -(int16_t)ascii_mirror_len) { - // Past ASCII mirror, don't copy - ascii_mirror_len = 0; - } else { - ascii_mirror_cptr += -mirror_start_offset; - ascii_mirror_len -= -mirror_start_offset; - mirror_start_offset = 0; - } - } - if(ascii_mirror_len > 0) { - int16_t mirror_end_offset = - mirror_start_offset + ascii_mirror_len; - if(mirror_end_offset > (end_page + 1) * 4) { - mirror_end_offset = (end_page + 1) * 4; - ascii_mirror_len = - mirror_end_offset - mirror_start_offset; - } - for(size_t i = 0; i < ascii_mirror_len; ++i) { - if(*ascii_mirror_cptr != ' ') - buff_tx[mirror_start_offset] = - (uint8_t)*ascii_mirror_cptr; - ++mirror_start_offset; - ++ascii_mirror_cptr; - } - } - furi_string_free(ascii_mirror); - } - - if(emulator->supported_features & MfUltralightSupportAuth) { - // Clear PWD and PACK pages - uint8_t pwd_page = emulator->page_num - 2; - int16_t pwd_page_offset = pwd_page - start_page; - // PWD page - if(pwd_page_offset >= 0 && pwd_page <= end_page) { - memset(&buff_tx[pwd_page_offset * 4], 0, 4); - // PACK page - if(pwd_page + 1 <= end_page) - memset(&buff_tx[(pwd_page_offset + 1) * 4], 0, 4); - } - } - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } while(false); - } - } else { - uint16_t valid_pages; - start_page = mf_ultralight_ntag_i2c_addr_tag_to_lin( - &emulator->data, start_page, emulator->curr_sector, &valid_pages); - if(start_page != -1) { - if(emulator->data.type < MfUltralightTypeNTAGI2CPlus1K || - mf_ul_ntag_i2c_plus_check_auth(emulator, buff_rx[1], false)) { - uint16_t copy_count = tx_bytes; - if(copy_count > valid_pages * 4) copy_count = valid_pages * 4; - memcpy( - buff_tx, &emulator->data.data[start_page * 4], copy_count); - if(copy_count < tx_bytes) - memset(&buff_tx[copy_count], 0, tx_bytes - copy_count); - mf_ul_ntag_i2c_fill_cross_area_read( - buff_tx, buff_rx[1], buff_rx[2], emulator); - mf_ul_protect_auth_data_on_read_command_i2c( - buff_tx, - start_page, - start_page + copy_count / 4 - 1, - emulator); - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } - } - if(!command_parsed) tx_bytes = 0; - } - } - } - } else if(cmd == MF_UL_WRITE) { - if(buff_rx_len == (1 + 5) * 8) { - do { - uint8_t orig_write_page = buff_rx[1]; - int16_t write_page = orig_write_page; - uint16_t valid_pages; // unused - write_page = mf_ultralight_ntag_i2c_addr_tag_to_lin( - &emulator->data, write_page, emulator->curr_sector, &valid_pages); - if(write_page == -1) // NTAG I2C range check - break; - else if(write_page < 2 || write_page >= emulator->page_num) // Other MFUL/NTAG range check - break; - - if(emulator->supported_features & MfUltralightSupportAuth) { - if(emulator->data.type >= MfUltralightTypeNTAGI2CPlus1K) { - if(!mf_ul_ntag_i2c_plus_check_auth(emulator, orig_write_page, true)) - break; - } else { - if(!mf_ul_check_auth(emulator, orig_write_page, true)) break; - } - } - int16_t tag_addr = mf_ultralight_page_addr_to_tag_addr( - emulator->curr_sector, orig_write_page); - if(!mf_ul_check_lock(emulator, tag_addr)) break; - if(emulator->data.type == MfUltralightTypeNTAG203 && - orig_write_page == MF_UL_NTAG203_COUNTER_PAGE) { - send_ack = mf_ul_emulate_ntag203_counter_write(emulator, &buff_rx[2]); - command_parsed = send_ack; - } else { - mf_ul_emulate_write(emulator, tag_addr, write_page, &buff_rx[2]); - send_ack = true; - command_parsed = true; - } - } while(false); - } - } else if(cmd == MF_UL_FAST_WRITE) { - if(emulator->supported_features & MfUltralightSupportFastWrite) { - if(buff_rx_len == (1 + 66) * 8) { - if(buff_rx[1] == 0xF0 && buff_rx[2] == 0xFF) { - // TODO: update when SRAM emulation implemented - send_ack = true; - command_parsed = true; - } - } - } - } else if(cmd == MF_UL_COMP_WRITE) { - if(emulator->supported_features & MfUltralightSupportCompatWrite) { - if(buff_rx_len == (1 + 1) * 8) { - uint8_t write_page = buff_rx[1]; - do { - if(write_page < 2 || write_page >= emulator->page_num) break; - if(emulator->supported_features & MfUltralightSupportAuth && - !mf_ul_check_auth(emulator, write_page, true)) - break; - // Note we don't convert to tag addr here because there's only one sector - if(!mf_ul_check_lock(emulator, write_page)) break; - - emulator->comp_write_cmd_started = true; - emulator->comp_write_page_addr = write_page; - send_ack = true; - command_parsed = true; - } while(false); - } - } - } else if(cmd == MF_UL_READ_CNT) { - if(emulator->supported_features & MfUltralightSupportReadCounter) { - if(buff_rx_len == (1 + 1) * 8) { - do { - uint8_t cnt_num = buff_rx[1]; - - // NTAG21x checks - if(emulator->supported_features & MfUltralightSupportSingleCounter) { - if(cnt_num != 2) break; // Only counter 2 is available - if(!emulator->config_cache.access.nfc_cnt_en) - break; // NAK if counter not enabled - if(emulator->config_cache.access.nfc_cnt_pwd_prot && - !emulator->auth_success) - break; - } - - if(cnt_num < 3) { - buff_tx[0] = emulator->data.counter[cnt_num] & 0xFF; - buff_tx[1] = (emulator->data.counter[cnt_num] >> 8) & 0xFF; - buff_tx[2] = (emulator->data.counter[cnt_num] >> 16) & 0xFF; - tx_bytes = 3; - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } while(false); - } - } - } else if(cmd == MF_UL_INC_CNT) { - if(emulator->supported_features & MfUltralightSupportIncrCounter) { - if(buff_rx_len == (1 + 5) * 8) { - uint8_t cnt_num = buff_rx[1]; - uint32_t inc = (buff_rx[2] | (buff_rx[3] << 8) | (buff_rx[4] << 16)); - // TODO: can you increment by 0 when counter is at 0xffffff? - if((cnt_num < 3) && (emulator->data.counter[cnt_num] != 0x00FFFFFF) && - (emulator->data.counter[cnt_num] + inc <= 0x00FFFFFF)) { - emulator->data.counter[cnt_num] += inc; - // We're RAM-backed, so tearing never happens - emulator->data.tearing[cnt_num] = MF_UL_TEARING_FLAG_DEFAULT; - emulator->data_changed = true; - send_ack = true; - command_parsed = true; - } - } - } - } else if(cmd == MF_UL_PWD_AUTH) { - if(emulator->supported_features & MfUltralightSupportAuth) { - if(buff_rx_len == (1 + 4) * 8) { - // Record password sent by PCD - memcpy( - emulator->auth_attempt.pwd.raw, - &buff_rx[1], - sizeof(emulator->auth_attempt.pwd.raw)); - emulator->auth_attempted = true; - if(emulator->auth_received_callback) { - emulator->auth_received_callback( - emulator->auth_attempt, emulator->context); - } - - uint16_t scaled_authlim = mf_ultralight_calc_auth_count(&emulator->data); - if(scaled_authlim != 0 && emulator->data.curr_authlim >= scaled_authlim) { - if(emulator->data.curr_authlim != UINT16_MAX) { - // Handle case where AUTHLIM has been lowered or changed from 0 - emulator->data.curr_authlim = UINT16_MAX; - emulator->data_changed = true; - } - // AUTHLIM reached, always fail - buff_tx[0] = MF_UL_NAK_AUTHLIM_REACHED; - tx_bits = 4; - *data_type = FURRY_HAL_NFC_TX_RAW_RX_DEFAULT; - mf_ul_reset_emulation(emulator, false); - command_parsed = true; - } else { - if(memcmp(&buff_rx[1], emulator->config->auth_data.pwd.raw, 4) == 0) { - // Correct password - buff_tx[0] = emulator->config->auth_data.pack.raw[0]; - buff_tx[1] = emulator->config->auth_data.pack.raw[1]; - tx_bytes = 2; - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - emulator->auth_success = true; - command_parsed = true; - if(emulator->data.curr_authlim != 0) { - // Reset current AUTHLIM - emulator->data.curr_authlim = 0; - emulator->data_changed = true; - } - } else if(!emulator->config->auth_data.pwd.value) { - // Unknown password, pretend to be an Amiibo - buff_tx[0] = 0x80; - buff_tx[1] = 0x80; - tx_bytes = 2; - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - emulator->auth_success = true; - command_parsed = true; - } else { - // Wrong password, increase negative verification count - if(emulator->data.curr_authlim < UINT16_MAX) { - ++emulator->data.curr_authlim; - emulator->data_changed = true; - } - if(scaled_authlim != 0 && - emulator->data.curr_authlim >= scaled_authlim) { - emulator->data.curr_authlim = UINT16_MAX; - buff_tx[0] = MF_UL_NAK_AUTHLIM_REACHED; - tx_bits = 4; - *data_type = FURRY_HAL_NFC_TX_RAW_RX_DEFAULT; - mf_ul_reset_emulation(emulator, false); - command_parsed = true; - } else { - // Should delay here to slow brute forcing - } - } - } - } - } - } else if(cmd == MF_UL_READ_SIG) { - if(emulator->supported_features & MfUltralightSupportSignature) { - // Check 2nd byte = 0x00 - RFU - if(buff_rx_len == (1 + 1) * 8 && buff_rx[1] == 0x00) { - tx_bytes = sizeof(emulator->data.signature); - memcpy(buff_tx, emulator->data.signature, tx_bytes); - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } - } else if(cmd == MF_UL_CHECK_TEARING) { - if(emulator->supported_features & MfUltralightSupportTearingFlags) { - if(buff_rx_len == (1 + 1) * 8) { - uint8_t cnt_num = buff_rx[1]; - if(cnt_num < 3) { - buff_tx[0] = emulator->data.tearing[cnt_num]; - tx_bytes = 1; - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } - } - } else if(cmd == MF_UL_HALT_START) { - reset_idle = true; - FURI_LOG_D(TAG, "Received HLTA"); - } else if(cmd == MF_UL_SECTOR_SELECT) { - if(emulator->supported_features & MfUltralightSupportSectorSelect) { - if(buff_rx_len == (1 + 1) * 8 && buff_rx[1] == 0xFF) { - // Send ACK - emulator->sector_select_cmd_started = true; - send_ack = true; - command_parsed = true; - } - } - } else if(cmd == MF_UL_READ_VCSL) { - if(emulator->supported_features & MfUltralightSupportVcsl) { - if(buff_rx_len == (1 + 20) * 8) { - buff_tx[0] = emulator->config_cache.vctid; - tx_bytes = 1; - *data_type = FURRY_HAL_NFC_TXRX_DEFAULT; - command_parsed = true; - } - } - } else { - // NTAG203 appears to NAK instead of just falling off on invalid commands - if(emulator->data.type != MfUltralightTypeNTAG203) reset_idle = true; - FURI_LOG_D(TAG, "Received invalid command"); - } - } else { - reset_idle = true; - FURI_LOG_D(TAG, "Received invalid buffer less than 8 bits in length"); - } - - if(reset_idle) { - mf_ul_reset_emulation(emulator, false); - tx_bits = 0; - command_parsed = true; - } - - if(!command_parsed) { - // Send NACK - buff_tx[0] = MF_UL_NAK_INVALID_ARGUMENT; - tx_bits = 4; - *data_type = FURRY_HAL_NFC_TX_RAW_RX_DEFAULT; - // Every NAK should cause reset to IDLE - mf_ul_reset_emulation(emulator, false); - } else if(send_ack) { - buff_tx[0] = MF_UL_ACK; - tx_bits = 4; - *data_type = FURRY_HAL_NFC_TX_RAW_RX_DEFAULT; - } - - if(respond_nothing) { - *buff_tx_len = UINT16_MAX; - *data_type = FURRY_HAL_NFC_TX_RAW_RX_DEFAULT; - } else { - // Return tx buffer size in bits - if(tx_bytes) { - tx_bits = tx_bytes * 8; - } - *buff_tx_len = tx_bits; - } - -#ifdef FURI_DEBUG - if(*buff_tx_len == UINT16_MAX) { - FURI_LOG_T(TAG, "Emu TX: no reply"); - } else if(*buff_tx_len > 0) { - int count = (*buff_tx_len + 7) / 8; - for(int i = 0; i < count; ++i) { - furi_string_cat_printf(debug_buf, "%02x ", buff_tx[i]); - } - furi_string_trim(debug_buf); - FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, furi_string_get_cstr(debug_buf)); - furi_string_free(debug_buf); - } else { - FURI_LOG_T(TAG, "Emu TX: HALT"); - } -#endif - - return tx_bits > 0; -} - -bool mf_ul_is_full_capture(MfUltralightData* data) { - if(data->data_read != data->data_size) return false; - - // Having read all the pages doesn't mean that we've got everything. - // By default PWD is 0xFFFFFFFF, but if read back it is always 0x00000000, - // so a default read on an auth-supported NTAG is never complete. - if(!(mf_ul_get_features(data->type) & MfUltralightSupportAuth)) return true; - MfUltralightConfigPages* config = mf_ultralight_get_config_pages(data); - return config->auth_data.pwd.value != 0 || config->auth_data.pack.value != 0; -} diff --git a/base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.h b/base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.h deleted file mode 100644 index e97ff636d31..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/protocols/mifare_ultralight.h +++ /dev/null @@ -1,269 +0,0 @@ -#pragma once - -#include "../furi_hal_nfc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Largest tag is NTAG I2C Plus 2K, both data sectors plus SRAM -#define MF_UL_MAX_DUMP_SIZE ((238 + 256 + 16) * 4) - -#define MF_UL_TEARING_FLAG_DEFAULT (0xBD) - -#define MF_UL_HALT_START (0x50) -#define MF_UL_GET_VERSION_CMD (0x60) -#define MF_UL_READ_CMD (0x30) -#define MF_UL_FAST_READ_CMD (0x3A) -#define MF_UL_WRITE (0xA2) -#define MF_UL_FAST_WRITE (0xA6) -#define MF_UL_COMP_WRITE (0xA0) -#define MF_UL_READ_CNT (0x39) -#define MF_UL_INC_CNT (0xA5) -#define MF_UL_AUTHENTICATE_1 (0x1A) -#define MF_UL_PWD_AUTH (0x1B) -#define MF_UL_READ_SIG (0x3C) -#define MF_UL_CHECK_TEARING (0x3E) -#define MF_UL_READ_VCSL (0x4B) -#define MF_UL_SECTOR_SELECT (0xC2) - -#define MF_UL_ACK (0xa) -#define MF_UL_NAK_INVALID_ARGUMENT (0x0) -#define MF_UL_NAK_AUTHLIM_REACHED (0x4) - -#define MF_UL_NTAG203_COUNTER_PAGE (41) - -#define MF_UL_DEFAULT_PWD (0xFFFFFFFF) - -typedef enum { - MfUltralightAuthMethodManual, - MfUltralightAuthMethodAmeebo, - MfUltralightAuthMethodXiaomi, - MfUltralightAuthMethodAuto, -} MfUltralightAuthMethod; - -// Important: order matters; some features are based on positioning in this enum -typedef enum { - MfUltralightTypeUnknown, - MfUltralightTypeNTAG203, - MfUltralightTypeULC, - // Below have config pages and GET_VERSION support - MfUltralightTypeUL11, - MfUltralightTypeUL21, - MfUltralightTypeNTAG213, - MfUltralightTypeNTAG215, - MfUltralightTypeNTAG216, - // Below also have sector select - // NTAG I2C's *does not* have regular config pages, so it's a bit of an odd duck - MfUltralightTypeNTAGI2C1K, - MfUltralightTypeNTAGI2C2K, - // NTAG I2C Plus has stucture expected from NTAG21x - MfUltralightTypeNTAGI2CPlus1K, - MfUltralightTypeNTAGI2CPlus2K, - - // Keep last for number of types calculation - MfUltralightTypeNum, -} MfUltralightType; - -typedef enum { - MfUltralightSupportNone = 0, - MfUltralightSupportFastRead = 1 << 0, - MfUltralightSupportTearingFlags = 1 << 1, - MfUltralightSupportReadCounter = 1 << 2, - MfUltralightSupportIncrCounter = 1 << 3, - MfUltralightSupportSignature = 1 << 4, - MfUltralightSupportFastWrite = 1 << 5, - MfUltralightSupportCompatWrite = 1 << 6, - MfUltralightSupportAuth = 1 << 7, - MfUltralightSupportVcsl = 1 << 8, - MfUltralightSupportSectorSelect = 1 << 9, - // NTAG21x only has counter 2 - MfUltralightSupportSingleCounter = 1 << 10, - // ASCII mirror is not a command, but handy to have as a flag - MfUltralightSupportAsciiMirror = 1 << 11, - // NTAG203 counter that's in memory rather than through a command - MfUltralightSupportCounterInMemory = 1 << 12, - MfUltralightSupport3DesAuth = 1 << 13, -} MfUltralightFeatures; - -typedef enum { - MfUltralightMirrorNone, - MfUltralightMirrorUid, - MfUltralightMirrorCounter, - MfUltralightMirrorUidCounter, -} MfUltralightMirrorConf; - -typedef struct { - uint8_t header; - uint8_t vendor_id; - uint8_t prod_type; - uint8_t prod_subtype; - uint8_t prod_ver_major; - uint8_t prod_ver_minor; - uint8_t storage_size; - uint8_t protocol_type; -} MfUltralightVersion; - -typedef struct { - uint8_t sn0[3]; - uint8_t btBCC0; - uint8_t sn1[4]; - uint8_t btBCC1; - uint8_t internal; - uint8_t lock[2]; - uint8_t otp[4]; -} MfUltralightManufacturerBlock; - -typedef struct { - MfUltralightType type; - MfUltralightVersion version; - uint8_t signature[32]; - uint32_t counter[3]; - uint8_t tearing[3]; - MfUltralightAuthMethod auth_method; - uint8_t auth_key[4]; - bool auth_success; - uint16_t curr_authlim; - uint16_t data_size; - uint8_t data[MF_UL_MAX_DUMP_SIZE]; - uint16_t data_read; -} MfUltralightData; - -typedef struct __attribute__((packed)) { - union { - uint8_t raw[4]; - uint32_t value; - } pwd; - union { - uint8_t raw[2]; - uint16_t value; - } pack; -} MfUltralightAuth; - -// Common configuration pages for MFUL EV1, NTAG21x, and NTAG I2C Plus -typedef struct __attribute__((packed)) { - union { - uint8_t value; - struct { - uint8_t rfui1 : 2; - bool strg_mod_en : 1; - bool rfui2 : 1; - uint8_t mirror_byte : 2; - MfUltralightMirrorConf mirror_conf : 2; - }; - } mirror; - uint8_t rfui1; - uint8_t mirror_page; - uint8_t auth0; - union { - uint8_t value; - struct { - uint8_t authlim : 3; - bool nfc_cnt_pwd_prot : 1; - bool nfc_cnt_en : 1; - bool nfc_dis_sec1 : 1; // NTAG I2C Plus only - bool cfglck : 1; - bool prot : 1; - }; - } access; - uint8_t vctid; - uint8_t rfui2[2]; - MfUltralightAuth auth_data; - uint8_t rfui3[2]; -} MfUltralightConfigPages; - -typedef struct { - uint16_t pages_to_read; - int16_t pages_read; - MfUltralightFeatures supported_features; -} MfUltralightReader; - -// TODO rework with reader analyzer -typedef void (*MfUltralightAuthReceivedCallback)(MfUltralightAuth auth, void* context); - -typedef struct { - MfUltralightData data; - MfUltralightConfigPages* config; - // Most config values don't apply until power cycle, so cache config pages - // for correct behavior - MfUltralightConfigPages config_cache; - MfUltralightFeatures supported_features; - uint16_t page_num; - bool data_changed; - bool comp_write_cmd_started; - uint8_t comp_write_page_addr; - bool auth_success; - uint8_t curr_sector; - bool sector_select_cmd_started; - bool ntag_i2c_plus_sector3_lockout; - bool read_counter_incremented; - bool auth_attempted; - MfUltralightAuth auth_attempt; - - // TODO rework with reader analyzer - MfUltralightAuthReceivedCallback auth_received_callback; - void* context; -} MfUltralightEmulator; - -void mf_ul_reset(MfUltralightData* data); - -bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); - -bool mf_ultralight_read_version( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data); - -bool mf_ultralight_read_pages_direct( - FurryHalNfcTxRxContext* tx_rx, - uint8_t start_index, - uint8_t* data); - -bool mf_ultralight_read_pages( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data); - -bool mf_ultralight_fast_read_pages( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data); - -bool mf_ultralight_read_signature(FurryHalNfcTxRxContext* tx_rx, MfUltralightData* data); - -bool mf_ultralight_read_counters(FurryHalNfcTxRxContext* tx_rx, MfUltralightData* data); - -bool mf_ultralight_read_tearing_flags(FurryHalNfcTxRxContext* tx_rx, MfUltralightData* data); - -bool mf_ultralight_authenticate(FurryHalNfcTxRxContext* tx_rx, uint32_t key, uint16_t* pack); - -MfUltralightConfigPages* mf_ultralight_get_config_pages(MfUltralightData* data); - -bool mf_ul_read_card( - FurryHalNfcTxRxContext* tx_rx, - MfUltralightReader* reader, - MfUltralightData* data); - -bool mf_ul_emulation_supported(MfUltralightData* data); - -void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle); - -void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data); - -bool mf_ul_prepare_emulation_response( - uint8_t* buff_rx, - uint16_t buff_rx_len, - uint8_t* buff_tx, - uint16_t* buff_tx_len, - uint32_t* data_type, - void* context); - -uint32_t mf_ul_pwdgen_amiibo(FurryHalNfcDevData* data); - -uint32_t mf_ul_pwdgen_xiaomi(FurryHalNfcDevData* data); - -bool mf_ul_is_full_capture(MfUltralightData* data); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.c b/base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.c deleted file mode 100644 index 1c3cb4a586f..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.c +++ /dev/null @@ -1,236 +0,0 @@ -#include "pulse_reader.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -struct PulseReader { - uint32_t* timer_buffer; - uint32_t* gpio_buffer; - uint32_t size; - uint32_t pos; - uint32_t timer_value; - uint32_t gpio_value; - uint32_t gpio_mask; - uint32_t unit_multiplier; - uint32_t unit_divider; - uint32_t bit_time; - uint32_t dma_channel; - const GpioPin* gpio; - GpioPull pull; - LL_DMA_InitTypeDef dma_config_timer; - LL_DMA_InitTypeDef dma_config_gpio; -}; - -#define GPIO_PIN_MAP(pin, prefix) \ - (((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \ - ((pin) == (LL_GPIO_PIN_1)) ? prefix##1 : \ - ((pin) == (LL_GPIO_PIN_2)) ? prefix##2 : \ - ((pin) == (LL_GPIO_PIN_3)) ? prefix##3 : \ - ((pin) == (LL_GPIO_PIN_4)) ? prefix##4 : \ - ((pin) == (LL_GPIO_PIN_5)) ? prefix##5 : \ - ((pin) == (LL_GPIO_PIN_6)) ? prefix##6 : \ - ((pin) == (LL_GPIO_PIN_7)) ? prefix##7 : \ - ((pin) == (LL_GPIO_PIN_8)) ? prefix##8 : \ - ((pin) == (LL_GPIO_PIN_9)) ? prefix##9 : \ - ((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \ - ((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \ - ((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \ - ((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \ - ((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \ - prefix##15) - -#define GET_DMAMUX_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_DMAMUX_REQ_GEN_EXTI_LINE) - -PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size) { - PulseReader* signal = malloc(sizeof(PulseReader)); - signal->timer_buffer = malloc(size * sizeof(uint32_t)); - signal->gpio_buffer = malloc(size * sizeof(uint32_t)); - signal->dma_channel = LL_DMA_CHANNEL_4; - signal->gpio = gpio; - signal->pull = GpioPullNo; - signal->size = size; - signal->timer_value = 0; - signal->pos = 0; - - pulse_reader_set_timebase(signal, PulseReaderUnit64MHz); - pulse_reader_set_bittime(signal, 1); - - signal->dma_config_timer.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; - signal->dma_config_timer.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->CNT); - signal->dma_config_timer.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - signal->dma_config_timer.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; - signal->dma_config_timer.MemoryOrM2MDstAddress = (uint32_t)signal->timer_buffer; - signal->dma_config_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - signal->dma_config_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - signal->dma_config_timer.Mode = LL_DMA_MODE_CIRCULAR; - signal->dma_config_timer.PeriphRequest = - LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */ - signal->dma_config_timer.Priority = LL_DMA_PRIORITY_VERYHIGH; - - signal->dma_config_gpio.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; - signal->dma_config_gpio.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - signal->dma_config_gpio.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; - signal->dma_config_gpio.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - signal->dma_config_gpio.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; - signal->dma_config_gpio.Mode = LL_DMA_MODE_CIRCULAR; - signal->dma_config_gpio.PeriphRequest = - LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */ - signal->dma_config_gpio.Priority = LL_DMA_PRIORITY_VERYHIGH; - - return signal; -} - -void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit) { - switch(unit) { - case PulseReaderUnit64MHz: - signal->unit_multiplier = 1; - signal->unit_divider = 1; - break; - case PulseReaderUnitPicosecond: - signal->unit_multiplier = 15625; - signal->unit_divider = 1; - break; - case PulseReaderUnitNanosecond: - signal->unit_multiplier = 15625; - signal->unit_divider = 1000; - break; - case PulseReaderUnitMicrosecond: - signal->unit_multiplier = 15625; - signal->unit_divider = 1000000; - break; - } -} - -void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time) { - signal->bit_time = bit_time; -} - -void pulse_reader_set_pull(PulseReader* signal, GpioPull pull) { - signal->pull = pull; -} - -void pulse_reader_free(PulseReader* signal) { - furi_assert(signal); - - free(signal->timer_buffer); - free(signal->gpio_buffer); - free(signal); -} - -uint32_t pulse_reader_samples(PulseReader* signal) { - uint32_t dma_pos = signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel); - - return ((signal->pos + signal->size) - dma_pos) % signal->size; -} - -void pulse_reader_stop(PulseReader* signal) { - LL_DMA_DisableChannel(DMA1, signal->dma_channel); - LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1); - LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); - LL_TIM_DisableCounter(TIM2); - furi_hal_bus_disable(FuriHalBusTIM2); - furi_hal_gpio_init_simple(signal->gpio, GpioModeAnalog); -} - -void pulse_reader_start(PulseReader* signal) { - /* configure DMA to read from a timer peripheral */ - signal->dma_config_timer.NbData = signal->size; - - signal->dma_config_gpio.PeriphOrM2MSrcAddress = (uint32_t) & (signal->gpio->port->IDR); - signal->dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t)signal->gpio_buffer; - signal->dma_config_gpio.NbData = signal->size; - - furi_hal_bus_enable(FuriHalBusTIM2); - - /* start counter */ - LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); - LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); - LL_TIM_SetPrescaler(TIM2, 0); - LL_TIM_SetAutoReload(TIM2, 0xFFFFFFFF); - LL_TIM_SetCounter(TIM2, 0); - LL_TIM_EnableCounter(TIM2); - - /* generator 0 gets fed by EXTI_LINEn */ - LL_DMAMUX_SetRequestSignalID( - NULL, LL_DMAMUX_REQ_GEN_0, GET_DMAMUX_EXTI_LINE(signal->gpio->pin)); - /* trigger on rising edge of the interrupt */ - LL_DMAMUX_SetRequestGenPolarity(NULL, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING); - /* now enable request generation again */ - LL_DMAMUX_EnableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); - - /* we need the EXTI to be configured as interrupt generating line, but no ISR registered */ - furi_hal_gpio_init_ex( - signal->gpio, GpioModeInterruptRiseFall, signal->pull, GpioSpeedVeryHigh, GpioAltFnUnused); - - /* capture current timer */ - signal->pos = 0; - signal->timer_value = TIM2->CNT; - signal->gpio_mask = signal->gpio->pin; - signal->gpio_value = signal->gpio->port->IDR & signal->gpio_mask; - - /* now set up DMA with these settings */ - LL_DMA_Init(DMA1, signal->dma_channel, &signal->dma_config_timer); - LL_DMA_Init(DMA1, signal->dma_channel + 1, &signal->dma_config_gpio); - LL_DMA_EnableChannel(DMA1, signal->dma_channel); - LL_DMA_EnableChannel(DMA1, signal->dma_channel + 1); -} - -uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) { - uint32_t start_time = DWT->CYCCNT; - uint32_t timeout_ticks = timeout_us * (F_TIM2 / 1000000); - - do { - /* get the DMA's next write position by reading "remaining length" register */ - uint32_t dma_pos = - signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel); - - /* the DMA has advanced in the ringbuffer */ - if(dma_pos != signal->pos) { - uint32_t delta = signal->timer_buffer[signal->pos] - signal->timer_value; - uint32_t last_gpio_value = signal->gpio_value; - - signal->gpio_value = signal->gpio_buffer[signal->pos]; - - /* check if the GPIO really toggled. if not, we lost an edge :( */ - if(((last_gpio_value ^ signal->gpio_value) & signal->gpio_mask) != signal->gpio_mask) { - signal->gpio_value ^= signal->gpio_mask; - return PULSE_READER_LOST_EDGE; - } - signal->timer_value = signal->timer_buffer[signal->pos]; - - signal->pos++; - signal->pos %= signal->size; - - uint32_t delta_unit = 0; - - /* probably larger values, so choose a wider data type */ - if(signal->unit_divider > 1) { - delta_unit = - (uint32_t)((uint64_t)delta * (uint64_t)signal->unit_multiplier / signal->unit_divider); - } else { - delta_unit = delta * signal->unit_multiplier; - } - - /* if to be scaled to bit times, save a few instructions. should be faster */ - if(signal->bit_time > 1) { - return (delta_unit + signal->bit_time / 2) / signal->bit_time; - } - - return delta_unit; - } - - /* check for timeout */ - uint32_t elapsed = DWT->CYCCNT - start_time; - - if(elapsed > timeout_ticks) { - return PULSE_READER_NO_EDGE; - } - } while(true); -} diff --git a/base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.h b/base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.h deleted file mode 100644 index 62c5f2fa46d..00000000000 --- a/base_pack/mifare_nested/lib/nfclegacy/pulse_reader/pulse_reader.h +++ /dev/null @@ -1,122 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PULSE_READER_NO_EDGE (0xFFFFFFFFUL) -#define PULSE_READER_LOST_EDGE (0xFFFFFFFEUL) -#define F_TIM2 (64000000UL) - -/** - * unit of the edge durations to return - */ -typedef enum { - PulseReaderUnit64MHz, - PulseReaderUnitPicosecond, - PulseReaderUnitNanosecond, - PulseReaderUnitMicrosecond, -} PulseReaderUnit; - -/* using an anonymous type */ -typedef struct PulseReader PulseReader; - -/** Allocate a PulseReader object - * - * Allocates memory for a ringbuffer and initalizes the object - * - * @param[in] gpio the GPIO to use. will get configured as input. - * @param[in] size number of edges to buffer - */ -PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size); - -/** Free a PulseReader object - * - * Frees all memory of the given object - * - * @param[in] signal previously allocated PulseReader object. - */ -void pulse_reader_free(PulseReader* signal); - -/** Start signal capturing - * - * Initializes DMA1, TIM2 and DMAMUX_REQ_GEN_0 to automatically capture timer values. - * Ensure that interrupts are always enabled, as the used EXTI line is handled as one. - * - * @param[in] signal previously allocated PulseReader object. - */ -void pulse_reader_start(PulseReader* signal); - -/** Stop signal capturing - * - * Frees DMA1, TIM2 and DMAMUX_REQ_GEN_0 - * - * @param[in] signal previously allocated PulseReader object. - */ -void pulse_reader_stop(PulseReader* signal); - -/** Recevie a sample from ringbuffer - * - * Waits for the specified time until a new edge gets detected. - * If not configured otherwise, the pulse duration will be in picosecond resolution. - * If a bittime was configured, the return value will contain the properly rounded - * number of bit times measured. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] timeout_us time to wait for a signal [µs] - * - * @returns the scaled value of the pulse duration - */ -uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us); - -/** Get available samples - * - * Get the number of available samples in the ringbuffer - * - * @param[in] signal previously allocated PulseReader object. - * - * @returns the number of samples in buffer - */ -uint32_t pulse_reader_samples(PulseReader* signal); - -/** Set timebase - * - * Set the timebase to be used when returning pulse duration. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] unit PulseReaderUnit64MHz or PulseReaderUnitPicosecond - */ -void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit); - -/** Set bit time - * - * Set the number of timebase units per bit. - * When set, the pulse_reader_receive() will return an already rounded - * bit count value instead of the raw duration. - * - * Set to 1 to return duration again. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] bit_time - */ -void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time); - -/** Set GPIO pull direction - * - * Some GPIOs need pulldown, others don't. By default the - * pull direction is GpioPullNo. - * - * @param[in] signal previously allocated PulseReader object. - * @param[in] pull GPIO pull direction - */ -void pulse_reader_set_pull(PulseReader* signal, GpioPull pull); - -#ifdef __cplusplus -} -#endif From d17cd559882caee0ef7cc014dd4ef2309465618e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 13 Jun 2024 01:08:27 +0300 Subject: [PATCH 20/36] upd multifuzzer --- base_pack/multi_fuzzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base_pack/multi_fuzzer b/base_pack/multi_fuzzer index a4588f71759..2ecfcd857da 160000 --- a/base_pack/multi_fuzzer +++ b/base_pack/multi_fuzzer @@ -1 +1 @@ -Subproject commit a4588f71759cd8fa9c3fb555a8c66884eac3446b +Subproject commit 2ecfcd857da54b7a08014d14d7b46eb235b72695 From 7c35d941ae4452d0cd6f37953224c943508f6417 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 13 Jun 2024 01:17:17 +0300 Subject: [PATCH 21/36] upd readme --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 49258f6a378..983ccad9b78 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -13,7 +13,7 @@ Apps contains changes needed to compile them on latest firmware, fixes has been The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done. -### Apps checked & updated at `11 Jun 16:56 GMT +3` +### Apps checked & updated at `13 Jun 01:17 GMT +3` # Default pack From 6e6f3b1387e33608e3b07c1dadf7e3e7302af21c Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 00:30:27 +0300 Subject: [PATCH 22/36] bump versions for catalog --- apps_source_code/4inrow_game/application.fam | 2 +- apps_source_code/Snake_2/application.fam | 2 +- apps_source_code/airmon/application.fam | 2 +- apps_source_code/bluetooth-trigger/application.fam | 2 +- apps_source_code/bpmtapper/application.fam | 2 +- apps_source_code/brainfuck/application.fam | 2 +- apps_source_code/caesarcipher/application.fam | 2 +- apps_source_code/calculator/application.fam | 2 +- apps_source_code/counter/application.fam | 2 +- apps_source_code/flipp_pomodoro/application.fam | 2 +- apps_source_code/flipper-asteroids/application.fam | 2 +- apps_source_code/flipper-dcf77/application.fam | 2 +- apps_source_code/flipper_analog_clock/application.fam | 2 +- apps_source_code/flipper_geiger/application.fam | 2 +- apps_source_code/flipper_passgen/application.fam | 2 +- apps_source_code/flipper_pong/application.fam | 2 +- apps_source_code/flipperzero-slots/application.fam | 2 +- apps_source_code/flipperzero-text2sam/application.fam | 2 +- apps_source_code/flipperzero-tuning-fork/application.fam | 2 +- apps_source_code/flipperzero-yatzee-main/application.fam | 2 +- apps_source_code/fpz_cntdown_timer-main/application.fam | 2 +- apps_source_code/fz-reaction-game/application.fam | 2 +- apps_source_code/game_of_life/application.fam | 2 +- apps_source_code/gpio_7segment/application.fam | 2 +- apps_source_code/gpio_pins_reader/application.fam | 2 +- apps_source_code/hex_editor/application.fam | 2 +- apps_source_code/mandelbrot/application.fam | 2 +- apps_source_code/mifare_fuzzer/application.fam | 2 +- apps_source_code/montyhall/application.fam | 2 +- apps_source_code/musictracker/application.fam | 2 +- apps_source_code/ocarina/application.fam | 2 +- apps_source_code/paint/application.fam | 2 +- apps_source_code/pomodoro/application.fam | 2 +- apps_source_code/racegame/application.fam | 2 +- apps_source_code/resistors/application.fam | 2 +- apps_source_code/reversi/application.fam | 2 +- apps_source_code/rootoflife/application.fam | 2 +- apps_source_code/rubiks_cube_scrambler/application.fam | 2 +- apps_source_code/scorched_tanks/application.fam | 2 +- apps_source_code/servotester/application.fam | 2 +- apps_source_code/t-rex-runner/application.fam | 2 +- apps_source_code/timelapse/application.fam | 2 +- apps_source_code/videopoker/application.fam | 2 +- base_pack/arkanoid/application.fam | 2 +- base_pack/barcode_gen/application.fam | 2 +- base_pack/bomberduck/application.fam | 2 +- base_pack/doom/application.fam | 2 +- base_pack/dtmf_dolphin/application.fam | 2 +- base_pack/flappy_bird/application.fam | 2 +- base_pack/game15/application.fam | 2 +- base_pack/game_2048/application.fam | 2 +- base_pack/gps_nmea_uart/application.fam | 2 +- base_pack/heap_defence_game/application.fam | 2 +- base_pack/ir_scope/application.fam | 2 +- base_pack/metronome/application.fam | 2 +- base_pack/morse_code/application.fam | 2 +- base_pack/multi_converter/application.fam | 2 +- base_pack/pocsag_pager/application.fam | 2 +- base_pack/protoview/application.fam | 2 +- base_pack/sentry_safe/application.fam | 2 +- base_pack/spectrum_analyzer/application.fam | 2 +- base_pack/swd_probe/application.fam | 2 +- base_pack/tetris_game/application.fam | 2 +- base_pack/text_viewer/application.fam | 2 +- base_pack/tictactoe_game/application.fam | 2 +- base_pack/uart_terminal/application.fam | 2 +- base_pack/wav_player/application.fam | 2 +- base_pack/zombiez/application.fam | 2 +- 68 files changed, 68 insertions(+), 68 deletions(-) diff --git a/apps_source_code/4inrow_game/application.fam b/apps_source_code/4inrow_game/application.fam index d2e899bdccc..4b2fa4232d5 100644 --- a/apps_source_code/4inrow_game/application.fam +++ b/apps_source_code/4inrow_game/application.fam @@ -12,6 +12,6 @@ App( fap_category="Games", fap_author="leo-need-more-coffee", fap_weburl="https://github.com/leo-need-more-coffee/flipperzero-4inrow", - fap_version="1.1", + fap_version="1.2", fap_description="4 in row Game", ) diff --git a/apps_source_code/Snake_2/application.fam b/apps_source_code/Snake_2/application.fam index bd5a7c39233..d177f1def6f 100644 --- a/apps_source_code/Snake_2/application.fam +++ b/apps_source_code/Snake_2/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@Willzvul", fap_weburl="https://github.com/Willzvul/Snake_2.0", - fap_version="2.1", + fap_version="2.2", fap_description="Advanced Snake Game (Remake of original Snake)", ) diff --git a/apps_source_code/airmon/application.fam b/apps_source_code/airmon/application.fam index 5d1ce4aa42e..86f76f0617c 100644 --- a/apps_source_code/airmon/application.fam +++ b/apps_source_code/airmon/application.fam @@ -10,6 +10,6 @@ App( fap_icon_assets="icons", fap_author="3cky", fap_weburl="https://github.com/3cky/flipperzero-airmon", - fap_version="1.2", + fap_version="1.3", fap_description="Plantower PMSx003 sensor reader", ) diff --git a/apps_source_code/bluetooth-trigger/application.fam b/apps_source_code/bluetooth-trigger/application.fam index d36b586108a..1de1237f5d9 100644 --- a/apps_source_code/bluetooth-trigger/application.fam +++ b/apps_source_code/bluetooth-trigger/application.fam @@ -12,6 +12,6 @@ App( fap_libs=["ble_profile"], fap_author="@Nem0oo", fap_weburl="https://github.com/Nem0oo/flipper-zero-bluetooth-trigger", - fap_version="1.3", + fap_version="1.4", fap_description="Control your smartphone camera via your Flipper Zero", ) diff --git a/apps_source_code/bpmtapper/application.fam b/apps_source_code/bpmtapper/application.fam index 6c17804bcfb..415fc034290 100644 --- a/apps_source_code/bpmtapper/application.fam +++ b/apps_source_code/bpmtapper/application.fam @@ -12,6 +12,6 @@ App( order=15, fap_author="@panki27", fap_weburl="https://github.com/panki27/bpm-tapper", - fap_version="1.1", + fap_version="1.2", fap_description="Tap center button to measure BPM", ) diff --git a/apps_source_code/brainfuck/application.fam b/apps_source_code/brainfuck/application.fam index 86aa442edd1..ef537a23456 100644 --- a/apps_source_code/brainfuck/application.fam +++ b/apps_source_code/brainfuck/application.fam @@ -13,6 +13,6 @@ App( fap_icon_assets="icons", fap_author="@nymda", fap_weburl="https://github.com/nymda/FlipperZeroBrainfuck", - fap_version="1.2", + fap_version="1.3", fap_description="Brainfuck language interpreter", ) diff --git a/apps_source_code/caesarcipher/application.fam b/apps_source_code/caesarcipher/application.fam index 8dbbf80b2da..66d608b0ba2 100644 --- a/apps_source_code/caesarcipher/application.fam +++ b/apps_source_code/caesarcipher/application.fam @@ -13,6 +13,6 @@ App( order=20, fap_author="@panki27", fap_weburl="https://github.com/panki27/caesar-cipher", - fap_version="1.1", + fap_version="1.2", fap_description="Encrypt and decrypt text using Caesar Cipher", ) diff --git a/apps_source_code/calculator/application.fam b/apps_source_code/calculator/application.fam index f4298c25f22..c08201e9c55 100644 --- a/apps_source_code/calculator/application.fam +++ b/apps_source_code/calculator/application.fam @@ -11,6 +11,6 @@ App( fap_category="Tools", fap_author="@n-o-T-I-n-s-a-n-e", fap_weburl="https://github.com/n-o-T-I-n-s-a-n-e", - fap_version="1.1", + fap_version="1.2", fap_description="Calculator, that can calculate simple expressions", ) diff --git a/apps_source_code/counter/application.fam b/apps_source_code/counter/application.fam index 324e2d3b129..9ae3ec7a6da 100644 --- a/apps_source_code/counter/application.fam +++ b/apps_source_code/counter/application.fam @@ -11,6 +11,6 @@ App( fap_icon_assets="icons", fap_author="@Krulknul", fap_weburl="https://github.com/Krulknul/dolphin-counter", - fap_version="1.3", + fap_version="1.4", fap_description="Simple counter", ) diff --git a/apps_source_code/flipp_pomodoro/application.fam b/apps_source_code/flipp_pomodoro/application.fam index 5802cd288f3..febab602ef7 100644 --- a/apps_source_code/flipp_pomodoro/application.fam +++ b/apps_source_code/flipp_pomodoro/application.fam @@ -10,6 +10,6 @@ App( fap_icon="flipp_pomodoro_10.png", fap_author="@Th3Un1q3", fap_weburl="https://github.com/Th3Un1q3/flipp_pomodoro", - fap_version="1.3", + fap_version="1.4", fap_description="Boost Your Productivity with the Pomodoro Timer", ) diff --git a/apps_source_code/flipper-asteroids/application.fam b/apps_source_code/flipper-asteroids/application.fam index ef25980d011..1269229dfe3 100644 --- a/apps_source_code/flipper-asteroids/application.fam +++ b/apps_source_code/flipper-asteroids/application.fam @@ -12,6 +12,6 @@ App( fap_category="Games", fap_author="@antirez & @SimplyMinimal", fap_weburl="https://github.com/antirez/flipper-asteroids", - fap_version="1.1", + fap_version="1.2", fap_description="Asteroids game", ) diff --git a/apps_source_code/flipper-dcf77/application.fam b/apps_source_code/flipper-dcf77/application.fam index 784c226a647..73eb6a25535 100644 --- a/apps_source_code/flipper-dcf77/application.fam +++ b/apps_source_code/flipper-dcf77/application.fam @@ -11,6 +11,6 @@ App( fap_category="Tools", fap_author="@arha & @xMasterX", fap_weburl="https://github.com/arha/flipper-dcf77", - fap_version="1.2", + fap_version="1.3", fap_description="Sends the DCF77 time signal (badly) on the 125khz LFRFID antenna and on GPIO C3 pin", ) diff --git a/apps_source_code/flipper_analog_clock/application.fam b/apps_source_code/flipper_analog_clock/application.fam index ae490fd780a..fdb30a3ff3f 100644 --- a/apps_source_code/flipper_analog_clock/application.fam +++ b/apps_source_code/flipper_analog_clock/application.fam @@ -12,6 +12,6 @@ App( fap_icon="analog_clock.png", # 10x10 1-bit PNG fap_author="@scrolltex", fap_weburl="https://github.com/scrolltex/flipper_analog_clock", - fap_version="1.2", + fap_version="1.3", fap_description="Shows analog clock on Flipper screen", ) diff --git a/apps_source_code/flipper_geiger/application.fam b/apps_source_code/flipper_geiger/application.fam index 4cdad82349c..271cf451376 100644 --- a/apps_source_code/flipper_geiger/application.fam +++ b/apps_source_code/flipper_geiger/application.fam @@ -12,6 +12,6 @@ App( fap_category="GPIO", fap_author="@nmrr", fap_weburl="https://github.com/nmrr/flipperzero-geigercounter", - fap_version="1.3", + fap_version="1.4", fap_description="Works with J305 Geiger tube on external board", ) diff --git a/apps_source_code/flipper_passgen/application.fam b/apps_source_code/flipper_passgen/application.fam index 99661090695..d0826658e14 100644 --- a/apps_source_code/flipper_passgen/application.fam +++ b/apps_source_code/flipper_passgen/application.fam @@ -10,6 +10,6 @@ App( fap_icon="icons/passgen_icon.png", fap_icon_assets="icons", fap_author="@anakod & @henrygab", - fap_version="1.2", + fap_version="1.3", fap_description="Simple password generator", ) diff --git a/apps_source_code/flipper_pong/application.fam b/apps_source_code/flipper_pong/application.fam index cf1604e770f..765b8c39f06 100644 --- a/apps_source_code/flipper_pong/application.fam +++ b/apps_source_code/flipper_pong/application.fam @@ -12,6 +12,6 @@ App( fap_category="Games", fap_author="@nmrr & @SimplyMinimal", fap_weburl="https://github.com/nmrr/flipperzero-pong", - fap_version="1.2", + fap_version="1.3", fap_description="Simple pong game", ) diff --git a/apps_source_code/flipperzero-slots/application.fam b/apps_source_code/flipperzero-slots/application.fam index 2ab7af0cbf4..5c5c284e698 100644 --- a/apps_source_code/flipperzero-slots/application.fam +++ b/apps_source_code/flipperzero-slots/application.fam @@ -12,6 +12,6 @@ App( fap_icon_assets="assets", fap_author="@Daniel-dev-s", fap_weburl="https://github.com/Daniel-dev-s/flipperzero-slots", - fap_version="1.2", + fap_version="1.3", fap_description="Simple Slots simulator game", ) diff --git a/apps_source_code/flipperzero-text2sam/application.fam b/apps_source_code/flipperzero-text2sam/application.fam index 9842fac9206..be38d7d80ba 100644 --- a/apps_source_code/flipperzero-text2sam/application.fam +++ b/apps_source_code/flipperzero-text2sam/application.fam @@ -16,6 +16,6 @@ App( order=20, fap_author="@Round-Pi & (Fixes by @Willy-JL)", fap_weburl="https://github.com/Round-Pi/flipperzero-text2sam", - fap_version="1.3", + fap_version="1.4", fap_description="Convert text to speech on your Flipper Zero with SAM (Software Automatic Mouth).", ) diff --git a/apps_source_code/flipperzero-tuning-fork/application.fam b/apps_source_code/flipperzero-tuning-fork/application.fam index 1364bb6e8a8..d308b02ac82 100644 --- a/apps_source_code/flipperzero-tuning-fork/application.fam +++ b/apps_source_code/flipperzero-tuning-fork/application.fam @@ -13,6 +13,6 @@ App( order=20, fap_author="@besya & (Fixes by @Willy-JL)", fap_weburl="https://github.com/besya/flipperzero-tuning-fork", - fap_version="1.1", + fap_version="1.2", fap_description="Tuning fork for tuning musical instruments", ) diff --git a/apps_source_code/flipperzero-yatzee-main/application.fam b/apps_source_code/flipperzero-yatzee-main/application.fam index 96f37254052..a3dd34f2e83 100644 --- a/apps_source_code/flipperzero-yatzee-main/application.fam +++ b/apps_source_code/flipperzero-yatzee-main/application.fam @@ -11,6 +11,6 @@ App( fap_icon_assets="images", fap_author="@emfleak", fap_weburl="https://github.com/emfleak/flipperzero-yatzee", - fap_version="1.1", + fap_version="1.2", fap_description="Yahtzee game", ) diff --git a/apps_source_code/fpz_cntdown_timer-main/application.fam b/apps_source_code/fpz_cntdown_timer-main/application.fam index 6a58d8dda14..8968cacbf89 100644 --- a/apps_source_code/fpz_cntdown_timer-main/application.fam +++ b/apps_source_code/fpz_cntdown_timer-main/application.fam @@ -13,6 +13,6 @@ App( fap_category="Tools", fap_author="@0w0mewo", fap_weburl="https://github.com/0w0mewo/fpz_cntdown_timer", - fap_version="1.3", + fap_version="1.4", fap_description="Simple count down timer", ) diff --git a/apps_source_code/fz-reaction-game/application.fam b/apps_source_code/fz-reaction-game/application.fam index c31575eacd7..f5926161e38 100644 --- a/apps_source_code/fz-reaction-game/application.fam +++ b/apps_source_code/fz-reaction-game/application.fam @@ -9,6 +9,6 @@ App( fap_icon="icon.png", fap_author="@Milk-Cool", fap_weburl="https://github.com/Milk-Cool/fz-reaction-game", - fap_version="1.1", + fap_version="1.2", fap_description="A simple reaction test game", ) diff --git a/apps_source_code/game_of_life/application.fam b/apps_source_code/game_of_life/application.fam index fad1cdd326c..36eb1b26c6f 100644 --- a/apps_source_code/game_of_life/application.fam +++ b/apps_source_code/game_of_life/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@tgxn (original by @itsyourbedtime)", fap_weburl="https://github.com/tgxn/flipperzero-firmware/blob/dev/applications/game_of_life/game_of_life.c", - fap_version="1.1", + fap_version="1.2", fap_description="Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.", ) diff --git a/apps_source_code/gpio_7segment/application.fam b/apps_source_code/gpio_7segment/application.fam index 526bd0d5513..a810ea094d8 100644 --- a/apps_source_code/gpio_7segment/application.fam +++ b/apps_source_code/gpio_7segment/application.fam @@ -9,6 +9,6 @@ App( fap_category="GPIO", fap_author="@jamisonderek", fap_weburl="https://github.com/jamisonderek/flipper-zero-tutorials/tree/main/gpio", - fap_version="1.1", + fap_version="1.2", fap_description="Control a 7-segment display with GPIO pins", ) diff --git a/apps_source_code/gpio_pins_reader/application.fam b/apps_source_code/gpio_pins_reader/application.fam index f9c1a6cb3c5..be46e2ca492 100644 --- a/apps_source_code/gpio_pins_reader/application.fam +++ b/apps_source_code/gpio_pins_reader/application.fam @@ -9,6 +9,6 @@ App( fap_icon="icon.png", fap_author="@aureli1c", fap_weburl="https://github.com/aureli1c/flipperzero_GPIO_read", - fap_version="1.1", + fap_version="1.2", fap_description="Read GPIO pins states, and display them on the screen", ) diff --git a/apps_source_code/hex_editor/application.fam b/apps_source_code/hex_editor/application.fam index 3c52217a5b0..7ad0108ac42 100644 --- a/apps_source_code/hex_editor/application.fam +++ b/apps_source_code/hex_editor/application.fam @@ -15,6 +15,6 @@ App( fap_icon_assets="icons", fap_author="@dunaevai135", fap_weburl="https://github.com/dunaevai135/flipper-zero-hex_editor", - fap_version="1.2", + fap_version="1.3", fap_description="Read text files line by line and edit them without a computer or smartphone.", ) diff --git a/apps_source_code/mandelbrot/application.fam b/apps_source_code/mandelbrot/application.fam index 9fab0bd5740..08bab43819f 100644 --- a/apps_source_code/mandelbrot/application.fam +++ b/apps_source_code/mandelbrot/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@Possibly-Matt", fap_weburl="https://github.com/Possibly-Matt", - fap_version="1.1", + fap_version="1.2", fap_description="The Mandelbrot set is the set of all so-called (complex) numbers that meet Mandelbrots simple arithmetic criterion.", ) diff --git a/apps_source_code/mifare_fuzzer/application.fam b/apps_source_code/mifare_fuzzer/application.fam index 61001e1f56a..e55385f8e8b 100644 --- a/apps_source_code/mifare_fuzzer/application.fam +++ b/apps_source_code/mifare_fuzzer/application.fam @@ -15,6 +15,6 @@ App( fap_icon_assets="images", fap_author="@spheeere98 @Sil333033", fap_weburl="https://github.com/spheeere98/mifare_fuzzer", - fap_version="1.3", + fap_version="1.4", fap_description="App emulates Mifare Classic cards with various UIDs to check how reader reacts on them", ) diff --git a/apps_source_code/montyhall/application.fam b/apps_source_code/montyhall/application.fam index 7ea6ae51ed4..40be2f5dc74 100644 --- a/apps_source_code/montyhall/application.fam +++ b/apps_source_code/montyhall/application.fam @@ -10,6 +10,6 @@ App( fap_icon="Monty.png", fap_category="Games", fap_author="@DevMilanIan", - fap_version="1.1", + fap_version="1.2", fap_description="Monty Hall asks you to guess which closed door a prize is behind.", ) diff --git a/apps_source_code/musictracker/application.fam b/apps_source_code/musictracker/application.fam index 6f0fb39c6b4..980a45494d7 100644 --- a/apps_source_code/musictracker/application.fam +++ b/apps_source_code/musictracker/application.fam @@ -12,6 +12,6 @@ App( fap_category="Media", fap_author="@DrZlo13", fap_weburl="https://github.com/DrZlo13/flipper-zero-music-tracker", - fap_version="1.2", + fap_version="1.3", fap_description="App plays hardcoded tracker song", ) diff --git a/apps_source_code/ocarina/application.fam b/apps_source_code/ocarina/application.fam index 7fae16a0795..a40dfc6cfce 100644 --- a/apps_source_code/ocarina/application.fam +++ b/apps_source_code/ocarina/application.fam @@ -12,6 +12,6 @@ App( fap_icon_assets="icons", fap_author="@invalidna-me", fap_weburl="https://github.com/invalidna-me/flipperzero-ocarina", - fap_version="1.1", + fap_version="1.2", fap_description="A basic Ocarina (of Time), Controls are the same as the N64 version of the Ocarina of Time", ) diff --git a/apps_source_code/paint/application.fam b/apps_source_code/paint/application.fam index 07c70810aff..62fc50e5729 100644 --- a/apps_source_code/paint/application.fam +++ b/apps_source_code/paint/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@n-o-T-I-n-s-a-n-e", fap_weburl="https://github.com/n-o-T-I-n-s-a-n-e", - fap_version="1.1", + fap_version="1.2", fap_description="A basic Paint app, Click Ok to draw dot, hold Ok to enable drawing continuously, hold Back to clear the screen", ) diff --git a/apps_source_code/pomodoro/application.fam b/apps_source_code/pomodoro/application.fam index 3ac5042edc6..e5488a15a5c 100644 --- a/apps_source_code/pomodoro/application.fam +++ b/apps_source_code/pomodoro/application.fam @@ -14,6 +14,6 @@ App( fap_icon_assets="icons", fap_author="@sbrin", fap_weburl="https://github.com/sbrin/flipperzero_pomodoro", - fap_version="1.3", + fap_version="1.4", fap_description="Use your Flipper Zero as a Pomodoro Timer.", ) diff --git a/apps_source_code/racegame/application.fam b/apps_source_code/racegame/application.fam index ec738a3a4da..13f8c0b4d28 100644 --- a/apps_source_code/racegame/application.fam +++ b/apps_source_code/racegame/application.fam @@ -12,6 +12,6 @@ App( fap_category="Games", fap_author="@zyuhel", fap_weburl="https://github.com/zyuhel/flipperzero-racegame", - fap_version="1.1", + fap_version="1.2", fap_description="Race game inspired by Race game in BrickGame 9999 in 1.", ) diff --git a/apps_source_code/resistors/application.fam b/apps_source_code/resistors/application.fam index bddafaeb616..073a4809175 100644 --- a/apps_source_code/resistors/application.fam +++ b/apps_source_code/resistors/application.fam @@ -8,7 +8,7 @@ App( stack_size=2 * 1024, fap_category="Tools", # Optional values - fap_version=(1, 2), + fap_version=(1, 3), fap_icon="resistors.png", fap_description="Resistor calculations", fap_author="Lewis Westbury", diff --git a/apps_source_code/reversi/application.fam b/apps_source_code/reversi/application.fam index 75af5c99a90..e38431f85fb 100644 --- a/apps_source_code/reversi/application.fam +++ b/apps_source_code/reversi/application.fam @@ -13,7 +13,7 @@ App( fap_category="Games", fap_icon_assets_symbol="game_reversi", fap_author="@dimat", - fap_weburl="https://github.com/zyuhel/flipperzero-racegame", + fap_weburl="https://github.com/dimat/flipperzero-reversi", fap_version="1.3", fap_description="Reversi game, the game controls should be intuitive. Longs press on OK opens the menu to start a new game.", ) diff --git a/apps_source_code/rootoflife/application.fam b/apps_source_code/rootoflife/application.fam index 105abdf583c..1443cb17075 100644 --- a/apps_source_code/rootoflife/application.fam +++ b/apps_source_code/rootoflife/application.fam @@ -13,6 +13,6 @@ App( fap_icon_assets_symbol="roots_of_life_game", fap_author="@Xorboo", fap_weburl="https://github.com/Xorboo/root-of-life", - fap_version="1.1", + fap_version="1.2", fap_description="A zen-puzzle game for FlipperZero, puzzle made on GlobalGameJam23 (theme: Roots)", ) diff --git a/apps_source_code/rubiks_cube_scrambler/application.fam b/apps_source_code/rubiks_cube_scrambler/application.fam index 871c90a8020..2ee6a800dd8 100644 --- a/apps_source_code/rubiks_cube_scrambler/application.fam +++ b/apps_source_code/rubiks_cube_scrambler/application.fam @@ -19,6 +19,6 @@ App( fap_icon="cube.png", fap_author="@RaZeSloth", fap_weburl="https://github.com/RaZeSloth/flipperzero-rubiks-cube-scrambler", - fap_version="1.2", + fap_version="1.3", fap_description="App generates random moves to scramble a Rubik's cube.", ) diff --git a/apps_source_code/scorched_tanks/application.fam b/apps_source_code/scorched_tanks/application.fam index da2b8a61bd3..2a74599de4f 100644 --- a/apps_source_code/scorched_tanks/application.fam +++ b/apps_source_code/scorched_tanks/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@jasniec", fap_weburl="https://github.com/jasniec/flipper-scorched-tanks-game", - fap_version="1.2", + fap_version="1.3", fap_description="A Flipper Zero game inspired by scorched earth", ) diff --git a/apps_source_code/servotester/application.fam b/apps_source_code/servotester/application.fam index 46f255053a1..efc7532270b 100644 --- a/apps_source_code/servotester/application.fam +++ b/apps_source_code/servotester/application.fam @@ -12,6 +12,6 @@ App( fap_category="GPIO", fap_author="Alexander Semion", fap_weburl="https://github.com/spin7ion/flipper-servotester", - fap_version="1.1", + fap_version="1.2", fap_description="Application uses A7 pin for servo PWM output. Has different modes: Manual, Center, Auto.", ) diff --git a/apps_source_code/t-rex-runner/application.fam b/apps_source_code/t-rex-runner/application.fam index b59d2b870f5..080d6337c37 100644 --- a/apps_source_code/t-rex-runner/application.fam +++ b/apps_source_code/t-rex-runner/application.fam @@ -12,6 +12,6 @@ App( order=36, fap_author="@Rrycbarm", fap_weburl="https://github.com/Rrycbarm/t-rex-runner", - fap_version="1.3", + fap_version="1.4", fap_description="Play the port of the Chrome browser T-Rex game on your Flipper Zero.", ) diff --git a/apps_source_code/timelapse/application.fam b/apps_source_code/timelapse/application.fam index 6dc6a3bc4c3..0053d7fc59a 100644 --- a/apps_source_code/timelapse/application.fam +++ b/apps_source_code/timelapse/application.fam @@ -10,7 +10,7 @@ App( fap_icon_assets="icons", fap_icon="zeitraffer.png", fap_category="GPIO", - fap_version="1.1", + fap_version="1.2", fap_description="Simple intervalometer app, works via GPIO pins.", fap_author="Aurelius Rosenbaum", fap_weburl="https://github.com/theageoflove/flipperzero-zeitraffer", diff --git a/apps_source_code/videopoker/application.fam b/apps_source_code/videopoker/application.fam index 85ecf7ac224..9165844dd11 100644 --- a/apps_source_code/videopoker/application.fam +++ b/apps_source_code/videopoker/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@PixlEmly", fap_weburl="https://github.com/PixlEmly", - fap_version="1.1", + fap_version="1.2", fap_description="Video poker is a casino game based on five-card draw poker", ) diff --git a/base_pack/arkanoid/application.fam b/base_pack/arkanoid/application.fam index 50bd202b07d..8b9004111f9 100644 --- a/base_pack/arkanoid/application.fam +++ b/base_pack/arkanoid/application.fam @@ -9,6 +9,6 @@ App( fap_icon="arkanoid_10px.png", fap_category="Games", fap_author="@xMasterX & @gotnull", - fap_version="1.1", + fap_version="1.2", fap_description="Arkanoid Game", ) diff --git a/base_pack/barcode_gen/application.fam b/base_pack/barcode_gen/application.fam index 2af68970098..61f82226363 100644 --- a/base_pack/barcode_gen/application.fam +++ b/base_pack/barcode_gen/application.fam @@ -11,6 +11,6 @@ App( fap_file_assets="barcode_encoding_files", fap_author="@Kingal1337", fap_weburl="https://github.com/Kingal1337/flipper-barcode-generator", - fap_version="1.2", + fap_version="1.3", fap_description="App allows you to display various barcodes on flipper screen", ) diff --git a/base_pack/bomberduck/application.fam b/base_pack/bomberduck/application.fam index f5c0c7ac897..1cd1f03ef6d 100644 --- a/base_pack/bomberduck/application.fam +++ b/base_pack/bomberduck/application.fam @@ -12,6 +12,6 @@ App( fap_category="Games", fap_icon_assets="assets", fap_author="@leo-need-more-coffee & @xMasterX", - fap_version="1.1", + fap_version="1.2", fap_description="Bomberduck(Bomberman) Game", ) diff --git a/base_pack/doom/application.fam b/base_pack/doom/application.fam index 7fe04d1d6b1..eced9b66367 100644 --- a/base_pack/doom/application.fam +++ b/base_pack/doom/application.fam @@ -13,6 +13,6 @@ App( fap_category="Games", fap_icon_assets="assets", fap_author="@xMasterX & @Svarich & @hedger (original code by @p4nic4ttack)", - fap_version="1.3", + fap_version="1.4", fap_description="Will it run Doom?", ) diff --git a/base_pack/dtmf_dolphin/application.fam b/base_pack/dtmf_dolphin/application.fam index 5f3bb6a4573..522b79cbc00 100644 --- a/base_pack/dtmf_dolphin/application.fam +++ b/base_pack/dtmf_dolphin/application.fam @@ -13,6 +13,6 @@ App( order=20, fap_category="Tools", fap_author="@litui & @xMasterX", - fap_version="1.2", + fap_version="1.3", fap_description="DTMF (Dual-Tone Multi-Frequency) dialer, Bluebox, and Redbox.", ) diff --git a/base_pack/flappy_bird/application.fam b/base_pack/flappy_bird/application.fam index 3588de0b920..9ef48b89957 100644 --- a/base_pack/flappy_bird/application.fam +++ b/base_pack/flappy_bird/application.fam @@ -10,6 +10,6 @@ App( fap_category="Games", fap_icon_assets="assets", fap_author="@DroomOne & @xMasterX", - fap_version="1.1", + fap_version="1.2", fap_description="Flappy Bird Game", ) diff --git a/base_pack/game15/application.fam b/base_pack/game15/application.fam index de08f2ca5f0..2845aeb2381 100644 --- a/base_pack/game15/application.fam +++ b/base_pack/game15/application.fam @@ -9,6 +9,6 @@ App( order=30, fap_category="Games", fap_author="@x27", - fap_version="1.1", + fap_version="1.2", fap_description="Logic Game", ) diff --git a/base_pack/game_2048/application.fam b/base_pack/game_2048/application.fam index 8c22f6270fd..7e491ce9bde 100644 --- a/base_pack/game_2048/application.fam +++ b/base_pack/game_2048/application.fam @@ -11,6 +11,6 @@ App( fap_icon="game_2048.png", fap_category="Games", fap_author="@eugene-kirzhanov", - fap_version="1.4", + fap_version="1.5", fap_description="Play the port of the 2048 game on Flipper Zero.", ) \ No newline at end of file diff --git a/base_pack/gps_nmea_uart/application.fam b/base_pack/gps_nmea_uart/application.fam index 7f6e605eed5..af2043345fc 100644 --- a/base_pack/gps_nmea_uart/application.fam +++ b/base_pack/gps_nmea_uart/application.fam @@ -16,6 +16,6 @@ App( ), ], fap_author="@ezod & @xMasterX", - fap_version="1.3", + fap_version="1.4", fap_description="Works with GPS modules via UART, using NMEA protocol.", ) diff --git a/base_pack/heap_defence_game/application.fam b/base_pack/heap_defence_game/application.fam index 2942f30f8c0..ab71b353939 100644 --- a/base_pack/heap_defence_game/application.fam +++ b/base_pack/heap_defence_game/application.fam @@ -9,6 +9,6 @@ App( fap_icon="box.png", fap_icon_assets="assets_images", fap_author="@xMasterX (original implementation by @wquinoa & @Vedmein)", - fap_version="1.2", + fap_version="1.3", fap_description="Heap Defence game from hackathon (aka Stack Attack)", ) diff --git a/base_pack/ir_scope/application.fam b/base_pack/ir_scope/application.fam index ceaa629f712..6fd3192df56 100644 --- a/base_pack/ir_scope/application.fam +++ b/base_pack/ir_scope/application.fam @@ -8,6 +8,6 @@ App( fap_icon="ir_scope.png", fap_category="Infrared", fap_author="@kallanreed", - fap_version="1.2", + fap_version="1.3", fap_description="App allows to see incoming IR signals.", ) diff --git a/base_pack/metronome/application.fam b/base_pack/metronome/application.fam index 12019f3e1ce..d8065f47652 100644 --- a/base_pack/metronome/application.fam +++ b/base_pack/metronome/application.fam @@ -12,6 +12,6 @@ App( stack_size=2 * 1024, order=20, fap_author="@panki27 & @xMasterX", - fap_version="1.2", + fap_version="1.3", fap_description="Metronome app", ) diff --git a/base_pack/morse_code/application.fam b/base_pack/morse_code/application.fam index 00a108b1698..df8d9cf38ec 100644 --- a/base_pack/morse_code/application.fam +++ b/base_pack/morse_code/application.fam @@ -11,6 +11,6 @@ App( fap_icon="morse_code_10px.png", fap_category="Media", fap_author="@wh00hw & @xMasterX", - fap_version="1.1", + fap_version="1.2", fap_description="Simple Morse Code parser", ) \ No newline at end of file diff --git a/base_pack/multi_converter/application.fam b/base_pack/multi_converter/application.fam index 25d7bc4c584..05403e9e142 100644 --- a/base_pack/multi_converter/application.fam +++ b/base_pack/multi_converter/application.fam @@ -9,6 +9,6 @@ App( fap_icon="converter_10px.png", fap_category="Tools", fap_author="@theisolinearchip", - fap_version="1.1", + fap_version="1.2", fap_description="A multi-unit converter written with an easy and expandable system for adding new units and conversion methods", ) diff --git a/base_pack/pocsag_pager/application.fam b/base_pack/pocsag_pager/application.fam index aee3b46c111..d9301b884b1 100644 --- a/base_pack/pocsag_pager/application.fam +++ b/base_pack/pocsag_pager/application.fam @@ -10,6 +10,6 @@ App( fap_category="Sub-GHz", fap_icon_assets="images", fap_author="@xMasterX & @Shmuma", - fap_version="1.2", + fap_version="1.3", fap_description="App can capture POCSAG 1200 messages on CC1101 supported frequencies.", ) diff --git a/base_pack/protoview/application.fam b/base_pack/protoview/application.fam index 705fb1b0bfc..920ee89768e 100644 --- a/base_pack/protoview/application.fam +++ b/base_pack/protoview/application.fam @@ -9,6 +9,6 @@ App( fap_icon="appicon.png", fap_category="Sub-GHz", fap_author="@antirez & (fixes by @xMasterX)", - fap_version="1.1", + fap_version="1.2", fap_description="Digital signal detection, visualization, editing and reply tool", ) diff --git a/base_pack/sentry_safe/application.fam b/base_pack/sentry_safe/application.fam index cb476439b6f..2fa3961bbd3 100644 --- a/base_pack/sentry_safe/application.fam +++ b/base_pack/sentry_safe/application.fam @@ -9,6 +9,6 @@ App( fap_icon="safe_10px.png", fap_category="GPIO", fap_author="@H4ckd4ddy & @xMasterX (ported to latest firmware)", - fap_version="1.2", + fap_version="1.3", fap_description="App exploiting vulnerability to open any Sentry Safe and Master Lock electronic safe without any pin code via UART pins.", ) diff --git a/base_pack/spectrum_analyzer/application.fam b/base_pack/spectrum_analyzer/application.fam index 314b0e61ddd..6c7d4638c6e 100644 --- a/base_pack/spectrum_analyzer/application.fam +++ b/base_pack/spectrum_analyzer/application.fam @@ -9,6 +9,6 @@ App( fap_icon="spectrum_10px.png", fap_category="Sub-GHz", fap_author="@xMasterX & @theY4Kman & @ALEEF02 (original by @jolcese)", - fap_version="1.2", + fap_version="1.3", fap_description="Displays a spectrogram chart to visually represent RF signals around you.", ) diff --git a/base_pack/swd_probe/application.fam b/base_pack/swd_probe/application.fam index 5ff9668485c..405d6f52b20 100644 --- a/base_pack/swd_probe/application.fam +++ b/base_pack/swd_probe/application.fam @@ -10,6 +10,6 @@ App( fap_category="GPIO", fap_icon_assets="icons", fap_author="@g3gg0 & (fixes by @xMasterX)", - fap_version="1.1", + fap_version="1.2", fap_description="ARM SWD (Single Wire Debug) Probe", ) diff --git a/base_pack/tetris_game/application.fam b/base_pack/tetris_game/application.fam index 23cee84de28..a4117aa6ae3 100644 --- a/base_pack/tetris_game/application.fam +++ b/base_pack/tetris_game/application.fam @@ -9,7 +9,7 @@ App( fap_icon="tetris_10px.png", fap_category="Games", fap_author="@xMasterX & @jeffplang & @noiob", - fap_version="1.3", + fap_version="1.4", fap_description="Tetris Game", fap_icon_assets="assets" ) diff --git a/base_pack/text_viewer/application.fam b/base_pack/text_viewer/application.fam index c186f4a3dec..69c45b9d783 100644 --- a/base_pack/text_viewer/application.fam +++ b/base_pack/text_viewer/application.fam @@ -13,6 +13,6 @@ App( fap_category="Tools", fap_icon_assets="icons", fap_author="@Willy-JL", # Original by @kowalski7cc & @kyhwana, new has code borrowed from archive > show - fap_version="1.5", + fap_version="1.6", fap_description="Text viewer application", ) diff --git a/base_pack/tictactoe_game/application.fam b/base_pack/tictactoe_game/application.fam index 8a2bfd4117e..88e77b98017 100644 --- a/base_pack/tictactoe_game/application.fam +++ b/base_pack/tictactoe_game/application.fam @@ -9,6 +9,6 @@ App( fap_icon="tictactoe_10px.png", fap_category="Games", fap_author="@xMasterX & @gotnull", - fap_version="1.1", + fap_version="1.2", fap_description="Tic Tac Toe game, for 2 players, play on one device", ) diff --git a/base_pack/uart_terminal/application.fam b/base_pack/uart_terminal/application.fam index 47fa996aeec..35f975f7d79 100644 --- a/base_pack/uart_terminal/application.fam +++ b/base_pack/uart_terminal/application.fam @@ -10,6 +10,6 @@ App( fap_category="GPIO", fap_icon_assets="assets", fap_author="@cool4uma & @rnadyrshin & (some fixes by @xMasterX)", - fap_version="1.4", + fap_version="1.5", fap_description="Control various devices via the Flipper Zero UART interface.", ) diff --git a/base_pack/wav_player/application.fam b/base_pack/wav_player/application.fam index 37a5953977a..96d146db03d 100644 --- a/base_pack/wav_player/application.fam +++ b/base_pack/wav_player/application.fam @@ -9,6 +9,6 @@ App( fap_category="Media", fap_icon_assets="images", fap_author="@DrZlo13 & (ported, fixed by @xMasterX), (improved by @LTVA1)", - fap_version="1.1", + fap_version="1.2", fap_description="Audio player for WAV files, recommended to convert files to unsigned 8-bit PCM stereo, but it may work with others too", ) diff --git a/base_pack/zombiez/application.fam b/base_pack/zombiez/application.fam index 0dd50d86756..bb851c0b8b5 100644 --- a/base_pack/zombiez/application.fam +++ b/base_pack/zombiez/application.fam @@ -9,6 +9,6 @@ App( fap_icon="zombie_10px.png", fap_category="Games", fap_author="@DevMilanIan & @xMasterX, (original By @Dooskington)", - fap_version="1.1", + fap_version="1.2", fap_description="Defend your walls from the zombies", ) From 9e29919a62459df80e9acb2a3220eb14cbb6276f Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 01:11:16 +0300 Subject: [PATCH 23/36] fix icons --- apps_source_code/calculator/calcIcon.png | Bin 2002 -> 246 bytes .../counter/icons/counter_icon.png | Bin 182 -> 167 bytes apps_source_code/ocarina/music_10px.png | Bin 142 -> 299 bytes apps_source_code/reversi/game_reversi.png | Bin 235 -> 278 bytes base_pack/barcode_gen/barcode_app.c | 1 - base_pack/pocsag_pager/README.md | 23 ++++++++++++------ base_pack/swd_probe/icons/app.png | Bin 179 -> 301 bytes base_pack/zombiez/zombie_10px.png | Bin 8741 -> 4853 bytes .../FlipperNightStand_clock/clock_app.c | 2 +- 9 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps_source_code/calculator/calcIcon.png b/apps_source_code/calculator/calcIcon.png index 05cda6ce675061565bcc15d251f85a8d599b76af..8c1ec302d5f0cfc482cf1701865b6e8d11152c6e 100644 GIT binary patch delta 229 zcmVZ!j8{WudwN zDWy_VnlYSA(}cEd(RJMy6z&pejDgmgOriE30;6dhM;e?Aw+}MsoG*%k>Z+>xyHPS8 f#{tgy)826bx^Zc@O}3;>-4=Fg=>}R4tG=1{CK;NUH_l9( zwBVuMytwxkJlK{}g~b+6{-J{CUPL|UT|q1AVg(Ns6zZEyl8sQiy%JD# zf5S(qT%5aEojN@|Jvlj{($Ue;;o;%v=;-nB@xj5t@bK`?&d%Q6UM`p0*x1MFMw0>KEnPDFL%BwCWi`GrkAwCZg zu`%EBLuyUqj<-VSEa8N;am@=#-0_Ep9P6PHx1d;}6;9&1H@z0&TWhmbXKl$b5I253 zH&|?$6v4*{WLthCh|N}sYXh6~Jyi=F+crs-N?bXO$SzuQ>?DaWtMM{$L{VflgO_Yo zftv9wD~qx$h^ipvfuxxQ)szZs=flx>EL)6_YtC1m@5G~0iK{0`XbM8J+2osfoK1c%$Ok0UA>5@WtlTUoWQ`r zGnEoYlj1!OnW9}#= z(d(wEO0q54vJG@q#X!+0ny$DCkY&ThiUesewTt#bIzz_4`}sII6RswN=`$sGG2?j&iD$Rdb#H_x%iF9dYM-jJ0u7IC^U;J(x&|fAN#~Cd*HL?CH1=X8WU$RTrl9BW zA~TDLn>1mB%QZTLhx1OjKp`<)IlqjH@#Ft2Bg1y;FsNaA($Wp=FRUn}XHx&vio)3g zEAW@BH=WrvCBiZ7`~?e^eN_uit*_i8udvyZG8YHq)$ diff --git a/apps_source_code/counter/icons/counter_icon.png b/apps_source_code/counter/icons/counter_icon.png index 47efe68db82b1e6031d6fa1da1cb56a9cf6fc512..5b27155a3dcf787e0985b35776ab7b2d1f963f3b 100644 GIT binary patch delta 151 zcmV;I0BHZV0jB|w7=H)`0001uGS9sL0004VQb$4nuFf3k0001CNklMj8~$BU3^!|p*sur z*&zBL3)GL*YFypLbIr!pzHmLJ$MZ&W<54!wYYSaQAB5y-^$Eal|aXmRf1PGD@$~d_5Qv`$sg;H219qR1lS)?S?*vrGz zl+@J4v*=jTqBfpGs*9Q$dE^)QEtPBK>2ruZ#PEDJhy7=#h2lWd7(8A5T-G@yGywqB CEkQc~ diff --git a/apps_source_code/ocarina/music_10px.png b/apps_source_code/ocarina/music_10px.png index d41eb0db8c822c60be6c097393b3682680b81a6c..94a76c88e0c6977682f9063b0d25ec039da80e69 100644 GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1idXey=`096rhltr;B3<$MxhNg$)nenGe5b z4!Ba&&?wn+i{IdnJp;p?I^K`p&!#T`s#Gm;jVMV;EJ?LWE=mPb3`PbkYkei>9nO2EgL-G<2RiFk2Pgg&ebxsLQ01!t`Gynhq delta 98 zcmZ3@)W@fnocf*ndEZEx;$l^?w(T#jxw^E`y2La<L@)dJmum22WQ%mvv4FO#qwHOicg) delta 204 zcmbQn^qO&k1Sba@0|P^^(fPd-6@}|9QX@Rme0>?TfMOgBjP02WEI<|`5K93u0|V0n zCb$UK0%imoBq_0B)_EWm=jq}YA|ct^AINpUfW!Ihh2Qem&##@Bs-4}+n&TRm(^Y(; z?u7vJfrz$=kG+Ir)7URl*YK^9y4KvsIX`njxgN@xNA($zjE diff --git a/base_pack/barcode_gen/barcode_app.c b/base_pack/barcode_gen/barcode_app.c index 730cdf19b85..f84830ef58a 100644 --- a/base_pack/barcode_gen/barcode_app.c +++ b/base_pack/barcode_gen/barcode_app.c @@ -3,7 +3,6 @@ #include "barcode_app_icons.h" #include #include -#include /** * Opens a file browser dialog and returns the filepath of the selected file diff --git a/base_pack/pocsag_pager/README.md b/base_pack/pocsag_pager/README.md index 408d264f0d7..6db87e32889 100644 --- a/base_pack/pocsag_pager/README.md +++ b/base_pack/pocsag_pager/README.md @@ -1,6 +1,6 @@ # Flipper POCSAG Receiver plugin -### Protocol implementation made by @Shmuma + 512, 2400 speeds support by @htotoo +## Protocol implementation made by @Shmuma + 512, 2400 speeds support by @htotoo Plugin based on [Weather Station](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/plugins/weather_station) from OFW Icons by @Svaarich @@ -12,13 +12,20 @@ Check datasheet and add required frequency in config file (see details below) Default frequency is set to DAPNET - `439987500` -To add new presets and frequencies create file `yourMicroSD/pocsag/settings.txt`
-And put [THIS](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/applications/main/subghz/resources/subghz/assets/setting_user.example) file contents into it, and edit this example for yourself, add needed frequencies
-Warning!!! This file is EXAMPLE! It contains frequencies that are commented with `#`
-`#` Is a comment symbol, if that symbol is present at the beggining of the line, that means this line will be ignored!
-To add custom frequency you need to uncomment the line and edit numbers keeping its size (zeros at the end) `Frequency: 433000000`
-To edit default freqency follow same procedure
-All custom frequencies added from this file will be at the end of the list in the frequency selector in the app! Scroll frequencies to the end to find your custom freq.
+To add new presets and frequencies create file `yourMicroSD/pocsag/settings.txt` + +And put [THIS](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/applications/main/subghz/resources/subghz/assets/setting_user.example) file contents into it, and edit this example for yourself, add needed frequencies + +Warning!!! This file is EXAMPLE! It contains frequencies that are commented with `#` + +`#` Is a comment symbol, if that symbol is present at the beggining of the line, that means this line will be ignored! + +To add custom frequency you need to uncomment the line and edit numbers keeping its size (zeros at the end) `Frequency: 433000000` + +To edit default freqency follow same procedure + +All custom frequencies added from this file will be at the end of the list in the frequency selector in the app! Scroll frequencies to the end to find your custom freq. + Default list > Custom list diff --git a/base_pack/swd_probe/icons/app.png b/base_pack/swd_probe/icons/app.png index 6949ce78d11d5aa0a40b3cf5253e0e297aab47ad..7df42e578e78711b834fa36d7a6f541e24b6c7c4 100644 GIT binary patch literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1idVjdRlR{1yD%A)5S4_<9hOs`i6(An4OuK z4+~1%JanMoKx1Mk^Wp!@3^UWYyjCq={R*g7wZt`|BqgyV)hf9t6-Y4{85o)98kp%C znuHjbTNxTy85wFDSXvnv?7sN;ABu+D{FKbJO57Sw^+Y=XH86O(`njxgN@xNA$)``3 delta 136 zcmZ3>w3%^&gfs^m0|P^^(fPeViY>|8-33Sk!B6Mi^%Jw@lAbfMGBWetyPDnz6m;-( zaSV~TytU7ek3oThS@(av@$&?aBP({?SZbnpooj*ZiANJk${RRT3vFVdQ&MBb@0DGD)`Tzg` diff --git a/base_pack/zombiez/zombie_10px.png b/base_pack/zombiez/zombie_10px.png index 37363ec042bf25445d4acbb150ceccf712807576..05f78a6c30ca06b58441102dd6c6f5cba4606670 100644 GIT binary patch literal 4853 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 KCGwd*D*Rv4lXA-d literal 8741 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 diff --git a/non_catalog_apps/FlipperNightStand_clock/clock_app.c b/non_catalog_apps/FlipperNightStand_clock/clock_app.c index 4f2fe9cafbb..33ba7c4d283 100644 --- a/non_catalog_apps/FlipperNightStand_clock/clock_app.c +++ b/non_catalog_apps/FlipperNightStand_clock/clock_app.c @@ -4,8 +4,8 @@ #include #include +#include #include -#include #include "clock_app.h" From 7c0871feda4555afdf5960e86b8999173f59fdc4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 02:15:48 +0300 Subject: [PATCH 24/36] redraw manually just in case --- apps_source_code/calculator/calcIcon.png | Bin 246 -> 142 bytes .../counter/icons/counter_icon.png | Bin 167 -> 145 bytes apps_source_code/ocarina/music_10px.png | Bin 299 -> 140 bytes apps_source_code/reversi/game_reversi.png | Bin 278 -> 139 bytes base_pack/swd_probe/icons/app.png | Bin 301 -> 136 bytes base_pack/zombiez/zombie_10px.png | Bin 4853 -> 157 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps_source_code/calculator/calcIcon.png b/apps_source_code/calculator/calcIcon.png index 8c1ec302d5f0cfc482cf1701865b6e8d11152c6e..bfad92a2b66dd7c09a1b8ba85c82eec55c0acda6 100644 GIT binary patch delta 100 zcmV-q0Gt2z0geHXFO4geqsLgW62rrD-rg_VE0hk_u<@li++z;K$J zFEE-cg;m^c+%FWUHl2+FY`tpg4vK46j~cL2zusxXxc^V3AWP%TtLwM`0000Z+>xyHPS8#{tgy)826bx^Zc^kTt6x>(eUBxgDYk^~UdBN-yZ zmY@a=P@k?$RciN+pr9=J18vmnwyO=zUTtBy`g%;2Pmkv{@CHYzTKhOBL}dT~002ov JPDHLkV1lY9D*gZf delta 125 zcmV-@0D}LK0jB|wF?L}|L_t(2Q+-g;3IH((vi<)z+hO3SLD$QysgXf4&pG%jk_Z4< zAOe|Ld}F=tizq_>l+as@SE7Vnd{@h%I}7*OAo?H+)Q{C_T;0WU&BoQfa6P8S^G0*y fQ8vzN3tdJZgyd=ULY~%n00000NkvXXu0mjf70fyN diff --git a/apps_source_code/ocarina/music_10px.png b/apps_source_code/ocarina/music_10px.png index 94a76c88e0c6977682f9063b0d25ec039da80e69..1c0046ad38aecdc7980004f2d0baa2fd2aef2ba7 100644 GIT binary patch delta 123 zcmZ3@)WbMIqJ)Eufq|jd==@$F#aJBV?!>U}oXkrg$Ia8lF+?Lc`Op9V|LfUI4xBi_ zA>Qa|EEL3Xi7}`rSaFxDNl?d|iW&L_YuI**-o0+Xuh89msL`Tz!2`$bQr;Jm_~ml^ a7#Yg-Z5}gS$eRE(k-^i|&t;ucLK6T}dXey=`096rhltr;B3<$MxhNg$)nenGe5b z4!Ba&&?wn+i{IdnJp;p?I^K`p&!#T`s#Gm;jVMV;EJ?LWE=mPb3`PbkYkei>9nO2EgL-G<2RiFk2Pgg&ebxsLQ01!t`Gynhq diff --git a/apps_source_code/reversi/game_reversi.png b/apps_source_code/reversi/game_reversi.png index 9175cdf63df3fe6e4548272a8b0cd78fd7261329..75def62b925b2fcb18a2eb058cd2714de4e09707 100644 GIT binary patch delta 122 zcmbQn)Xg|SqL_n?fq|jd==@$F#aJBV?!>U}oXkrg$JNutF+?Lc`Op9V|LfV57?gb! zm6eqvEcI#=S`}OkSWo1nbbADIT=JZ9^~Rs3b%O6CMZP=OvI#TqoNv^6<4(_2mz+E{ Z21i!c$6b*vr+@}Bc)I$ztaD0e0syUSD&+tG literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1iL@)dJmum22WQ%mvv4FO#qwHOicg) diff --git a/base_pack/swd_probe/icons/app.png b/base_pack/swd_probe/icons/app.png index 7df42e578e78711b834fa36d7a6f541e24b6c7c4..5f6d42d110a32983435774ec4a1a46c283c7437d 100644 GIT binary patch delta 119 zcmZ3>)WJAGqJV>qfq|jd==@$F#aJBV?!>U}oXkrg$H~*hF+?Lc`Op9V|LfV57?gb! zm6es5J^1~kmI$bLax9p^5zJ#O+3GJZd~q$CCF5%8i?(dnIEt0;El5mpnc<;P!B90j W@cpDVzJEZ|7(8A5T-G@yGywoyUnQ>q literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xkYHHq`AGmsv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpafHrx4R1idVjdRlR{1yD%A)5S4_<9hOs`i6(An4OuK z4+~1%JanMoKx1Mk^Wp!@3^UWYyjCq={R*g7wZt`|BqgyV)hf9t6-Y4{85o)98kp%C znuHjbTNxTy85wFDSXvnv?7sN;ABu+D{FKbJO57Sw^+Y=XH86O(`njxgN@xNA$)``3 diff --git a/base_pack/zombiez/zombie_10px.png b/base_pack/zombiez/zombie_10px.png index 05f78a6c30ca06b58441102dd6c6f5cba4606670..3680085f123fffff62ec662d07c3a64eaa357e7e 100644 GIT binary patch delta 141 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 KCGwd*D*Rv4lXA-d From cfefb707230b00975aa94331de38612f1646a441 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 03:20:51 +0300 Subject: [PATCH 25/36] fix barcode and nightstandclock --- base_pack/barcode_gen/barcode_app.c | 33 ++++++++++++------- .../FlipperNightStand_clock/clock_app.c | 1 + 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/base_pack/barcode_gen/barcode_app.c b/base_pack/barcode_gen/barcode_app.c index f84830ef58a..ef18859d0a9 100644 --- a/base_pack/barcode_gen/barcode_app.c +++ b/base_pack/barcode_gen/barcode_app.c @@ -13,7 +13,14 @@ * @returns true if a file is selected */ -NotificationApp* notifications = 0; +static NotificationApp* barcode_notifications; + +const NotificationSequence sequence_display_backlight_barcode = { + &message_force_display_brightness_setting_1f, + &message_display_backlight_on, + &message_do_not_reset, + NULL, +}; static bool select_file(const char* folder, FuriString* file_path) { DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); @@ -146,6 +153,8 @@ void select_barcode_item(BarcodeApp* app) { }, true); + notification_message(barcode_notifications, &sequence_display_backlight_barcode); + view_dispatcher_switch_to_view(app->view_dispatcher, BarcodeView); } @@ -301,11 +310,11 @@ void free_app(BarcodeApp* app) { free(app); } -void set_backlight_brightness(float brightness) { - NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); - notifications->settings.display_brightness = brightness; - notification_message(notifications, &sequence_display_backlight_on); -} +/*void set_backlight_brightness(float brightness) { + NotificationApp* barcode_notifications = furi_record_open(RECORD_NOTIFICATION); + barcode_notifications->settings.display_brightness = brightness; + notification_message(barcode_notifications, &sequence_display_backlight_on); +}*/ int32_t barcode_main(void* p) { UNUSED(p); @@ -327,12 +336,12 @@ int32_t barcode_main(void* p) { submenu_add_item(app->main_menu, "Edit Barcode", EditBarcodeItem, submenu_callback, app); - NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + barcode_notifications = furi_record_open(RECORD_NOTIFICATION); // Save original brightness - float originalBrightness = notifications->settings.display_brightness; + //float originalBrightness = barcode_notifications->settings.display_brightness; // force backlight and increase brightness - notification_message_block(notifications, &sequence_display_backlight_enforce_on); - set_backlight_brightness(10); // set to highest + //notification_message(barcode_notifications, &sequence_display_backlight_enforce_on); + //set_backlight_brightness(10); // set to highest /***************************** * Creating Text Input View @@ -439,8 +448,8 @@ int32_t barcode_main(void* p) { view_dispatcher_run(app->view_dispatcher); free_app(app); - notification_message_block(notifications, &sequence_display_backlight_enforce_auto); - set_backlight_brightness(originalBrightness); + notification_message_block(barcode_notifications, &sequence_display_backlight_enforce_auto); + //set_backlight_brightness(originalBrightness); return 0; } diff --git a/non_catalog_apps/FlipperNightStand_clock/clock_app.c b/non_catalog_apps/FlipperNightStand_clock/clock_app.c index 33ba7c4d283..81070908bae 100644 --- a/non_catalog_apps/FlipperNightStand_clock/clock_app.c +++ b/non_catalog_apps/FlipperNightStand_clock/clock_app.c @@ -6,6 +6,7 @@ #include #include +#include #include "clock_app.h" From 0ece7167f37bd43c6c34e4e5464f003d3e83f486 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 03:23:49 +0300 Subject: [PATCH 26/36] free properly --- base_pack/barcode_gen/barcode_app.c | 1 + 1 file changed, 1 insertion(+) diff --git a/base_pack/barcode_gen/barcode_app.c b/base_pack/barcode_gen/barcode_app.c index ef18859d0a9..2da9abd080d 100644 --- a/base_pack/barcode_gen/barcode_app.c +++ b/base_pack/barcode_gen/barcode_app.c @@ -450,6 +450,7 @@ int32_t barcode_main(void* p) { free_app(app); notification_message_block(barcode_notifications, &sequence_display_backlight_enforce_auto); //set_backlight_brightness(originalBrightness); + furi_record_close(RECORD_NOTIFICATION); return 0; } From b9443ac327d516005fe4001dec1c82fb317cc016 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:28:32 +0300 Subject: [PATCH 27/36] why icon is still broken??? and fix readme --- apps_source_code/ocarina/music_10px.png | Bin 140 -> 122 bytes base_pack/pocsag_pager/README.md | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps_source_code/ocarina/music_10px.png b/apps_source_code/ocarina/music_10px.png index 1c0046ad38aecdc7980004f2d0baa2fd2aef2ba7..495dad4d1be0f8f50c080a31512a050100703ed4 100644 GIT binary patch delta 79 zcmeBSteRlxY2xYP7@`rJ{OAAw|MhH249Y%=%F4=qPZc%?h$I=yq#T$K&cV$(gWWNa iiO;=6UU;p5Z2+VEw!p`}@fjx>fWXt$&t;ucLK6Tht{Hv+ delta 97 zcmb>GVVqzX?dIv?7@`rJ{OAAw|MhGp2Tq*e5O4G}77F6H#2C~Qthme7B&g#}#SDFe zHEcUY?_M|HSLkj&)M(MV;DO_IDentO{Bk*dj11-aHjkMuzmvv4FO#qF( BC7=KR diff --git a/base_pack/pocsag_pager/README.md b/base_pack/pocsag_pager/README.md index 6db87e32889..33bca4efde8 100644 --- a/base_pack/pocsag_pager/README.md +++ b/base_pack/pocsag_pager/README.md @@ -10,17 +10,17 @@ Includes new FM preset built into code - 2FSK with 9.5KHz freq deviation. App supports POCSAG 512, POCSAG 1200, POCSAG 2400 decoding on CC1101 supported frequencies! Check datasheet and add required frequency in config file (see details below) -Default frequency is set to DAPNET - `439987500` +Default frequency is set to DAPNET - "439987500" -To add new presets and frequencies create file `yourMicroSD/pocsag/settings.txt` +To add new presets and frequencies create file "yourMicroSD/pocsag/settings.txt" And put [THIS](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/applications/main/subghz/resources/subghz/assets/setting_user.example) file contents into it, and edit this example for yourself, add needed frequencies -Warning!!! This file is EXAMPLE! It contains frequencies that are commented with `#` +Warning!!! This file is EXAMPLE! It contains frequencies that are commented with "#" -`#` Is a comment symbol, if that symbol is present at the beggining of the line, that means this line will be ignored! +"#" Is a comment symbol, if that symbol is present at the beggining of the line, that means this line will be ignored! -To add custom frequency you need to uncomment the line and edit numbers keeping its size (zeros at the end) `Frequency: 433000000` +To add custom frequency you need to uncomment the line and edit numbers keeping its size (zeros at the end) "Frequency: 433000000" To edit default freqency follow same procedure From 06c22064aa6ae0c33438795eb7cd27d4d083c6c8 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 12:35:54 +0300 Subject: [PATCH 28/36] OH NO THIS ICON TOO! --- apps_source_code/ocarina/icons/music_10px.png | Bin 142 -> 122 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps_source_code/ocarina/icons/music_10px.png b/apps_source_code/ocarina/icons/music_10px.png index d41eb0db8c822c60be6c097393b3682680b81a6c..495dad4d1be0f8f50c080a31512a050100703ed4 100644 GIT binary patch delta 104 zcmeBUtePN^#KFeEz|d=SelL(>EDmyaVpw-h<|UA0;_2cTq7j_@=l}oz^=wKE%07z9 z%F2FE6*dQmBpJ)39GDQ!!Oc2@-7%4g&%H!mc&&hK0Hgf2z{kGv87G1I89ZJ6T-G@y GGywo;_#deN delta 124 zcmb>GW1JvS#>mXTz_9&K>^~sI7T^=&`o9avV%YU{mjRICEbxddW?L0H&KxGV`u6{1-oD!M<+)E-M From de4d9717148083cf08429e2ae1f3d300d6a44899 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Jun 2024 20:02:24 +0300 Subject: [PATCH 29/36] add eth tester for W5500 module --- ReadMe.md | 1 + .../eth_troubleshooter/.gitignore | 6 + non_catalog_apps/eth_troubleshooter/README.md | 21 + .../eth_troubleshooter/application.fam | 57 + .../docs/FlipperZeroPinout.jpg | Bin 0 -> 763631 bytes .../docs/w5500-lite-assembled-top.jpg | Bin 0 -> 217569 bytes .../docs/w5500-lite-pinout.png | Bin 0 -> 1247894 bytes .../eth_troubleshooter/eth_save_process.c | 301 ++ .../eth_troubleshooter/eth_save_process.h | 31 + .../eth_troubleshooter_app.c | 212 ++ .../eth_troubleshooter_app.h | 49 + .../eth_troubleshooter/eth_view_process.c | 422 +++ .../eth_troubleshooter/eth_view_process.h | 59 + .../eth_troubleshooter/eth_worker.c | 582 +++ .../eth_troubleshooter/eth_worker.h | 78 + .../eth_troubleshooter/eth_worker_dhcp.c | 8 + .../eth_troubleshooter/eth_worker_i.h | 31 + .../eth_troubleshooter/eth_worker_ping.c | 11 + .../images/ethernet_icon_10x10px.png | Bin 0 -> 126 bytes .../images/exit_128x64px.png | Bin 0 -> 893 bytes .../images/init_100x19px.png | Bin 0 -> 270 bytes .../images/main_128x64px.png | Bin 0 -> 924 bytes .../images/screenshot-ping.png | Bin 0 -> 2287 bytes .../images/screenshot_dhcp.png | Bin 0 -> 2221 bytes .../images/screenshot_init.png | Bin 0 -> 2304 bytes .../images/screenshot_static.png | Bin 0 -> 2033 bytes .../lib/ioLibrary_Driver/.gitattributes | 22 + .../lib/ioLibrary_Driver/.gitignore | 1940 ++++++++++ .../Application/loopback/loopback.c | 225 ++ .../Application/loopback/loopback.h | 38 + .../Application/multicast/multicast.c | 113 + .../Application/multicast/multicast.h | 28 + .../Ethernet/Socket_APIs_V3.0.3.chm | Bin 0 -> 1435546 bytes .../ioLibrary_Driver/Ethernet/W5100/w5100.c | 386 ++ .../ioLibrary_Driver/Ethernet/W5100/w5100.h | 1865 +++++++++ .../ioLibrary_Driver/Ethernet/W5100S/w5100s.c | 514 +++ .../ioLibrary_Driver/Ethernet/W5100S/w5100s.h | 3323 +++++++++++++++++ .../ioLibrary_Driver/Ethernet/W5200/w5200.c | 353 ++ .../ioLibrary_Driver/Ethernet/W5200/w5200.h | 2110 +++++++++++ .../ioLibrary_Driver/Ethernet/W5300/w5300.c | 225 ++ .../ioLibrary_Driver/Ethernet/W5300/w5300.h | 2336 ++++++++++++ .../ioLibrary_Driver/Ethernet/W5500/w5500.c | 267 ++ .../ioLibrary_Driver/Ethernet/W5500/w5500.h | 2165 +++++++++++ .../lib/ioLibrary_Driver/Ethernet/socket.c | 931 +++++ .../lib/ioLibrary_Driver/Ethernet/socket.h | 489 +++ .../ioLibrary_Driver/Ethernet/wizchip_conf.c | 842 +++++ .../ioLibrary_Driver/Ethernet/wizchip_conf.h | 661 ++++ .../lib/ioLibrary_Driver/Internet/DHCP/dhcp.c | 991 +++++ .../lib/ioLibrary_Driver/Internet/DHCP/dhcp.h | 159 + .../lib/ioLibrary_Driver/Internet/DNS/dns.c | 564 +++ .../lib/ioLibrary_Driver/Internet/DNS/dns.h | 109 + .../Internet/FTPClient/ftpc.c | 584 +++ .../Internet/FTPClient/ftpc.h | 130 + .../Internet/FTPClient/stdio_private.h | 75 + .../Internet/FTPServer/ftpd.c | 983 +++++ .../Internet/FTPServer/ftpd.h | 154 + .../Internet/FTPServer/stdio_private.h | 74 + .../lib/ioLibrary_Driver/Internet/ICMP/ping.c | 298 ++ .../lib/ioLibrary_Driver/Internet/ICMP/ping.h | 38 + .../Internet/MQTT/MQTTClient.c | 582 +++ .../Internet/MQTT/MQTTClient.h | 182 + .../MQTT/MQTTPacket/src/MQTTConnect.h | 136 + .../MQTT/MQTTPacket/src/MQTTConnectClient.c | 214 ++ .../MQTT/MQTTPacket/src/MQTTConnectServer.c | 148 + .../MQTTPacket/src/MQTTDeserializePublish.c | 107 + .../Internet/MQTT/MQTTPacket/src/MQTTFormat.c | 255 ++ .../Internet/MQTT/MQTTPacket/src/MQTTFormat.h | 37 + .../Internet/MQTT/MQTTPacket/src/MQTTPacket.c | 410 ++ .../Internet/MQTT/MQTTPacket/src/MQTTPacket.h | 133 + .../MQTT/MQTTPacket/src/MQTTPublish.h | 38 + .../MQTTPacket/src/MQTTSerializePublish.c | 169 + .../MQTT/MQTTPacket/src/MQTTSubscribe.h | 39 + .../MQTT/MQTTPacket/src/MQTTSubscribeClient.c | 137 + .../MQTT/MQTTPacket/src/MQTTSubscribeServer.c | 112 + .../MQTT/MQTTPacket/src/MQTTUnsubscribe.h | 38 + .../MQTTPacket/src/MQTTUnsubscribeClient.c | 106 + .../MQTTPacket/src/MQTTUnsubscribeServer.c | 102 + .../Internet/MQTT/MQTTPacket/src/StackTrace.h | 78 + .../Internet/MQTT/mqtt_interface.c | 182 + .../Internet/MQTT/mqtt_interface.h | 271 ++ .../lib/ioLibrary_Driver/Internet/SNMP/snmp.c | 927 +++++ .../lib/ioLibrary_Driver/Internet/SNMP/snmp.h | 122 + .../Internet/SNMP/snmp_custom.c | 147 + .../Internet/SNMP/snmp_custom.h | 41 + .../SNMP/tools/OID_Converter/Readme.txt | 45 + .../net-snmp-5.7(win32-bin)/snmptrapd.conf | 33 + .../lib/ioLibrary_Driver/Internet/SNTP/sntp.c | 450 +++ .../lib/ioLibrary_Driver/Internet/SNTP/sntp.h | 76 + .../ioLibrary_Driver/Internet/TFTP/netutil.c | 158 + .../ioLibrary_Driver/Internet/TFTP/netutil.h | 27 + .../lib/ioLibrary_Driver/Internet/TFTP/tftp.c | 660 ++++ .../lib/ioLibrary_Driver/Internet/TFTP/tftp.h | 101 + .../Internet/httpServer/httpParser.c | 402 ++ .../Internet/httpServer/httpParser.h | 158 + .../Internet/httpServer/httpServer.c | 749 ++++ .../Internet/httpServer/httpServer.h | 111 + .../Internet/httpServer/httpUtil.c | 75 + .../Internet/httpServer/httpUtil.h | 32 + .../lib/ioLibrary_Driver/README.md | 58 + .../lib/ioLibrary_Driver/iolibrary.chm | Bin 0 -> 4728334 bytes .../lib/ioLibrary_Driver/license.txt | 22 + 101 files changed, 32731 insertions(+) create mode 100644 non_catalog_apps/eth_troubleshooter/.gitignore create mode 100644 non_catalog_apps/eth_troubleshooter/README.md create mode 100644 non_catalog_apps/eth_troubleshooter/application.fam create mode 100644 non_catalog_apps/eth_troubleshooter/docs/FlipperZeroPinout.jpg create mode 100644 non_catalog_apps/eth_troubleshooter/docs/w5500-lite-assembled-top.jpg create mode 100644 non_catalog_apps/eth_troubleshooter/docs/w5500-lite-pinout.png create mode 100644 non_catalog_apps/eth_troubleshooter/eth_save_process.c create mode 100644 non_catalog_apps/eth_troubleshooter/eth_save_process.h create mode 100644 non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.c create mode 100644 non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.h create mode 100644 non_catalog_apps/eth_troubleshooter/eth_view_process.c create mode 100644 non_catalog_apps/eth_troubleshooter/eth_view_process.h create mode 100644 non_catalog_apps/eth_troubleshooter/eth_worker.c create mode 100644 non_catalog_apps/eth_troubleshooter/eth_worker.h create mode 100644 non_catalog_apps/eth_troubleshooter/eth_worker_dhcp.c create mode 100644 non_catalog_apps/eth_troubleshooter/eth_worker_i.h create mode 100644 non_catalog_apps/eth_troubleshooter/eth_worker_ping.c create mode 100644 non_catalog_apps/eth_troubleshooter/images/ethernet_icon_10x10px.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/exit_128x64px.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/init_100x19px.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/main_128x64px.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/screenshot-ping.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/screenshot_dhcp.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/screenshot_init.png create mode 100644 non_catalog_apps/eth_troubleshooter/images/screenshot_static.png create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitattributes create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitignore create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/multicast/multicast.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/multicast/multicast.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/Socket_APIs_V3.0.3.chm create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/stdio_private.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/stdio_private.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnect.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectClient.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectServer.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTDeserializePublish.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPublish.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSerializePublish.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribe.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeClient.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeServer.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribe.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeClient.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeServer.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/StackTrace.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/OID_Converter/Readme.txt create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/net-snmp-5.7(win32-bin)/snmptrapd.conf create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNTP/sntp.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNTP/sntp.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.c create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.h create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/README.md create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/iolibrary.chm create mode 100755 non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/license.txt diff --git a/ReadMe.md b/ReadMe.md index 983ccad9b78..3a9c86ad345 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -207,6 +207,7 @@ The Flipper and its community wouldn't be as rich as it is without your contribu | SD-SPI | ![GPIO Badge] | [by Gl1tchub](https://github.com/Gl1tchub/Flipperzero-SD-SPI) | read more details in original repo | ![None Badge] | | ICM42688 Air Mouse | ![GPIO Badge] | [by nminaylov](https://github.com/flipperdevices/flipperzero-good-faps/pull/83/files) | read more details in [original repo](https://github.com/flipperdevices/flipperzero-good-faps/pull/83/files) | ![None Badge] | | WS2812B LED Tester | ![GPIO Badge] | [by jamisonderek](https://github.com/jamisonderek/flipper-zero-tutorials/tree/main/gpio/ws2812b_tester) | read more details in [original repo](https://github.com/jamisonderek/flipper-zero-tutorials/tree/main/gpio/ws2812b_tester) | ![None Badge] | +| W5500 Ethernet Tester | ![GPIO Badge] | [by karasevia](https://github.com/karasevia/finik_eth) | [with fixes by arag0re](https://github.com/arag0re/fz-eth-troubleshooter/tree/hexUiFix) read more details in original repo | ![None Badge] | | IR Remote | ![IR Badge] | [by Hong5489](https://github.com/Hong5489/ir_remote) | improvements [by friebel](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/535) - Hold Option, RAW support [by d4ve10](https://github.com/d4ve10/ir_remote/tree/infrared_hold_option) | ![None Badge] | | IR Intervalometer | ![IR Badge] | [by Nitepone](https://github.com/Nitepone/flipper-intervalometer) | | [![UFW Badge]](https://lab.flipper.net/apps/sony_intervalometer) | | IR Xbox Controller | ![IR Badge] | [by gebeto](https://github.com/gebeto/flipper-xbox-controller) | | [![Author Badge]](https://lab.flipper.net/apps/xbox_controller) | diff --git a/non_catalog_apps/eth_troubleshooter/.gitignore b/non_catalog_apps/eth_troubleshooter/.gitignore new file mode 100644 index 00000000000..81a8981f739 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/.gitignore @@ -0,0 +1,6 @@ +dist/* +.vscode +.clang-format +.editorconfig +.env +.ufbt diff --git a/non_catalog_apps/eth_troubleshooter/README.md b/non_catalog_apps/eth_troubleshooter/README.md new file mode 100644 index 00000000000..56aa6389419 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/README.md @@ -0,0 +1,21 @@ +# Flipper Zero Ethernet Troubleshooter + +This is a small helper that lets you connect your Flipper via RJ45 to your network +You can then set the interface-mac and test if you can get an IP via DHCP and the ping addresses. + +## Prerequisites + +To get started you will need a specific module called the W5500 Lite with a chiop from WHIZnet Co., Ltd. +You can find those modules on AliExpress etc. [Find Module here](https://www.google.com/search?q=WS5500+Ethernet) +The second thing you will need is a proto-board for the Flipper Zero, which you can get [here](https://shop.flipperzero.one/products/proto-boards). + +## Assembly + +If you got those things, you can get started. +You will need to solder the board yourself, but don't worry. It's not that complicated. +First we will need to know the pinout of the W5500-Lite-Module. +![w5500 pinout](docs/w5500-lite-pinout.png) +here is the Flipper-Pinout to see where you will have to connect everything: +![flipper pinout](docs/FlipperZeroPinout.jpg) +and if you have correctly soldered you will end up with something like: +![w5500 assebled board](docs/w5500-lite-assembled-top.jpg) diff --git a/non_catalog_apps/eth_troubleshooter/application.fam b/non_catalog_apps/eth_troubleshooter/application.fam new file mode 100644 index 00000000000..11fd5712d24 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/application.fam @@ -0,0 +1,57 @@ +App( + appid="eth_troubleshooter", + name="[W5500] Ethernet", + apptype=FlipperAppType.EXTERNAL, + entry_point="eth_troubleshooter_app", + cdefines=["ETH_TROUBLESHOOTER"], + requires=[ + "gui", + "power", + ], + stack_size=5 * 1024, + order=90, + fap_icon="images/ethernet_icon_10x10px.png", + fap_category="GPIO", + fap_icon_assets="images", + fap_private_libs=[ + Lib( + cflags=[ + "-Wunused-parameter", + "-Wunused-function", + "-Wredundant-decls", + "-Wunused-parameter", + ], + name="ioLibrary_Driver", + fap_include_paths=[ + "Ethernet/W5500", + "Ethernet", + "Internet/DHCP", + "Internet/DNS", + # "Internet/FTPClient", + # "Internet/FTPServer", + # "Internet/httpServer", + "Internet/ICMP", + # "Internet/MQTT", + # "Internet/MQTT/MQTTPacket/src", + # "Internet/SNMP", + # "Internet/SNTP", + # "Internet/TFTP", + ], + sources=[ + "Ethernet/W5500/*.c", + "Ethernet/*.c", + "Internet/DHCP/*.c", + "Internet/DNS/*.c", + # "Internet/FTPClient/*.c", + # "Internet/FTPServer/*.c", + # "Internet/httpServer/*.c", + "Internet/ICMP/*.c", + # "Internet/MQTT/*.c", + # "Internet/MQTT/MQTTPacket/src/*.c", + # "Internet/SNMP/*.c", + # "Internet/SNTP/*.c", + # "Internet/TFTP/*.c", + ], + ), + ], +) diff --git a/non_catalog_apps/eth_troubleshooter/docs/FlipperZeroPinout.jpg b/non_catalog_apps/eth_troubleshooter/docs/FlipperZeroPinout.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a6f6d628c4c966052cbd016dc4c56b7d7cfbbba8 GIT binary patch literal 763631 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

!rIwBy%g^ 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

mLgkwugc#V-ybhpz0vMQ}Zr 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%0Aev7Ot3L0N*;n5ug0Nb}`T) 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 R{{YEFSe}X~uVDPh|JkKQE5iT) literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/docs/w5500-lite-pinout.png b/non_catalog_apps/eth_troubleshooter/docs/w5500-lite-pinout.png new file mode 100644 index 0000000000000000000000000000000000000000..fed1752a4ba9fcbe91bdb0e7bfd08397893bd769 GIT binary patch literal 1247894 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%0AmK`40_-CEPm4(SM!cz? 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

IT-Bwyd-~_ zoHSM%-dCae%hP6ulm-P23%fbbbESp>@w>xqEoW*?b4ftr94Tevj+2KM&-c{;Oau39N^LpB${{^JnYl) zcJT&fc|m`~vkS~oRCr)3Ju58&N`?-pOu}qEN~v7E?*(Pk=f$gD1w$n$ht&gA{ zCo)HJC$ms^->DTvO#Bld2F5ZXu{SYV%3s^;rn!6tn?XM8np<3ZsMTOF@=ht@tt8;7 zuyrDN6K-hFJwWMLp7~>5`42$u>=$S;=zg=LV}c={XNQ^bcc`YlZ=Ho{{>LmACVj7n zv`5QiPT-dmu~Vgqdra6@U{eupd#a4m5T<2?0QO~Gbgxj6_S2fC`w)V;5 zR_|zq7@lyZ9i){*6j?8|60?k#?y`5gNU^`68%!RY(%O*_fiw}A*Y~uo{1lh%HBzl0 zS1dYUrzsQ2?N^|0&rz_qlu^n(g~)n5j1A0(*-gMqJoxv4cKser>`iM#d-x${IinKK zxTZhqX?9CqR#OD|p!0rL(e~i0+U?=VZcZqUQ>Bqcnq51&=t7RhVNKKJ2o&bKpY@xz zB96U{Di79yoskts8S|cuXp+``H1yJiXKih%0fq+m`nO6gXXdzoVAWlDU{9%2`t!n^ z%v~e9yDYzY-q_U^>MuqP_pa?oj^{0f^CuX!tkak_#k~CB7(^g4^o=Dg-#_y7hHgJ8 zCb?@|ly7vs0WZwf$kP-VkoOdQ{i;ld+$WDnxw>ZjZp(TXv*MvTRqmk2&%lzz@~pX^ z&H**43r97xv$FNZE(FDy`0l*X7?K!&NEx5kU`d8wbKH$$oCS}+E)ApXIHZ#>k}1WE zmbdh2ucIAv1UxxsDAgM-u5WXz-5liayex4C9FbYc0cAhcrE`1-i%)ACStL8j>FLT0n3S$Bpga0ctD{?;8P zbDV5&4^~mfe03Ciswq%!H9*{tgVWqgI1YH$ZdIn~BtN%}ybBxt|j+tymw{jnHzXYW2ShZW6w3b|G?3&Pz z*Gxq3oKic-d31Vd59ntwe{W0-XTpQ1e9%+If>_vxMi!FPM-65V#-tmPi3#3sTllqG z=1U|S^80~-u5KwL$7d5kUUS)w-iX=a~FBh&N z#qM%9(P1@_h^_>`XPqu41F3!uPciXIFrre30x9XLq<&SFF_05oJ#e@D*)sHCOyQ(b z9ZXV_QtAEJ_~b!GP6gt2?Lm=pPq)3#rPUE}(mpL7*T_$#b)RjuM?5!Q{QMS-kFmX|~B&&**f*F%*Pj?o)?$YK{SSm|* zK><>};8O;ITJ(%onmoS%07G8PjobzsORQC=NY~ZCg=uY=GMzEdJuhKwCOKs7dpV2) zFY_2LRmzs`g-KZLEU~Ht+{(cg<{HUo7j}|`#XBQjMn>(@m<;SXvCQuoc|hp00x(FC z$ehv2!*7*Xh6)2dnj z`_LhH-PQhIC7t=5%Ea4A0CM7r9PKM|eD&p;GWvnl`v{se+6WrEXxN~0M%!6Z@P)#; z@T%f8gEnK(*K9)OR$Z&w9E)1{rQ@&Wp!)e!PjM4vYtIb$nilK(J+|<5pV3nVP)q0) zVR7Y0+Ot>V?Kok6CJB!nlhi0R6_75^v*e;c^+bAZH&|~NkOgbEh{%keP#&{oTFqsT z>^FXy_wWS6bcla)=;=v^!3HdB`joD+FV)C!aZhdCu>WZ=L{FdM&`|j$eQS=?`1cM~ zuaLF)(K#?HZ#^lP{b*6QpjcIX9`1S>^Puw;uQoJ!?r34QAH>^Mn{n7BO{()$4(EB^7d;T6IXzHwd^%n~YQc?QDaE%59JTa8 z&JA3j-Y0ZblIiL`gj2GxTzqSyfnyEX0Z{iui3p*yw=+i|c*N@{3?P!P{9YID_f!_a zoWv>TJq!_QAg z?WkQ~mkGk)T{q#ChP5iiIZe5UATwD1@)h^6ln1`PCX zrzA7l^a@F&;OX}DbT^0~@kq%I4rOipkwdQ*vDqqk`>1OqSa0U>v603nGIFxewxu0w zwU?h!mrusT4Ef(vYcP-P(p^DLJ^+qCDgykP*D{V8zf*M~ZE%>-z6iR9R-@#rdxRW@ zvQ7J+dz866_rG}N%2Yvu`lw>V5IRj&C#}hAq*WOqzoL6IJ-FJ}*Jf;46^7J1X!(-9 zWD^H-Y_MfN#)E=Ion>tR_7T~75K^RvY`!yFHk0CSPIAlQG}*`vU8}}P#Akvz!kCb~ za!g5+OU|w(MWimgMJ`^Phseq1HFiD6!yFZv6-~F?Q7!U|dbNE%gX$}3$Gj#eB&TK5 znp1*o4^uEolxQn(AS=yH!KV zOWT+uh)_aaQ1Xs^M%FP_N+o}&@1>2?mFwp%Y?wXF&S>-u@v+07Gjv>3hulf)wUn@fU-8la%Ko%y9C2a&njUVCUK#l)WBf z$%@>nYhSx`Oq`^ZdpKyJWGZ z|5_f9Bbl0B5o^!3OtYJu&)bpj+}P24OKH$x$A_Ry zWLqRI(?^H=LdH5E&DQj4Unqa|QK zru>4ENlTa`L0GUZ$flB{vK$7MI*qP2nH1G&i)a>CE4t*d(5k)AN-PGf=qpLazsIv6)>_1(c& zl$atc@c?uS|0zQ^_DNbcdj~V?l)>r&YSK}dqc8TTJ^O{q+~qWR_IZ%hysBp6C^Ie6 z$Y8l^z-!50zO8c}QrmMoOAWbVisPjO*V_{AZUdd^uOE+aw~Q)pSvw1%$QU|Zt_+5w zIEml5w0B5@2et~`i zQ}->$R!KKLoZ8{9AVqmC({H1>oprNJI~I4Yf`>WRi=rhEod@@{S8@B4{GqS0Z;QJO zQ|QRvuEZ|AqI^P`xh3s&(1Jbp42U=y98g4bqK) zmQ6heORXq-2yKv(frtzK1hLusodDv|S85=X>EQR@GMhH@De!bf9(=W%Bvo8hvT7tq z49B~(n05x~{cu*-ApE*(asM6&XS^L5hWrv5<8qKIalCY)G}^G_vHsLm#l47zH%={w zVboI&xv$Cs=Id`J*4%7>berXPM(3;h+3PHT*OTz1_s7b$bHmR+vuWY z@<=mLh&C%;FRdartv^Duu}LTG*yxrP=4Mgyn_HuHXQo9T^s8Nz?w;Je1k-OT%*{sF zLZ~(g!JUm9tuw}yh~>1zNzJYCg^S<$?hUNzLc><_Lis70jtfC{y%3Pwd8=FRqhCJ^ zUD!A{c;Oj)!$7LuEzuPBwa2fOyBKF`5ROnfv;Q~R0WRtA+)CQ zUB{YF_@~UcqFyw+;+&s~kJT-{l9~c8Ziz(PUJeEcHOi<;FPaa*cVc^EJSvDUM}Zi< zV+-(@^5;SMj-2c zvWl!~Ad&_nZBIL<0dzHXCHe7Ej}@*NGuD8Q?iiFDX^hce$5H|fRyVIfNY@N|=35`B zA9!qm>DiBn>K1ns#!TFv!}8Q%ESVcR_`_86h`m=6zmO1%GaZPMEL=Mp^w2we#$c}n zijH-|9ZJMh{^(!)3gPMy4=n1|3PRLezv|y}@KJ2~dVPcj%Pcm&*Q%=brp{>Mk4n(8 zhO`~a%5s~Po3tDdnoxmjP0^hZs6&`@{YDxM>js-C zlIPmR&&nMwEU}i+U!W}(y|NJmccLuviKfC;q33%LQBN7(t=Sf?Kj9aegP6JqMiP*! z`Z}OmW*=|yg|aAYV;o=8UFH!E2f9SkRoKmC8tfh{xe#rp@11GD z%J!>^pPDifCYJVi^>np#6=d7ULL8}0asJufSxgp?14lIgb!-5G$8Ctj!s&=%(rK_# zn#XIJuDPsBk2ecMJ;w?Dp(@`sGT9xH@7CecXwE*gC?m=?*ncLMtDD+u6?ci8jBu2* zq!xLFSj)PArXV8|Mc;3L>|Jf}~c;NL3kmaf>4 zzUB&hY3q~b2CvKrbky`9CM>5eo^lA~nCA9SZ)v+#&?-mdW%=LC#f#S2A}>?bCR{S7 zRb9KDpzswL?1li2E!J$^GHrs|V30QYG>+-kih#zS0O2o_mztgq7sxkM+`GyhfTh z#mxrR;=RopZFT!xI}4jgS%u`ftMSjpQ*6yaFymMl5Z2Se53TZxKs;kn~cQ1t^Y4iA>rPorjw#8jC{IFS?6%7Ea|1=qt z_0@(SYyYgdSn1sCEV(vr*E|?ud8*fFs+oXnvLsl}3HKsbSl!ezx3mf)e}x8u8`Z2) zK6b#jr2;W(keO&FrJlcP#W(XyE8!ocqSfua!ZTeJ(f=X4Fx;=G-EvUdwQ@@hZ}vPt~^OBD7kJ6YLrZ!@QKQxG+8D( z23=#l4fS-7Gb)&l%ynn^72eh!a zO~=X{SvRs2GtI{cDn4r5B9zG>%n`x`#4`8X4c)ThlNH>Ii}np|G=&kECd9>(hx?zOXMx1)B=c7%gO5uWum-8Blf))d` z819vh!69YcoX{y@s=BK{7Lv35+Ffpl8w|s+r58EAf#R$836F-Qg?OAh7h5Z~N~>9T z>anbqFSydqlXbhE$HN@LW&6}G7j`vaZFOv=ugIyk+qZ0uf&m;ycIBe9r%FPZCBJ}G ztSjHbS=2J`Cu7yxgepulhf!5j$%}D=@9`TSQg4sS_7h$-m=(BMjJLHeD-4|qq4Oy% z>G3e`p_J)lkW+WEUPID!j~bJows?epeEw*OD$>kj!VDtW^MY!Hnb!>lo0HZl#6rPQ z&)Ws)=pwi@VA%4ODJvMLiMqaV2>(GfLSogoWG!BpsQq4^rq5Q(DV7hBU&$5d zdoLS-T>zHR#gnZ-z1|i%f~C%>!sdNtV=CcYMUIQV_?-tKznj{@spO;Y^`YjCi19Kw z#V=je+pY7gF-@9L_ccPAaa`ZxZJ2boXUsBQYl}2$OyPyevK6LRHuI5Ca;&_wpx2wc z+)fS9VyGY!fbynB7~^}FMtHwVnTm^vN@K88r)?uQD4Xvx(BrKNKEVEI`3Qb3v^aK@ z!ZIr>9B{Qru;iHmsiqc{@TbVth#gUK1Q+qXgD<-!ZKE6FrYut7RW4xGoA`ps2vFg` zq?~P3GYFnwn40fcc_w*1+cnPXAa1?{y$f?lb4f!a;SdMikQ!WbYk7K-$sC(G5cLKB z3GeA%QCNf11JEJXc)|U^3?hzipi8; zXZ|&XH{af62ditlq|Y@BUugkrg2L(h6vF{@ja+yTYfulz!Bm z^~T_ui|dKreiOxJgZY9zx#gEhJQwU7Xsi4lsunJhx&Y6ji9ZaR;CyktM?9aM2y*U* z^Aj;>tCp1B#$lRZ;1_nPe=`=|bBl?G3J;Q^7oA7^z^AMDPlD~F4Xt(9e%Q<DsRJka&XL$n6&cR?Ee17R7P?;o7bfd1L$H_`ItXv|c^vN@|O1?qs+3R3pN17dx&& z!zvV8!lMAEn1FU5F-qul(`DMMEFD`+N9k}v-%y01Q@TGJh&hiV#tPg!38Sg+52x=H z$vrDfwS?aKsqOH4UdEoeBbN^uynT44)og$ov2>k0$&4q#1s2|wjbjjAxDMc?tL#|K zfrb$S_F=kj)YLvzQP*}5Y=JOg*o8Q2Jb61<$bYKq1|s~Q4Gafwy2T<(Sba)VY{_+t zE1{jeH(!n=Jke^T6N6gt#j%cQA?XJ5Xo;6&RDN2B@E%liu;rjJH`}8P@CreB!*Su} zSI+;UrhHshPZBY6r`DFDC~wI;#C*m~Hkc<~Zz@NfwUBeV+@D@q(XoJ58Mv7n52@v4 zWO4geU0@5~@4{D&9O*pkm%>x{ULtJ0!XUpgR;fKcDX#|!jJ-S=xoPd~(hPFJ-eks_ zr*s=ae{D&s>KwCs*PsoexqHP;WT;K3+S1aSqy$dTs5l=MIx|u5LKJxxVd^)A`5Fy9 zvuvf{c)4WhctAb=vI-p1vKmWVO?Vesuiwq6fq=g?hBLGO-1G z#v7I#2c0&TF=1V}-7lUx-%WwH(Hj!V_Znd;!9{(m)bXWBVze+uU(&kr(;!ca9b3Yy zq9rT(6|Q9&p&FZ%wX@MJ+3!=La{IS-kF zbV;emuPp96>@l$5&v}WgIU74#C@5^l%LEx|H#lqjM2L(;3QFA?p5;u{5hiRsq$V<6 zZVz5e!s(H;H?MBPHKexy(t*lU4{rO@x~?a%MD=VZe)>iG8CMf)j^Zecw|G{s>r9nc zJE3^7a0=kOp2-`vNg}{t{@id|;aRj$wfv(iU(Ou{^u1HjWEdiz@}{~&Z{w@=cY7vy z?HFwDDNN1eRd8Y)dvA&G=jSd*o*6nGV3?%@L1m%%q=FEs_TFQ*+|!bjeST3YQ<|`X zhVRqnX=|PBUFGp|b(Uj2i3OnyF)Lz$9Ymo4%AOh(7SSOc41n-83L@YY7Y!q-XzbNW zi7W<)YPOqNB-X@0U&(Zm9gWXL)~!$8%I?e9rjbTU3jt>`G}oHV7pch+=mU_H3Fl#1DazJKS^WC&iznki%8K{oGP zJj4BJIsLkOWJ>t<@ke>w;m%5KSKCyd0T*1dX2?=#yZR^&smeg7(dSX)D2rH@1)v8> zT~jd14bLmt97!iFC|n^$8mh)D$hbS(eeCUSVmM011V83&4(`&4gcg&&C7 z85)+#-ytz1oe4ID=EvvIPWTlam~Hw6M&zO!lrfKBEUyd$X!pJ|8r3ZFOfDX)HcjKjxiPG1!^Y*#akM z`VejO(+_D1T(1B+*GFy%*D4pDj$2;?fjg7k+mX7!6$=e%&o5x3vPR3qMyj;vRRoR_1uaZRG+uT@Hi}`2Qg}P@>j92=z zd=Ffq&@r>Qtcb}+Wl4?N!ig!aD!A;FVA)=GVKo>y1_m12Zn_H z+soKx7>xFr>B+^f{D?23-J{37@Z~|1ZPTa)zYJ6456bJCjAWzy%qt?{%QvHu^i?Bn z^B^j#A623x_)xRNaN{T-D%8blBi6liQH3h9CO{S^qi|! zcb)vMfY6n11S5Nd4ks_Dv(qXd9r_0ukqs@yE0MQJsmGxGYmfp{D>3&|cYr|pETpcY zI5>mg@?b7|JMssTNviAlmolvP9;dK7WSYx!lUA%-uRa3$g+`7hHr67bIkC9s zq){fhL8yc>=_nmk%V;)OCRd)eTD;naeIXqnQK7S${>vg!gT3EVF(40HArwQ5{-&n_kaMPP&2VR&AL};<&z?`)04TlR8^N}>fs0?H#zDv8X3ej_kc_IL4 z9@LheTH&-qFs4;(l8M@>3vWs%5G-*lX9&Zj*TR>?36g2egr!S9-4+V0W>s{QX{cXMpuS&&Igtexg2V zD@1;bpC(34K`2O3P1H_D-eDyMOd|_caVfe0HVScT*w8JW+e8pU+NgUtIOO*>ItRKtIBy zi5*;oG-B^nRI=A4&Twxj1XN}jQR79alPl#HD$O$ecJx2-eSs#1CFi@9tWxy~1*&aA zV|QCW>1i;skIpfkZ50Q+r5CQmkSzQY8wY%&3?Vc8jqH=1!mF{9ph@fgu*5eTqx7~I zQq;LHkYu<=Qn+hLH13^yzIIGD-Gl}Dah?CLI`gX=Bm?YqyA{~FFK==BZGJIRvwPgRw6Edv2B5wGk*xdd%k|62!rCiq zDsOGv%6=-boRYd#RzzS8232Rwy|lrYW8O97C%#|20Q2z%f% z9#vmioCrNNAitjLFjMGuJJjvgU;~Os;sV~!88lp&yN_$WMP) zzH_k}E2XD+EASWLsD-L^heVUhTg99ik2|Y3cMHp{sg9hjA+JlsD@d#7WX@zU^|jSH zg(^*a_YHyX@!4|WgnAnfwGOab?R!^g^!^>lFW+Zs3ez`#bm*5Wg(tNa2MawsDsQF_ zEL!moD2w3t4jI@m`<3`P`1joOpn9JO&hvTF>WBZmNB;wxscu%>&iC{bp8T5V<;4_z z_~U^98XM9k)L|s;fNbu)itN=~vmXPn&K-aI?o&Y#_XPVLjV#G0_Ts={>Ja2Ar%qSrv5Q#}9VMh6Cq45~^Dll4ezdv{Hos z)lqKk5sZn(`|a}Gw3)WcUQw>y(WOzentocCs$?R9$nMxgKTn0PUZS_dOb-&;eiMz{ zA04pO+e8;-$l;BZIhl)3^pR=`0oF=+Erts#FHk&dxwwUg@B4$U{t8W^ZhPPJ2Jim~ z!^TffagoaH<)R%woEd7C$TM%6bsBRt-ykz?XIGD<8|DEbyv6&d*g?(7u85yLFtCKd zy*sGwjP8j_-k#t3{R3d3E&?Ti@s`E^p}P--Fm(1E2e-yd#7S73-RMf^yS!p6-sT=T z$=e5iOW0C0tv395ZgR~Y6@scyD3AWFT-OFm>zWN&r)U18^wCg0w7p9=x*EN!oGZe! z19l2|XdtfI4&cPE%x-yaY14N*WXG=@{qEMl9=<}muH6izIQTsxxyBBa?&aye9riVA zB*o>UfA*MbBotU&LjKwCKZf~RSO13P`?=i|z=i3&$Oe=v+~D)NZ~3n5YpMRgU;6_5 z`mf`L6>EIGwb(7I)HLCOQ|RBhafJWFoS?rECPu7ZI-{rmer5l7vfg(vD&dMrn)CWG z?feFI();s@-G$g~+j0KI20Fr~yuWvt26RD7DaR9?n#wiT3nx(Zf-L*u-)2wv7BpZ( zX768UA^**Ye1RemfKx^Mlfz$cNbeV0U9$=3JK8ndUSO;vi7|b}HTQm#$ALT5t9KGy zGU%2J=XY899B>>dx{u1bwDL#mv(p<9j(%g^mA~bS_dv`#i4j4rD9zneZRKy_DKD=5 zCNyxdG4V+|%gUTR)GZweSEDco4UtR1@jdTt%nty@TL@QeD*RIOA07YAM4cAm*u~rb z!q7BC#$Y>A;XUV7%k7Q<Vu|KMAi| z&frJ>2IvMzb{k{Kg4x_n1|SN-T-{2bHswe$USQKt`_FhWUj;w;lUKIR3!cS%g_p3rufG|K{9ZTKe~& z314;bzwtMn=w_LVpD6wvfTcDuEH^cqy7UpK)p5IK9h+&5@{MWr5Wm8T+aI{@Q!o=p$P{`7u@7ML5!7P1E$p-(C1{@c0jMhYTfL`&TN19Bp@fXvY^L z9JR0_N5s#6zOyp`s&M2G_zy(?oC3k_*%ZHPpsZPRV*#k5>(`6+zbPE7SUGP1@AhPa zdC&($u2_)TZopmMKdcZ5;P$W!>8kyqhWP#$(BD4U7;-gCVqx0?e%Ma!kIw%q!bw5GL2Xv}Kx4Ig7^f&b8Kg>}4V~z%X*(k`+>FH$ppBeLC(EY8`SyK^= z!MZ7*`#Z)b#mqOhNkIK z-G6Rq10|B=hDOzcC8Yj4X0xXyW?!wAt)KP;&~dxc>ze+)q2Fb0Y45D~t^eD=ey0Ha z#l~X%%^9HF@5E?iS;hDyl0TDm^<fGtW2Hn3? z_?JfpLGK}F-nPsA#M9qiBpnI>C9eM}O8BFN$C z{*`*q14739Ov>-`{+mwujLN4N@G~l(QTbz~{}dE|(TbmWECM&&aqpC#x&8*u+@ z4}F%P&l2=mf<8;opU#EKIpTy{loe6AE20BpX`6+-=`gQto6wVrMAKG6^w0hiY z5B`@w{_*s0ewdq_yt7s`9sTyJe{b?{K6?MC`po9d{1DHlyZ+}7owrJ~5@-UA%YPZb zKlS!uU|omyo~+tsuK7QIsH-X@w!IvB#^hgd`!Bkc`$BA7=e6^h|M|o81A9;6E-yCT z_;|Yhp<9QPJDUV&besR-wT~$pDiRYLw_sysRsYHy|5Y=tU++vBlt`ETpFfO`5)$j& zuaoPV#RH+|l7{=;75vqR|b zmGowj&kmu#Hx)lSgg&jC|8#&kmt~P|^~g9YUYtn?Kk7&kmu_4x#rt z=JTHO@6DOdd(OXCBqu-bIscx4HjDiKu;(<znS?({gb%@L;Bm$=XS2y)UDZc`zZEUBNq?Q=PoI{ zF#S(v^lFM&%lZXt_O(w3)`x5ZEG5#{Zw9Qv)fN6U3I2_ZvFA2xwyr-Zd6V=>1u#pO zFxc^STh_YP;w#%v_j6}c06@uM3m?FEVg2_zqEC3Wmfi>>^|*YwYr21L3V(wBS(uox z28lcO$4}#f6AvgXEVMYr7#>Ujdno-iqcszNm6N zWd4cy7?S&<>EwFIou|7$LFdUK!oj@6$N|@d^`e(E{#$o0p|&>RE{vq!S!KZ3KGh|c zeS^@MNxY9Kgb1-IdG2iV=>e)f-kZAV8FY(CRbn;$Uc5kIjXOPv2fW?h0#CTJY6mvt zY^PGW?TkUS8NY_~eU&raizSO(CF7DS zoUZ4gT<wZ>7m@OmXy~LFw^HsaZ!fP$jP+fdjBpx`748E zeydAwJL0uy*|c72i5-1UFM;jS|IWAS@Rh~++qnK3;uP-P3|;$h_FpIR!yIEbk~OGL zycIt&cICszjgSa|;jwE!bDSb(Qc3WHc%RBjq&%gC`)n|$Ag5#iJ5gc5pLlUNZnTry zHwj~7>Af6z{1LVL?1FT+u{Ap?mc}lk&LP2U#vojO^G^ZwGq4P45s29Qq6a{1-Bf%n zhqimJ9#-fRT_8yIcWs$k7HeMX1IZ_(A_TE=v%976yA;l#b&(BYzJVO%<;B#~iLMTn~WdO#3WJ#8Yu>V0`YY^_XW zaDH(TkV?cJZP^AL*bHwhEYF-|ck2JDNRVno=)DO_pU7G$z3sh1&t*UQW+e=)V3u<& z6o;8?*QkQH0D3>>m~>%66YdwE=9o{Y7_?4+Mc^&`OYHIz2)!88H4Z*@}SdL;RxPVjiNa+$O zNj5nf6mkD^r6kZ2%-xc>7voxbqwvVy-|0WKm} zPN5sy$2xmo=`_J$n&920Hl=)@(YvV=a)pY{Sk#{gAFzVUTUQ;)JNJqCd$y6i#PXIs z`tec{FmrVFJL5&?8TOZI_a{JZ%es>ZSSP4$dT#e%AFj>#?$nh7l)_*KzN^-X+zJDJ z6T=4<$xvu3g@Zu5lgK|Y zCcJms^@-xZd5*&#BwG*EaON?I2wwKG=EqDG7=BYQ^$FcKbbA9HroHUpkKm~ml4JP# z4&miJ!mh97>0z7t^u!j+!bW}X`lK{tpY%w_We56qw>;U2260x4v0t}B_<+n8I=#>O zC0g+ggKa+LEUN2l5n2&fZqMpuW$`f`NAwkLXCcW%f+~nvrvb-Pc{gIS^D!k^mWiXD zl`FFtoqBui7mnF_cWhCd_Dcor3NwpNuWl5^qvGMt%XMCdO)6P%9LaVy7HM7y;=o_% zo8GAg+YP}hl&X~H)?{@Q!x+HWAbYSH>XJU=a2K5xx19e|gB4Ep=GUrPF3Or^>9nl4 z$IE>=HI)h6bi!K-WBx5Y`6$C&x>7N2C9wWgI(|8H0N`7sPI;mzS=of3a&_z5hEsUO zmXV5`DF0RQ>Gj}s{RweNDE(u>t9l?*glb+&+XFwLsdEn=hau1T;FJ1D*T0E}oG}c) zZ4zl@bNuj2`6dmKS(yGea2x_Pt=9Rn`G${o6wyT2@H8Pbsi6&v2_3Ciaeq17M$B;@ zq=w1fW_Q*7YTYUr-WdbXD#RViOyD04STa{tobbrt_;zXK0iS`eBgTM1Xm!e$7NSpr zawH-6J+58#u~kqHxh+Xs0|-YwZ|<9A`eLo>mO3gz!DiBLD!%3?FD_+7zgzy+z+k5( z^Xl?19nZl(wpk-DhRi$WMvP)~t9m1*=CE0M)a_0SQCLMV4(_LeYBO-eIKtXG73j)2-byPTZQBb5|(-fJDL3T9;}x-m8*4Z;WpO2 zjMrYKr}R;p->Qr-xAH$2LCUJFr(U+ys3wjg<7Z-|b3>1VOm4eB6bJqI)^KZ&YGEF} z)c%N-=UVut|Hs$6$1~lB|KoR3q3#q($|0Q;N+mgOq>@xhIh$2tch1rrX0u4?E{CMZ zX{#hTZLttzE6Om8m^qIe#>N&iv-5AC$M5_5=hOZD{k1>ddpve{zpv|hKA+d~dR^iw zeOor9bI~V}U%aT)>wzSPtUz==>iG|&%N_W+r3uN4_-?>eVCzpwGndOm5sL;2#OyVPy*+gpHMe zY=51tF0q7cTvb9_G{;~oP;|j7)I;)+q|Isklst_C-C9G$0w(#E&)~IS>aJsD^kfDk zuK9_Zd#J9JFOr~5k?pV^UI|&HMt^Q^$d*_J#pJ$9INrH*V29VperWDRG9yAPcroJ| z_z3Gq62}&KiT5KR8E7wgB>-NZ_+25+g&^RVaGe%u+^aBLA175FH{^$51FUzA2KU}4 z7+Ws)epa0wv>3;iH@zGn7XFl@hVj1kL2Ks}@{~0V>X{95I~oudJTr}G%unCCe6Et) zsMe4r92)T_lFRpoqXi)VY#>9#cl0hsZ`mt@UF@!Y`TmPbX3T8Gb;myBB3sp?Cbir{ z618&LJ9W8uEz1ovGYCoN4OV@Qn_sIs-SHL8P7eG#W-D{r75;e-Ya!$Ct)xZKUJ2m}EDv&_DGoD? z`6O0qqd>a?!EXgAV{Wf#_oAD$u~GLwB`9|SZ+wy(PYNp>hm@3$`OjBdQ2=Lwlw6~H z=cGseTHgeU6Y4K1FM33ty4~jmUat&JA+xQNDJD?IHh}DUNS7yZYj@0FGTvbqBmz@l zEpeGVyDMjr9hL3z$`Huk*+B1hk7in0(}Sk!N7DN2V|qCipUX`UU3?GXQUmDX`HUtvhPKF=Zks9^ zLtOSiB7wsYIF1c^#g~SdHw+hgT$I{y@-No%T_p$h0<)7@!J@_i394zLfILZDJFyLQVTJDVAYz4QeTlPNhD?EwgyoS(t$>|Y$ zQN3u35%6JZDo-O%&OnOfJ71x>caX_EqgjjYUj89I#5h+OskjN^#hl5q$8x4%c%uWd zT$^cCNoT~A&A-p5UVb_h0aI|10gzo9aOaVn?yLj|Jxby#VPq^4v-{o3Xb7rgb-D2p z%G!}DUhr1VqDhrz4UDX#RPwJ^X$9{!xn!=ACCKnJ9 z73)`=Zvt@L9{IR~aG=6Uc(x>9R=Cnjwum{CuH~$d;ctwyS&yk&t<2|#W6GI*F2^c? zCjF&Tq9EtRq3OHjMLhRVwd5UPzKMeeBKFCdJD0Xq;4`diO`8k|hj85t@b&gNku9n^ApFTRW3c13NQcT= zNZVhZcWo*HgoqGi2FnIwzVqk&Z4dnilay)80R^(VDZ2PS07bfz_P#K*Zo%8S3J>Sz zM>;D$Ib8$g)nQo^;_8C5<07{4x;4egV5gf2y7ZJ;qgbM9r$>HDKJ#w!oZ~KOt^DLS zj1_qcmr8e_>LHFX22&Uw3}#gHXk>vYtw$EnIhA#M{E7JJx34OHr^|mSt}r5Afvfy2 zgEvT78U~V=wr6v4Sve07&8s-EvA(dZZ!vyWkXn@v2^1nC0H)Lu%8EH9|F5Z0Y<04( zHML&lr2AjXw+@{tpDA*2b8cITLO*OR3&g<*i)H7+w^AJD>mDCewH?}LHxa+tMj{dx zOTt6VMaX)@xi8$}vV`LS)|qT!YSPe;!#=j}?#0&Nv9!zFt$U6(X$V_jXLkLFk) zcU&+312$0vrFM~~G2Tgk+K>f96qGYCHtkkW^ z+3(;@u!zA6Yey^2i73mc_Jt)|Qv@-7IsDUf+6igEOFLfb@}sQ%mtU_dzKk`Utuo_Z z*UscgU7^GdGnXmEWObFaDHe03jL=W&11$b2X>EJ0Adt1K{fE-H*KR^9@%!4W!HDS= zU>#$rg62H@o^5piY`?UX0?h8Kiug+`E zUeT5wgMO5(wB`&)=d5oa%H>VM5j|YL-kFsnluIl4&fCQJ>kyCvkIHd4s!S`noU(w= zh)j<(_HR!ZP^Lki*Q~%Qn2brT?;GjWsb{qVw_2eObCS|nupvMGlG!3^)gS#=V$OyE zB+U;~zc`mIB@(*eC3jL&9tf7NN|O@#E%BxN`|&GHZF zjxN2vZneUCFaad;a-UpPX+=ZzG_(ue3Q(65lBd++$P1E#yMXIgA#Q+X!G0THAlk)C zfqTTKBi?#OtL5Y@A>DG;>a#5MH#pi+8vgx&y7r~iCa&~kYm;$)Tpdoxn}Wu)oqqGw-a0DAM;utg7R1;qs0M6HN~xH}}YuLRCg z6#OHxI3V%Ox7o}vfVRHi55=Ad41O69Ex>zcUy3!?X6)i(OZhlD z-#dFmm~&O_9d;KyW!muxfP?#d5e`6>U2dXb!hmdmA957r=f@5!%TSyPH#&tx|AzDP zbD8C!LdfGDl3Qx#Y|u%Ju}(TAm8;wVzF`9}CDUF=wvu8#NqH98UlDh_W>dE8D8;N@h*?1Kc+IJ>GC-L@}F`3J44M=Eh6Q@D3fXQk(T0ExE}q{~B&f0>Hp zhkaR}r6UX~P6DM%@ta`XiPF>M~g9G2AXOzFi!~)g{-JSsSTRSfh zo!>-So(}wog(>&t#5L!dDmJM0LORV*+iQH!6I^ZuB9UgLf_BLHQ~X0NL8*50SR0FcD$}8p z3o%|aZdBvuAP{243x@Oy&n(N|iwL4Bm)#BY=O8tUJJ>PiJl%!{{5WXbcM;&5FgP|k zz7WO^-YF2VRC>W4cJlA7(#MZ4LG?1?uFzbIEwh0h)K%u}y%;EhYA;Y+<`|x(Q^u_# zQQ6 zy1f$IW2K8MdNdK#I3hvKP{Z+c*zv{jMi@RGabmVe&pVEs8smS3UblCu-T58qI_t*5 zclguul7*OS8BOUXXw2~6=f6z?x_8qd5-2eSjp90{vHDDp{Hdg`8Og_5Wfu{QLw|_u zYa^TC$J$=K8DKEs$oEfK2it396|3rp7na4B*02K-utH=}h+<#P1e~U2|2=tFeW&)K z+B+8|LSO-QV)FGlX?3lU9WuLGr2*}BoRD4!J&siFF)&8&y`64w2aH>dehzrcD=3GQ zxC|+E8jKGz7O&pvwoT%CmB7F2T}M?hOlkfmqWzmKe$5>zwER(@*)wsNeE#@PaNuZH z^nfL03#DXM9>M;q%AYCQ5F4hfeZeB--i(7d3bAt8mt&Cto)mOi5#wX8dw7_xKuUAx zNSf;R7NKbfNek>V*-|~d!hvV%k1FbR2e9Zk_t=ZupRM$SI_C2zP|-``j*|sYa2bwm zJ>oNLv)BTVQ|$9Mr4sRrapDJdpA-;hTxqz%eeWqNrY*nNY&MM-Uw*{EhGC=i!U61YIzjK&+AyVJnN~xnFQ1W?t>@*Y z0l*6v9{@tt%Q!&gpR^ZR3k*C^{xr>Ua}~{k{L&nxEk)>H*x(782u@ zZIUoXTUh3&$lo&;7L!vF*ZdpHgh+i;i^m2UY&Ri)aDv)~T3o7jk(k2aDPxH&ZhU9!W5IXs&Y_ZJ#?Kj}GXBC3U8S{od!9FF` zRPIAKcbn*UOumYm?ufcsN*kMT?9M%YD?84{zd+Ci2Qebi^^v0Y=2vD@_3kKyj}69{l;4gcf8S;H%*Dvemp ztsO7vit1P7Th#dk^ zbVNmQhv8KsE1>fd{g$Zn40?!ReF2=B(t@Q^c;*sd_J(@JL)&MHyC9iDXgQh0W8%t}(X|R&oJ%+SGUDvwWkrN`Xlk(8a z1kcEm+bLr5ys0%}(|qv4U77)9%d+wiv22DAsOguV&P~I=IPFiQywsC8(eGv*e54hg zv{J*QG?qlk)?kwODoo_UGhO-6KBl{BiWSwlSR(0Ot{{HSfbNmgJb2+(XXGaI>WUc@ zGU75a9rtRc&*jVlH)>5pv>9af#OhJG1eOjnUFv$PaWk7cQz3PAW%fr^uU~X4PiG9i z4v;n^t?)KB5G%E2!pq!4X_|#XXMug&@5O+@ zyPfG#rGVv26!kAOs8GZNPC4(DPQtb4b6KJ$R~NR*cZjKJAKjpz?u_`G^=|eh(v9=f zW>AE<{)$;Mi2LpVzUCBbORC0viRZ~a4AVRY!osY#A$?>_Cj{tbOk{!w;#C`u$6jW) zu*VkB_&OQ~c1TF4ORM5V!ZEfSaMN!*2iy|UAmQc2gBR$gBN;MHf6^QmTQx1bJvLP~ zHk!NJkL`jCc=PzxQd*8HyZvs$01=-;C-pV%Ec&CSiL?Hv+O@~fYyN{dd2YV(v$8tu zRie+p(3OeMV-)Q&T*EOqj0q@Hdi5`zwLf{+Z$Ey;I!ediA zqP6oA!mzvDiAh1q);7v>aZus1%4}NZ!Kdck)~lpdr73E(TD)^t2vi{MB?Un&j|Y-3 z^Fp9FaVJ~cD+0L#8?JCtqbgKaJk8 zOCuC&9DA*5+2217V?4Ds06?*PEY~T-U0PYscy^c&KL-1!%V1#Fk6Xq#xb3Ip+3Nrw z9{v`9A^c{E3KAWU*V%(3Gn9RNH2f$YwHTun>D%Vt9PCLPyz4YtixIB=gjhNAp_!-g zhEq+payPBzr*du*{J?0!HC!9* z(SXqh!f-V5nsZuB>uco9G-jL>PN6SijP@d-{MtYi5+CnzOGqA3=_d**1Bk8l zB@7@wa1>Sg!q2SMFrlrl3l%xDv7(zf#RCA)7rhXb>m^AEWCPrEy8C{(Mf_aL`hZ$L zrWqx~j}^4^@mhMx&2=4fLhTwb?NlHdtuG89re~b^v7h$hQvjw0b2Oz4??;BL#$(mHh|6rawIy zfm61okq9^pb6G%M>?g2`=8B8R}y#jE1iAOMaM^FS)CrrD|^UM&Wl z7oKoHP_fDMA+JYMc)+frTMvLylq!}JW$X!}|+oL{C>W3nRoJa-b zTMQ$H>|5Aj^LY26-BV?YDqZNprn2oMo40MF4-eV^)t{1oq}tK9m=5f^*XU44{p|Qs z-ozKgR{`!BYk$G;N0^0$Nt(?FuDR4Q{IR*3aw64C0xG(9D*@SJ-I{@)& zK-B)qh5$)t)@dNuMw>#l@!0;lV)D4tf9x_k~Vfb=xoo>=&_!CbCfppCnt5 zG9<`oWWvX75}s&`l+Ty{I|?gNfdW(jVcaK%C%!D|yn+O?I*-xy`BIu^&=!f%vo(hi zR%n2mVeF=WX%{%brDI!vG7QV?ft$Gt-RqHr=Rt)?&-e6of?WQkadlov9X_-+xCk&` zl;h!Mj_o(33|2?EPYPDzXmFGii-M`Fd6(RX5PF#Mn6+SDlM0Fe$BrVsy|t>+pU{K@W? zZdAOegv4#V5FaC1Wm1M<{QP*|~*%K!|~;Lv4|JY{L1uz!tvb+uXtUU3|(-Xi?Q`wD-U{xYn~g~6qreDXu|xC4a_1A zfvBPdM3#4nwp~ui>nao~Q4p;vd0MY*d=5Jvubkn5R+T?^Hpl{V zPU@Bq=Wmc>Q6?g-0Ps%>_u?r%)%LJZ{#&V6<#Hp(rIHIqNxUc#aa$p!eKRK#YLn;t z9G{ZnaBdvzok5lz{h{J&R64UF9|AhW(|FLa3Z_Okc`)0`xhfRey=&`)BMk(2+(g;< zR8@Wg4I5^478&nnFVB1|@;WSq?mkDTWhHCI0jcq&5CX?9SUY3|ML4Z}$KAem#qJYO>wI)}(m1G@JH!sTy>Z~}4~GM`q1UZ| zEVk=_ezW5`!kx|6gOAnJbKaa53f0YhYx~;8{ex=vwAT^iK14<&pL29{IJU?I6aMOX z(bPSpXZQw4*mV_g|H*L(SyS27l<_2{s|P%?bOAfhU6_0qC~Yc@_{AD7{|nKzyI`-R z#i8pWn1A>K1N!Z5AvBL+8g`e>8AQ*J$31x#y5K(HnzMbgUStS@T`#eCV(BdJ#tj-C zNBQ{p0O{=b)sc)!7@&*ffqKjeSeOyicUs6((Kh;|07k#ly;iP5K{nQpBEEDiEa&LF zCsxEzMR@X4MFvE@r(jFDz0iy6fGjBQb6SfUt64R`y7?ijqV zkJlR5alP2X(lHH}a6i97B)Tb}IR@cVo;yGTph*p_hL{Hk;g?Di4c`J{*){}->o&gj z?;zxZBw4-%HrYF9r;z1A!;ipn=%AMlN5jjc`MW?i_n*r<3V9a5@CKM_F{3dO*Ilg_ z#K~ZRH=-XFU99twZLJJ?KOp7$3JA?HgPs{v&g1rAADQ)*Ynp$;EASC{5A)T{vj4#G zYncklNe8V@ufOG-9@26I9c&p7xS#vRBc(~$BaGcJrB;A_KK44GP5~(_U?YJ7Jr8DNSjM7^_Vx0Hb&oJ#(79FcnYFL>T; zwc4HjYqSPq-Td4(KmIB6pKhwbyvh1IxMKv&3ET=h+RP^$V=f6SaLx}&wL=g-A78(6 z*CU;5JO39V@D0aK4q}mh--Ieal)-(koabJ16sGT#u+OnIbGr`UNc&*xN7ft@MhnCJ zup!J0R-MMtdBP~(J$SnR7`uKk?#Gljy1cmHE6`;kSgL!ukTKjzgy6m`|*Xxe=I8Sy)m=GAJqe8F-+PwhXdi4(N-V+a?KUY8j^^ zMkNd;QZz`)i<2&|RuA`EV}@;fZyaufnXiq-Lh7F{XQ0*tsVF{#mW`^JuP-hF2AFK6th2w*2V zxjekSs5I*|FTCX?D5K6#mv?#yH13wq67u~!xc>FNa=rE#-IpzmMbzL4heuR?(y7a< zV!n5f=vQrE5%T&vv3U&v%h}|6V=pnVh)%fx?0z*leU=N&(ho2|&O&%QQRmPVj*G&$ ze^#9eOEy%lXj6-9k)dM;E&(c}Ln6Hy^PHxJD zE3Dvg#>)3;#`C!vwx%nATQuhKam0)W{;fvK0R#38(8iaNWNBUzzt7P?!+JX5pZsBo z<&I+B+6}wo@?R4|dEp)NAi|QMLWyxghu62fGj|xuJie8_9U*#ne+*GGxr2`JgXfm z9O_<5g(M%1+K$k-9O|WPQPQ>be6)12aEgee)W8Vh_*I_RtJRIMRoTIN zc*Ps>mL9siln!Wq1q@g(v@E8mbR#Qj<2_Fu_q;C8)q03d zi2#C${jYYa?D2TUp&6+59>xE*lWTu zrC4pQ!%~fP@kz!0JNsF@ANJVoApnepkd3n``=n|zP;dRZt^ntF_3c-@+>bH_+Q2Z) z58p5s7L4%FZ*i1ErVQIXh-PleUx*F$MrUJ|%Ff)^G@}X2aZgie6|7g@@n0y~%>ARb zB(vts6G~^Z53toD$uAbYttQNk`mZFV){N9F7uDv>ffl#4_qMDJJ#t2;ESKeIjpW?; zwaaCAwtx!8cdp{xDk1x-nfDKWV(BWZjGYcZ5EhQ2Ka)F&Iw(rv74(!Z?qav}`4rTa zk5Dz-mG>afVYASjrVeWA33nFjFfZTczS@FUjU8w11qkt z6bx_;a8v^u)cbgu^AX|4ma{TM4yh`Bi_6JlBpUDBL-QFoGU(Bq^(C;qP( zI7}-yVMcJ_d!kKFvzWGCn}0gI8NPiV&Frz)erJieH0@ZqRab3lQ#4xgdFAWc`zudL zROG$6tR#W8xoRhU3@R|rhgSUQJxU0b!$h!1x=ZH|yWiIsHP4g+!e=scS5PflZs*Lb zEyeo<=93Tyn$3QKQYwoBH7agLJJ&dj1}nCo{}}RbPTDEYI%mDo__-R>pmO;lRmGq8 z7LE@j*BG4wzpclQJl)|Q!JeHh%O($FifgUy=yLc0B?NL1u^;74B9Cn+)(LTWP^lQ6 z%m5QHpWv5Y`z^5pE@^qlrJ^?flxd@z9wWARSnDalOSB~VZ*V3mNe}{^XF)I>C;2!V$WzQh@&w;FMq?cTfCO}X3m7Q8#DEf6Aawa#2!;D zh)*80=^B3b0&w2Q^c%ypncif1%s+0N7iEI@{@y5E=-lOZ)Qx{GMKa7R6lMmpidFC2 zDe4|9gCGGCUFVr0!qcFb$AjD-$pp4aADTx~?+|=olb~Lp9M3Kbq)Zqc!z(imM#yT@ zn@XXN=13tcHH26nI^UacA;$zZGnVDy(w%pmcGKU}+(MRPM`!4sb+b^t*ckr`%C_G< zOO$3dxd7*n6+aVH^aNO*JRP{CSpj(nh^H5&mTr21uIVFgn)>|{oDngU(0CD{_h%X> z{!bSK%ZrKr^AdV*&$kM61gfN@EsmqUR?dStHCcW*!Gb9SmD_mSb1URnB{!C(7?KkY z-ghh4(j~(bzvTGOhm@LkXAR)6-Z3NB4(eluTqt3F>uOU}DD?5Mfe@~8H*K`hEI&NE zJgnaQd9Jcn&~0le-zDw1%9i_a^J_K5rrqR6)rns!41S5$sARlZq6G{b88 z=N)$e4w-F2JknGDKsjmb>W9~wR?9=ie#{+^Tbv-CA#}-97&aTTLcq zMy_0id|B8DQ|P>QOJjd(7$PIDG~s~VuxSr1xvj2_ z?_Xa(0s>JbU&?O&3Vp;1r!f6)s6xW!@gb>-=d?~FCas6VZ zid(qs0*f21De+JL=Vj;kRuW0sv2vxi3-5jYv$*|@+=b}QymJFoA{@e!;vsZ<=u1NP z@{fkr0myCx2QMrdG-)7JTKV1zD@rrh%EF zStf*!8`gW}m`{)vPxQu~e3@Fjn>JZ7bqXlKzwrML&oS}+{|xWM`D}UmXCK-_$o*?L&l1ipM`VWFWp)Ql_sfp}CK+$xYWBOdD+GwN~2?3ZfURbG(O1A;>2 ziCy}_5RWE8x8hE96w$N8@OP6oxpP71O8IU{sidi^vEQmEKYp~BonS`EN(#XOxt{Pq z3qm@F6kQS4;cmb&bP<8-d}_-tvVVMWnb+S~bHE0D^Pd5EttTXWj902HBl~h66urRdf2IRq z2Mv+i8BaVkP!d~DYTR8MW+|5pE2Wx}e$r^XZ2G@?OL603R`+U?P|$!&h+E{$@b_c5 z&O#e^#@(Sl$s8QZl2#Lh^JXZp!1^_K$beWEl^UmqsUzVqNds}SGvE==CLjrqOJ5{c zgT5^ebC5@h109L&@#WHU>G?1d5H*CWC$~LR5f*qSz|yjqp@5?_f$LzXglrhcn02uo zRzE!LX=)*oA_m;_T z6~YN>keajHBHt zXVKhO<6r3wfjWd5h5o#gWhRCzM2qX8%QFv0o(WxP=Z1*&Lt{;N`dDLm{8H`gDpo=t z?_V;9q77}({K1hre;d4T*?oM!KxZ!V`$OGE6q>Wyk^w>(*i+ZSXJW< z5c@UyXn1h+N*;o6*zke7{TG!Mx<}BG+oSoipba(Z?>cv#Y>=EAh}KxG;3`u*o)8?; za20!Q#DVQ~$OfeIf`yX!k(he=E^5m6vaX+ud!IeVz#R}`O+Aog;~X@wR5Dhw77VaF z$Ll5f*JSz(fGaN8RUtFfUbsAwViscXd_7EzjEl|#2`J?a=H^gv&@3JQtXfuihRcx~ zZf@~8NUD%7b4!$?IATEQUI{)X-017t2eC;s)~GjD_JQq&aMDM1tE*g^Ffo7Mjoc|a z@tpAD?NuNy(+x|y;#pk-`4}x)43n(IGP_-9;A0`b?IE$>J z$Du=?kr-mhj0@lNLrH)OpEd=kEhK^@b%fJDqv_Ii`j5|DRjHPo0=RH2%MSi%g4?}N z%;$C&aC%yVtF?jFF53u9$bcXpra1$?>=a8_FZX`XavG1t3%=knlK#ubf%Kt^Vu1|D zKgJB5y6_ou)Y^&P3E;?3kPrB&!D_zH!!2>|x%PXQ?uB;_3Lp2VY~EIijo)rH%ET~y z6wGy>aG#GtDOuleC})#}Pu*w~4(7_bLx*0x=RP0#C=Ffy;vVZo+^A!bM&v=qJ-g~B zpW*8s2iDwZ@D9zl8typsomKAJxbr7)Uj%jTJ}?7+C6lOCz7GcX68=cq`z$_3Rs@%9 z`T6nD*t6lJ^ZpRyeJ?g|ihjqSUDI9LkhiHF$g({6OU%eXhf9mO6c=yyIzt>>y&ld&hJ$^rI2Q~ zzvsVRekW}IM?oSg%t(|H+}ArsN*;#*23p6R5^?Fmy>~UD%6ECV zB_%qI;BJ&s>7+Q{bnn!0^5n;t#95VLTGv-R@hlpV+~ zarK(|SGJu05>cfd`uc31TArP%*HNXF#$(&g!tR`yeLktLlL$ZlrXu@re$ipcHan%4 zk!tjc=v{Xd69*l&prb!uGRwlgdH5zhcQO{fk9!FJ?w*jY*|vM2H{JByXM%+O^|F3FGw`UJ?&))J!Z;F+fA_p(@y&irMS zI}BJFhrK#}=ls;1na0DzAIp5V-JG!U@>!xJeckZ$F7wDtGW}kKPqu2l&e*RxyY#dz z6@i84E)4u^yX(KE(N*O?BtN9M@5?qY=u(Wf;RG;7!a-01~2|I7{B|(#lZDj;+ zTpB2Vq%y1!;Uljoqa?CEo(>Jz?1gf@C*Mb`l?F{cFSOE!IehrA6&#H7k*Rsetlf8pp$E(ykZV}JE5f~xW4=%Nm8>%l7lxfM{{^Ozos6xalv5( zvEV-UYuJivUY3cAIT8;0$z}9)Z9?2StY&NR`>$yFKOy#;u>HYa==|X%8|%3|6I!`Z*KG>>W^!jF_-#_~wyBoe-=1|| zWulX|M*&{fS-DHI8dqpJ&v|VrgLf1X{j9qkjH#P9qxI68!Dr9Dl1W%gv&3P96etsr z7+|EWQuyoyPU$IS-%CQ9OL4b}cZ%vVf0Q|+G|SHb0+`|!?%K*qFa9TT?YF&&-Doi2 z^&Zv2I|Uhzc&+^QB>$~#r=v{J5xZNEi#XFQCO29g--h(3;7e;en#0vjY&nISGh%u_ zG_DCwFKi4ncQ>8yWc@S1q0(>T88X{DwC>58=!FuCs-S|SZ;Zd{0Sai&!5>vcG+ zs?Y>1bG>o^Migf&!p3|rJy4B8RP#!N>lAD$<&AgkP>kF&JLnm$O^VMgSRaLcUMEqo zenzcA1J-FPEx)_%8uHUj-1x~&OX8Z2TR}9*YxP^DMAC@KZgNpHN|TV$e9W;(RiH;IFNwcXRDyo2}VE>udbY0_Vp>m%8&VZe^osVnbC&fp< z-DDWBYigefZ~xw-{=QcJ9QdC3M&}Zk1{;NRzpQRz?Y{EX^Vmg~Qa|8k2T{#+)>*QOH>F)a=@%YMSKX+LL`jWKvw#UY|)igt{kG^F+0Dt!UrXx zIlh}3pKo*9&=|nDvv>>%-&Xq4@)x`}Y^BZ|O>7($uP>Ey`?~1pp-h2Sl*+#=Z<-RJ zhMc0=bti-5Rk0VlNi3o0nIom`0!9~6Pd7~3pT2?wB&hxCXRYw;EE1w-8?`;<-&9>A z|2xkkcdR?%ooR|cNy@u2Qq3JSlzI3qT=Y2ONhPvqwMmS(&bXJ7R=~8S(>qSH; z!t%ANceQs=(f)z{^w_zQj#R;c1U{9<&WT^Yrt2@!J+ZGYAnDi-abArZK%?%W5Jaup z`>2S$xqfGzFlxCSbN*FbrIV>g-SBc==m6AsrxCTfDlJ*l|BmCD|BER^hFYZ5o}!1c z2NQlT?8ro2=bQMk4dtut{q zxvEFv#X{O;l!xC-8}C6k)OWYM=F7fRF(bY}ywW*s30ZEu*!pa<>BG3~bM?IK50!)` zb_SG2cNH<0I_-QMsf>G=zD&6}%8G1o$g7&F)fb@_QGb zIkD#CpYylR0I_ZI+=+D9z$k0;cXbomIic>Jwcnak2U-q#P`4FWs;HN`rMcfYl!nl< zj$M1CaGQx{9Q=EV=G9zBAle3Zjj^w&Z3eo)Ew+V-ZBS0S=qMXoE3!Trq20f zzTM?&X~ODp?B+A>h0g+}lT8dBUnPIa-}=lUT~Zl?PW$KdtMaIw>r#F7&VGC>KivRm z|4xRzup$#sz*a+#q`-Y(($5tpWJrg*+6HZ>i7OYOa4$+HPUX*Zv||BSG3*yEGQ z*2jHT4Ly3$j^%dmj?C;X?eDYU_?~NrHmvKrLtvOZUE2GrIGRTjE+6?dSyaoHEWhV2 z?R`;X+{kJi{5LPlAX5i@E*}2a4!f$ks4M=xa?W~iQyglHA>%QKVNxCkng2=1aop~% zCxdcJ2Id^QvYb}(aIZBd9vC|TyzyHyH%A5TRrvePw%ehVKTWQ_r>iL5H~Ln0dS9K} z%R)fvOvfB+PkAI!Z8n6sj`}a(QWUkE^%t>zB0iNn;%^t3?r$=H+QN!j-cn=uiN|(FZj6Yy>WqpA0}0`n}HWNb+DZ}_Y>CEzA;GnjPW?> z!w$SEY#iQ$xcnX#g069}Jpjuh>UVOH0nQCcGbV15po_<_0vLS9ICy1&M)p25^z4T0T+{v4K6kM zJ)4$P{~yBMsw=Lxi588Zf#4q8-66QU26u;$puuTqAXt#bUAxiX?jGD}+$Ct^?z(x; z80T((*}q_2ta@h6npLyvoSM3d=ot`)k0;&7NU05I;_i$Pt9;s_Y9+Ui)S#Vi+hlZp zihYIVp(BtS2xFIm4I%6qlI|y!6}__iGRb;r^KubwPrfMb90+u0Gv7drg@Gx?=(;0~ zrZ*FwH&;dr`n@qPq1`pBqM2AcS!SSHbC)yEs98#paLAfhb8@$cwB;vRY zXLj(NnCKF;S$V~io+ti#*J+Q-#>uER*?ycL-++O)s^Xh~viVj{=#R8?d`vlMcFPpD zMI++`$@qtvU)ULJ zMtWLNsBTt{e^%dhF?@OUoMb_(YF3T4&gQX7giS9ey`Qwc6NN-gP-NiOl0*F_E5N5%b8W7OZM(f_ zds{;!xL9qgstV_=8>i3sEumBvBbVDEHmh;VEL}}=a8{KY_8($J44eG+69nI8nHQu! z$Pi)Bd_hvLX59Rmjbv4z{vxwnrI+6-L=ClyhpSt#q2W*3)szKNHi3w*#garF?CIC31t}?{JWt-Pwb6lY-deJ56kt`Lxxr|mh>FojhLGdbh%CMcXJYP1YL-dQQ+k=EIZwrwM$hAi z8%}12)60A zELY^hG5c%VD~w;WMfDXq$Iv_pxKfbs?UQi#Iic!TxzT%~KLmk0%eD?37gHQZOHa&u zO~C6dZ_aZex(@DN3)bZ(=S_LuJiiL!0OvNwAribh=vv%Bqe1*kTWi-u6swtTkQX+>Z@R4*=~Bp`kq!530q$#EpwP>N&+^({@|Rld=F(cG``3Xk4~WC_ z?QICsrI(pv3;1FH>*#f6`86HfY{tW4kpA{?`Gczpk11xz8yh%I9;eE$e81kQ6$%{Q z60`MuCq6)rJn3JzX{r3(JYD+3J4vm=yR&W)4cUKgAQ+=`pZl${<)v&aYysel zvAeJ?=#hn9Ps+>`sxALF?G1+yN?b~lal4X!qXUYIl55@WC(z<`g4eME%HVLzUs|=1 zJjwWX+1Kza= z=oX}(0+FsD$Is)6Qk0JAVq`bi$KJA|ncy6A{{!UQ$4$aGnj4Q{0*PBs;(4m|Up;)^ z)4r%m^Z$iu^ztb^sHh@aVX6J{XKG)Xi(C$Yf7wUFh|4n zJp(WS(pU9bC3YaA-X^@r*t&yy{XWnugEiLYbN~Pt?IxFx6N8i1E9Vk#`9vgh@XNhE ztgu_Ld8u$9M&G14`gnNWp8maKcQQJI@Q}$0r*8x!VQDh^fioWO!RuqRy6k@4n8RGL z8r^FQ&Y6>+)`Bxyh-7_CxWbJ2XW5X2g##kpw_YyP*l>2|K3bGa&^l8;%dI{-YI9jAd`FG|LbkNv>@TEPrz};7Lt#fsJ-MghGE_eT%!t zREPX!FCtN&nSYC`p2AIUX6^(BW!g8?IBq9TrQlRkcI&Nc22RcQlu?f$R-tg>ONl%G ze56fFKj-lWXZ|FcztW)-OejGEU~W7nBMwAmv=aX*FTE}CyIT$aNjsJT9Wb$fC9tnr z;hvh5(2;~U&idiqfM49>?#1;^{02~6*c~G5NoN|(7yu)%#6aZN$>jW`rt}dj9j)(f z-z;52u#aCr0NL5b&)k_(7nt+=fO1jyJ*Vdi3bNUaGhH=I{6G;-4N`T{+F00iBOT<4 zbg44m^ANbR_v5CJpn;Z`v`+Cy>zB^vKsh$&qR;}w*O35+1jK{Ty4MYc?(nk?SF^)o zwlzE5Mx}G<1`HMAQe5YNGLaV6Dn=|t6Fd$=+eQo>o>-lP8QASzm0i31HdwRwt|xKxBd*JFE~6l0`W~m(PXFtn-aI~X&5r8; zc5hcxd{EPBq^7g7rY+uXVKElsO{_Q_S2Lof&qu2g zJU|Kkvef1DwWQ3t)*>^>;X_WsnQ{E7a5Z=M-4Ci3e?H&wv9r&<;);B>QOB2)OPO*T zA+l{-*V2N0qPzUhdeC%4VMnPPzgMd7Wp{vCzOv_d8JFc=?iYJ#%(u3>-^5BRY6J6Y zvne=v4{5u26t)Do`{;B)(+W2G=}vaXDi)T{jHIne8h~^Ij{}}c{+1vueFKciY(+g* zMM72=Y>+0xRyK<6ITIq#FL&&ID_PHz^n8+hErgV2^WwU{n{4Rnc;`$KSaGrFnp5?4 zpG#iPIS1jNZ`mJsLzsvsIm{<@Fq-B`W{?|? zfLuD*1o1+Sl(}*i5Q@+Hz|*LEaj+i{Rs9n&A7|stSPfBt>S9bK#mw4D+wwA~gq|QM zB-BH|MCx6~gvx${0K?{%s763=o0jz-_BDbUB(LelFZ<9uF`}e=3HZ8X!q0Ym*Ou9- z<%IpZQ1iitYWb&nMjuPj;+d4t&SeOxE3n}B;F{*K-y2KTXDhnk~tOlY>dM{sb)<} z`v-v2*lauD7Nzn$irOCxD&42pg-(moSe%I4Wo*J)Vk8RPbZH6@76KcGc@A(U44o3{vMRDin3eq3fqeV`=!?;}nDu@iFH!nuFB5Ht}ud8p#s};y5P$; zL@XcRXDoMrbg04>qV`geGi2pN0J7fy%~~s@`p8My)W=%V^!~>&!lUVV>wv{7!>#9q zw58pcY|3H`>N=>XB2YI15fhK$sbI|U1YGBRG(0NnE(62aGyXx(=ALftq5rDW4dFXC zI%7AXz5D!($y5FX?G8nPa*MByo7H7n2yX81{dZADwbr9zJ|gTY9mG;Ovw9D9I!D1! zu3knDkOC=9v978qWwlTf;Bo?iOD=%bYS(?=LMud53aOs!{A+v@G=*d=q-YM z=orTmI4leyCV{g?Gk)W}vry!HRdX^IQ#q3iCVL!0*a99K-NJ<#s}S{wvyqcXWrawQ zLB(SCw+jZsN82L23zgi6@SSJ&oH$6IY4Fs{dmE3~%ZLIhRYD2#sb`~`M)?NToHLrO z`u>W|AU^F7m{aF}LAGy0i_CoFgFj+H|K__O1w9J%W%zZW-9hB?kVl75Aa}`Ta``Sp z{_>s&Cpnzb0kHBP^O}^e;s~Q2dR$ zW^C)VI-_~Upa#aItHiTK!^(W5$iO9(vcL)BfH3aPC1$scstxI9%$TXK{h&^cD?A5E zQpUVP)QNAvp_Y9-YOIB|fdJ^4c&4YC++FQ|nXhz`rd|)g zT(v_ER(aY0BJHg%&s!bD^MmLv%S}w?*2pi)@HanHcnYxSIBDE%IHH*X`<2EYTaE^X%ZI8fcxldP=P>NyYM$5%A1zW3B%%^rVUj%tg|>_+1!ll7y% z*l(9$Z?4lC>Y~z$i>yEBmQGw}x7%^jS!sYfABaa9(>b2UfXGb~GO>A)9Beh^JYXDo zwij}%iTv=NK7_?TdX}%N9%3ruS_fbVxYWfNy_uZoG zc?rhROM&h2%jGJVdlXX-I1aKZ(i18dYzgPrYSdmeG{67bx_tx&`FEzs`KbnhNEUh&5MSQHo?O&HhIF3=F_`wR&WGw2Fn< zdhshreO(SO*iz29X`b*Pty=(y_)=v160Ucy#d;Qv2u_LaN&loCtNGP7E7R_xn(F$` zg5d=1wHWVcVb}}$Uvn`33B{|Q-igZvTGG7Ju54!gjl_ZCyeP2?T9I$#Vhs{`q8bx# zX?v}c@u~@1DnVi$bFvcyX5PK5ms;Vs@Gi>duf?qZxjou>;j?L$_(AyXE$9?sPZ@u} z{8c+{6c$EU5OqJ(s$JHa$)+szDM|y?vpIEag4y2KsK~QPNq+aSDvKf;j1| zRpO@I{#MlY1s(^_qfy6(I-!u1@Aq^@OX3>l;w8?N&r7x%1Z3P~F~N8RT1^%ID(&

hfAU8iHy1J)z82C=6=ETik+u7ckH%$kTva|hM(7Yn&gV6wxI9> z(U){AO7SCWs&*xeO-jxeQ)iD$nu>A>EzZx0(y%g$Q`VSaeVlNjOg zs&YM-U4RhZq-g9A?uz7~OG>qISZ9Lwmqh{AiC7F!v;OU*J#I6;HfyLNUG#vY1T1%+ z_LfR^r!e85n`1U7Ui*s6j_I=j<@U(4*00QJ*YZLp82k1EaxQVp?NT~@YbkBl}jULUo2HbI;WjrTI*+9j5UVIx{t$j(BgznOay+4sj`Q-si#Ko`}~W=v>N=^CUGeE zjcxm{0T@RlvC#Bra);5lVvquj!AnuZikn4&k-IJIPs1e}?I59Vzg>N;}u z5(s#oa-hjevStO%swuxHiM#luqDS1L88rOvt-bO> zbEb06b* zBp6J9-C%NzVorFWDm#x32pbw}$7gl@;}gJfkhf=1-Uw;@+*9+V2e9Hnu8|&;(cvoL zBNQ?Y`h%Jc-owBZ1V`UrMHr~uSiu#`MuW<~>J~u@3h*d-sJ+1a>N1L2ecAOE^eU#D z{oQe9#oUB~i?L!Kb&BpEKB^*c1?`cgoUhdXU2B%$Ay{$uq zIlkp*UBc1UqjU)Xp1c|XP4@`%0&Y+v>Wr&5q?yLLHAx+$bF5h(-@SXfSpM|`-Cd~v z5_a-&(x0xN-DG5quFnH^l*RMnU6!AjSkhH=eXJqk$-BwdezUVp9IXN*;slQ=KhLNjIg2?43#t;gMo89J%XERr>-l{Ni;TC)j*eui-{1$UXL^{DF3;rlxgg zR&ZD{1074){)E6zLf9+xN`5t-c1Li=18^v#p_?~{h5U_?R`?=B9j@zn&ImL zwxN`f{=IMIL&0}X6a5Aco+VFBkDD&uDlJJJy?D@rqfOFqXp>WB{ANv!0?YlPp5R<^ zvcIFl#DT8LRNPjSdWh%^fzwN*-+J8D{rI>^kP(onuRh{S&sIWGyv3%#8q>a>M&4G_ z(MksZVVkfe4TM^Do3R{-=G8!)J>WXVL>g2SAti>idq#=pH!x1Q6U(y) z61128A_iNcdh~RujN)uCh(6*%U{#R4eR0zTbX&psFvTGwlH^8FR7usPMP6nbp{ODU zA<`?=V>n)S^(ZXK1%K={ez@ZOktW~(NkD7vmwhY7%$QyD1~1l>FRJMs^nkmMqSR-Z zLF?N?8bIhe{go0|r?E3kjBw50CQ_^thNy)jCELS*!`wGPgilJvV@HtNuf+5mY?rb) z#FAbt!{>+2DGtU*f-LW(60mul+U1e9jEnjX;fq?5waoORyisuT8P_8Fmp*es^dDO} z*xTFsf3TI9Rz9WaMQUrCBxKv2A7!=fQ~7e{F{@}Xv-57oElmh>k@MnnxiUg0hl0}K z&l3{N@nx^lih@K-l$jtVZAcW-{&b%2K=`6E&)D)u-u~}cX<^fpgW`soB=2%PVp)Fa zBUr&^$)S?_vu0wHH8yEdg{=$upPL+5yZx7iZAMhl#m?o_kXzm%7wsQU;f>$$b&>Dm zWi%O9#_R`NE4AA8NR@FNK21uD(ZMNQim$;jnZ;WIW|8b=_Ts$uB1?c2_8($&35zQc zfXr59(mQQ(rL?Hw^tYF;bXYzk{D76P%Wv;!<9|~nh2)f|yKS8{6{c2hE1XdD_jX4= zBFT*m9RYo!lw1SYjFUZ}g#MnMD=GP=nFe6HqIV@<_vWt@fD{ zeec5^eo>eXuNJtbg?E+aWt;;l(3DKYr{@|P5JP-DXH?O9kwM~Ykpw)1gg)?O2 z=u6O4)!$E55=5`-SodNc${@Yfog=c-J}6hgg;_gYco#JH$kryg&1s@`Nx;)t?DrW7 z-Q?pI6eb3oUz@d-pnj2>svio5hP|s?yv!s+iXWygeu_RSXINW%EqeH;_6>c;+z8;{ z^9m*cBJGa^swCc@|9uwnvYh|>yNh?=o5Aa6kwAaeSzc8Uu_`^EU+Q1c=SWyM!h8e8 z$b#;~v)CquI)1$Y7_+7LOxy)!knCQ8kn57#Y}@)J(#~MOx9!pY!d(y0f7;~Hw5$2Q zV!s3X9Y(#S(_>`sC^w`D{+q z!v??9O-GjT%qd8`qlMiP;gnKecr53Y*47pgZ zzaLX~kL9Co+4Y7 zR&f&F#Y)0wj8vstuyGiEO0Ggv$gw1m*$(qtFw`5{Y@f7B8Et>IdywRuUaR9gmNg-q zxhemA+dkuq=EG@Hqkc7aY4yBvctuYT%cAxKvN>h-Gzi~2i%joQ!fDXak-jsdsu-XeJ&GW;f4T#3z^J`ToT&*xO$Fu!di31ZnaTH4ih_B7OU=|c2j~P zDWFAAzKb?79PeK+sgscasyqFA6w1_yinB&=lbMa3$$U2Wff4I2m`Q^oBloDemJV^> zDZpvo+b71BKWLuC6(4;sWG$3~8r7XxlV2E?=54(57rr`I1?ei9c1-rud%oK5kyumESc`mLek#u+b z{!gT6qI5#VWE!>ig2;m#D@TelE8!%ERzq7gCgAYRomxxET54rs^P2Wg$*n_e^9HGL=Bq+$HIV(k<*(|W z8e*6(k6Mi}weZRA0oDc>823n6gq2LFGQfF^CAcLOVNnElrtVp?^tpN)49-YOCLTX( zN#d)c3mz4|D|G2Dw8FWzZLcf#8qA2KZBf|@&>~*m?f6O`GZIsFId@IKycL|Uv4S`eTbLItr z35sRGj|g&%gIZbWlx>?EvcUT~@p-u z)ZX=61tQ%M`?Lsh8O$xfq37G5C)9cy$>fCIJb_|tTsz$rBBvjW=9>~qcnhNg9n@wZ zqkkeakXlN4wJ*zrT)xNw`BY{lozI#H_l9N(tiGI(Ln}^CK}gR$q{0?Y2S~M7s9VgL zL$|?j=c`*Hef@9l5Ub~4Eee&N{sp0;#Q#km{0MCc{1+U*;KF^S+_bd_XxYK8PGdZy zVt*$Qd{Iu3>yxgY!_Clh>36Y}d<>7bl=NH}Jdzhn$FjYh2&u5uM1`DSg}wI0Rk zDaS5B^t*YZ!9!`IsM$hqkmPV%do z@t1Z*ij9q&OK4}6@jZE!6mqce&)9E4(=rJJ-%%s$59a~KlBPNUcX0FyEMDxyJ$6^J zVP35D0;$>&{>_K3s9YkgoHr1S4cl*%Rpg^P-__2Fh3W?6=QZTqI~}*x-ZMVXZxU_N z;e6AOS;XKt=-DCP$X586TDNg^&Mb@}=3Foq^bLzxR>v;doO(6v#|v`~LkkRV_HvzP zuzC6s6{~G)s~344w~N}1-#M~*=)3@07Wwfr{-INOYW?DorjoQ~$mH)O(454z+Ah{(g{B&tvk&1Ar_y(cgYv;h^J0Nlda!i$)xLB zX=2?lBg2y6ctykvALNrbXAB<5L*ypMNVbq<;_l61p-$hhun*0uqf+O_F(cOvCQ0H5 zM6X1`xDyW`Kb!wlATqmXqs2C3oVoK%#e(E{S8Y+U&PJJY;Nkl>*hg<#)@%mn0b+`ob1cvi6C0Fc75NGU=6n!AK-;cdn7z_^14DQqyOd5lBCLUO1Z9R#3q6PK{cvZtN1Nrm0yUsiU?9RK z9lIztT#hVHGl+Bg_EDBUldz|LK2>+9)zhK$s+USZ)O-{Y+-p-5iz4EGN9jT4lp3T~ z$I=AmuP<&RwyWV0!aj-fWV;3nZ=(LZsiieYecoZC(Jq$yUN8KTuk#d(kA3sn~<;TK`niv|O=I)IbH)>NtAa@U6W zvDzrtbo!(`q`507yp8{qR4N8vP#J?mt4QFymITc=2(H3EQK7w_P<3WbR5T~KoW!`m zu>|f_ZL(t|oWnG=Ji7TPJRg3CLU6XI5%-1me#ne)91oYvX6T1pyNOm`iyC1)&a&&L)O;fk8j)M zPQj|c@lS2J`zR`4e9WytB}g7%K_((t3O)6i{#>}@-JdBYDygVc!Mk@S-xLgd)Qm`Y z_4Uf9V_ip!l%wCXV}H8Z^kn>C_`ox7A~x#?y4v(%lo7B zdZ8LAI{vNCJ-edQP!?^$C2!t|PLyfZ@NNVP`E97Pt~{x$#Grkkac*!{ValU?EM0>B zj*|U7lgXhg5yjn1d8bA2ylWV4kX&#UdMwdOMFwHBPvMV337`LV=qSM#YgJk8#? zu9(7ZXz-*f<;OYm>0Mab=HYtF-rw-AKy{m}h?GXKY-{3N&0_P>S1dK9RLFJg5QvxX zVHyx?c)eyb$PY|iW8p0nVil$1CVf!|Gj5zz)bR*uN#9)m79eEdbFeW;p1*m*4 z40n(3TSs-0oZa&AT^n)bR7cvo1+A7G=^u|>NKGm$NG!t%pm39m5d7{io_HC|{li3p zWcShv5t*O-(r$fisUn1`#AEE|aEM3DP-Nuiq;uLO#@sO%tEw{>nR+F~fRjLn&DTG)|ir@!1t(92myUa_Kx z$cpg|HgC;{?cy8AiEaIf*S}=a2l4-8QfpR$_GMZS%nU!zQ38WqoIb_Mww|} zkhDu4ey!KkOd8WW8nnH1x1U>Qzu}fBWrS@iw`;g`}yHNEg9)YpRR#mHfyrQcF;?x_Yb?=3I91FU$G#Z|5B5znCB!jm0~^5{iO;o=%a7(wm?{udL9x) zatOi4bS%~)@>lu0W=%<%-md-68&YJKg9T}vUD5+XrYr`%Du~R(UilvH3a~&AlmBvz zDq_5DDPZ$&6SV(FZ|Zgd2{mBzv+JW4NBCyGuksw$VDYnDZw8aCRB1q^8*j(BbwY%@ zjiDu5%GU$kV;|?A1GsqIDwJ|Rq?8G953azjC6o64!^8jPSYVySR!_CX>h>qMFu!`bdBPz|qq|B29?i)YA(Qz1JOSVeY&S&-+1%Si%VRkLqj(%D zu5+$&Wp}T9HN>pp>agW;?D-M>(!@j;_aVaJ2-3C^19>3Ul9Tq?hQ zGAFjOO}DWdCVtNgM)BFbRq|vRt7m{nm)yHkY;{H6m7xZJTY24}$Iv_d=HePJ=Xx z_$dl5Ha~sgcN1*JOCA8>Gn^YFX1}lZhn@Q5)QL9LI-F#c2CU86^0V$;E-Lvg0(TN+ZP7Rc$de8tf-SA2>?g zt*^w`k<>H8E;c~owV?JK*A~l!m^mBf)4}Q^Mtl;*-`vHxXLjs*)4Fzv77fZ#!pl?$ zE5~FQ2yQq4PW|)}b~y`iob8?i{isaHCrJ9DTT*|o+NK7S{8|r5|VE2!Rc_XX| z5hdfp9OlAW!wcGi=e>qQT=(H-OK)89jI`K**O7akdym!jGNwdFzhj-E=iykdWLh1@ zRN5=(v!1oM*+G07+&hW{>;<#&-C8cYgt|8`x%&LFdD@6Q0PNjpd2n*16=PtJ(%|U< zo6yHtR+&Fu*^&nMkdy^Xt1CIZt5EE@xDvy6Lvb>hJt~lR46HonEixC66?B=@3DDH@MZbLMwVmwv_2oc4 zf2(xRdXRr`l+KvXdarmNi}H0f&vfM%*)zw_`FOnlB5nfzNr?xQC*XgLDn6Tty-~sS zqt#ZvGBt$n{E(DbMxW)8N&4G7KeLY3lBGTyy&2EzW=~=8Fk^({qRB3J@Xq2IcW?|& zP|iK$(#S2b>7cc@7@trTmn3`>SmU6#Ek+0@_ke~yHTEGfG}dWEr6yUnZTB=dbvIif znP%foZkL5K)`6aB6(eIF!&zMTFzK4W^0w(ksXq><)Lg1({KpJo&SB^;xl3B^_HU|7 zluho<`^FLR%L7b^4DcS3aofxE)TqE;=i*6Xdh~`iYDlwL!T_z zacw&#X?2BpH|Lp^3U2mVk-Glkt6OeRya;W@F1YmGZioz-kV4uvT7(-9xSpa3 zs8ACH7K}*yUGZeZ^GJ;go;dLP*d7ldY(INJrd}%YR`yA6y=Y=+5JYwaZIGzw%(tG@ z-Dy6l{dy_16vD+j8o&pYn$=jqdK-AJn|pC0W{X4BY=32t)C^t9cTf&mj14L}pP_Iu zURX6v_Hu6Xlk#It_*jUITG3iyv%38T+Q=rvRScIoEEyY|Gzgi*n#FDDF`ZG0$7~03 zJL<*lCqE$9XAr#}7%Q@mZKh$fV4u0J`TqT1oUh`))_BKyF%-t&SxpzAMBXwbVWfPd02DOX-+tsTP{4Gd^Db9 z``Se~ENZx%xKz9??+?6@6rpR0roWCpc{g&pOK0}$R713Fn$8Z$xK{2D?s?T6!vkf3 zc>CCAZo-?}NY-5=kitqqQT?T_#GP25u@@k8(6X1xQcdCRVSfA6U24qzj0N&CJO9ieUb|7(I^a# z+qkV2J^XTvz}_YOVTkGnrp}ZMFl}U;!-&A&tcaQIS_5NJx6HBqsjpUWSXEIxjJFej z*Nf>wFYGtMWNtF~r`Jo<-)}G907c=&|N z7P8cv8$uu1@Bheea<6!_rkMSY7|FuCRYOXV<0;e{tPQyAb2z3zf2Tdmwxy=V&d_BW z(>$vpNo%fq+8AD^{RCgdT0V{$PmCAF$7HZWW6tcu=ZHNdf%n{F+CNLL>_A;^!NwWw z4Tl=1-^DJ#J~NibyWOFMR)R}JyC<$I%n`Ew`To@Y2;kK~*n|fT1$|T~jnx9y zY`<3Y_|Cl4-GbVW5kZzkMw2YsYubVhtk*g1z3$i1fHulU@mN%O^W?tXK7 zMJJhuo#S0wu#QMs!_*UMLgT~nj&ps3vik?Dn`yU%l(*#|A^oup>Sn-U^6M6P2gffV-JHcitH z$0>pfDf}u&td6k7qo|Gr2fEF6pXHL7a<}mzGV?u&F{6>CPc>>)ITyhm4?rPNZ*QZJ237cIv>Fb$?UfBu%&;z^&& z~|Mu0I+4*NpB3vMYH<{)|Z6$O#IIhX1Q7`2j>kQRxl4c;T(z`us2xcQ7`J1UK zgWw*>@MrVG!=##wUHN%u*+0eCwRiuut?;I%<^M^U%8^n65~Y~KDQ)1-gk<3XOboib z!6CRKTw3G1j+9oZrMMAgZ-?{h?aH)K-s2`guOebv*$=ALr&nthd@=nU1oD}x^NTXZ zARN?#5%pFvID4o@L({&zuR}gdxC>wsn{MsI*TW8vxZY^djKzRp3^}xKN`@xiRX;_s zvy0A9@z=%nNQCE$c%!Sgnt!r5#BLoRh5iXSLj-qO7E?{FwqIshskvYoS>KdgRUMNR zBq*IC@W&WqNkXR%@9Moqdu)wihZ#`*`~U$c3jeQti8toDJ_}#jUd{#Agl)Z{7p)^M zgLcDb#1jv#H~KCNGNTuZ7AwWjA^rP$?aK=pjMZ6b=FLaLjtMs_-;b+(IBfR@fRoRU zm{T+&nV?Y~pDNEr8atn4`qCG^K4D93aM4nK*wLrPj%l4opW%ai$Hn_muF2iU}GMN4`wf9yU{c$tTemT<5(i~`!A4zO;Noy@gRy{;eR0<$`GFH;iCbg6{ zR%nrC1pUwu#3yQyF3?B)dLGpZJB|74Q^<{X&X9p-F?Salyu9{)3uEo0R4F3zeNj}+ zCAZe$p}9d;-wd4_q(|a5+y!B&9MOaACCwu}6C|tiXqB80(VdSN#Oj`Z1M<7~-2~`# z`7*HEALh9>5PA#gL{WuIN&gFQRApWPN0jjNxcncv>+cH-%3mDG?4BJx-{a>lDqcxv{ml5=g&^*bdS*TbnnAURmXW~Z zjymJ6%f>Hb3mYP!bNZD+t>H%7v%nxEDI|*wA^)ar1n9Gr@x}69?&|7k?FnjL(#5Sz zmALvsW1gPZ{$W-&7HNX*dkMwLwHW8lpQ}IYN~%W<&pNNy*1+rh{PoTR#w}yGKXPkL z5a_YH>_=#4f{QtI@5+ec*9KhUGK;_{PJKXC!wZnZ6JWkZgss~n%5By8wTcdV?&!|C zZod7HYP~VKmmoQ|={3prRSnEUC6bq)B3j9m`)bW($JB!WMJnpz8o7Ffso%|1=thi( zGP%!|G)*aoTbfY`c&*$6Go&|xZt-Ev_;=qUMfmg8^fpVeyys-IDi=)Fx_4{Sk@9R? zBc$SE@26YzH?|(Y13t0zR2MEk8kvmp`e$$EA_^#vE3%_RcK8e;Rtny42$0lFQLh$( zYg{$^*+9GfWjJ>=VDyio(L(gI3rC}wDkoAEB7y8|)k2&LINwSAo`$)=nLK_`WoPP1 zcA4$xgLl#9=!im-={&EiKzZH%4`FW^6=xen2?j!tKycUKE{(gp1_*A!T^nmO!JXg^ z3GVJ5+?_@PK^xb`ZTa@>oSE63WPkSQ`t?3_s&3t?y5);o?(K{$f;qpj(MsrCvPq)L z1P*dGTpdR66#8^Osx+_IKw%}EJW-%w}&dxL#$h=oSJ=r zA!lR%9^txmh3~tu6f+`ZO4#$)BZr%~88r7o}m-{|ascQdl&=&x{QRB~g%A6?ObspN=zC71; zfUAssPYr--MX zB5n!|U#=A5YeywHf|Z2nnLWR7 z!vi=kh(V5wyxSYgbJ;u7M3j8~lKD|hrpDIA#ew*BGt8Xs@s77$kN9O#=^fk6fUMk6 z3J3j!sM1I0Qe_$6{a*&Mj|;zJI(~dEMX=0x&crORkvY2#l+o~TuAg9*kzyJE2}96>-Shdu@g1X64;~8~v5c{wL2bEOjG_d5Hz|)yQk4tsm7|tU|DA1h1E+v+UEuhk zPe_Nly*rg3Xm;@^*1Y{H38k(Q%T`9Uds3~_N|;_T#L)~95fl&40!p%AcuvX)mBEJV z)Xf<|#bE{Z2LB+|j$73DD%gYWK8h2n#2THe+-6 zcT2s3Yi;z7WNrtnXcSGd?eZiTud&+t!4c$RSM)%C^kLrK*r`5%^LK3rb&4!hAM(JB z3`s!3FuT4g6(tyWB4|_~n?S>(maIr66L-Uod;<}tjH8aF4_27Rk7LR-joP2<9J14n zHU3mat}_wLiE>BBgT%P5EqcHN9Mgu`o8S#wOiO?Yn zE?;kp>$Z%gIlJlZr+DS9eMr`{(=sb(Nc-@Y zOKKS<$+7}8(!NS`FzpDy9LtYMn}>HDNaeE<^(BXr5r~Y2aQH3dXLFn*)1mK!PM88? zy;=OOKu}1GAUYWC)4VF2!^&)<((u*Mr-+}kNv#o_H6khas=}5%O!f!EEmz&P%z09o z4cKjrXv9TVVJU_yGZ}DkB*3%sruV3?rJ8R%s~h4K!n`$P|5Fl1+)!i<;!1r9AhfY^ zOlL#2wxBP^AEkDHz!atkL$p1B&SvjUb{~UWfC3lKBa+{a^nKxfEC%=i=Lzcu;k`dMn2u0X^`*vYe z<%173n$iC6!Up2z@6j9q#I!RclBbJ18pmwkGeyw}mf-L&OwjSkS;g&80x12Er>D*2 zF~d+?qkVFfQ1>!9qc1}hdk$(V}SyDXvqtp><}+mfyAY<{i*%wvIht z>Dcu#m4wco>E-b>rDTP#9}(W>uefK%9qt5eaR58l`F3q8vOW09(oD0sT6LX4`gnN5 z^S?53tr+V@eQO$<=3f z)Fb!4y4Sdbe?awW!Ayr(9ttS+ZGYdEIkicvnbcm5d z%&da$>q`IbH8NU}pifRFLgwUK;k?Ul1|(xLT*oSUu%m{aEYexmGwNO`zllGUYSYg5 z>SG22!*Q4+*ZgWOv40&#at-Ldn}LK2PM%zfWkZBr88JH)=D9`|(+ri#N8@I|>$qJS zx$NehKG_tUibYJJM|S;(AM2mn?an@YAUPy6jq8XtXv4SMAO$&@J4LY=)Rp(#9MG?s zXf@Ox)&2`n3;m}Gd&5bTrSLCw?il;Vl^$zMk@{hILv%B~3Q13OeWp4db{AE@N+GVd z))s5EoHB+1jDRtw;cC%NTN2%9&hUpRmoZIVHupTmGZMeP}dB#KlNpKX(v;MruOFKv^=SO__6`=;45 zbnFvithf%aWQ63bemQ&l_0kui7;@EBCvA!h$MWZEGz}+WJ3w3SaI*n7^1_}DJs}%} z`e~v6CNnC4#l6+2C)=A(@}!EiyutR!@Pq3>_oD2eWmeUrKTqN-(7z#Qy)fSpoJDcPo&fXtHbpPH z>t~mDOB?7_^wy)vgU16Q%R{G@sACw4ez0X`>BZh<(f^$r2y)0znkg%|h*HF2=8|WR zU4R4K_ojBvh70nBR6I#o@HO7H=x+m=p_1JWe8(b0?j8T~tET@5q^^EWxA=c0xl;m| zu+PLCKW*mXGWyLEnnkB_3l*FeX4Y$qdp9p~(qmX_Q@HdM5hcVr=*)g$)+q(iEc1$I z>nds#Xc$feN@vd(Mzxk3zm36?>I?tKxu~k0$ba1T5Z^Wt>mreEBnuts;?MJ5picoB zcQfCWGz#yn$^0>n;D5VH3RiijCbasoCvMP0k!$F(RPmx3@tZw*=3Z}UrDn?bo*AMI z;pl3?xS9Aq)`ehdZCfp3?l(rh6tTqM9FN}0X@DWZ=RM9F!B$#V^@Z9x`r5?FgJE_P z9VZ)S1|3jgN;y00idGEKEQg6s)}guMX3-B<0j_n;ETKHoyYUMJjD^Fa_??@X`SjaX z$Q8t1Ooo})t-x++E>{pDk()@8=XWuy}lW5(i!E(Pl^SSk_!WP=*++3h~HjpiqK zYaN`Xz|W_A*N{xt(sk;FX2|i7eNO^>m5}dVp{!%&#MY0{J;wY3ARkY$O3!_iMoeEx zf;Xa@-~RUNT7J=%dM3q$h)~Ii8vkz|@)_V7kZfKEXQ=O;R`r4YRY%@jox!l|92Upy za47pHgLDjEAMI;jm$NcOL97+t-p$W7vc=!N=js;AYA|?oXriCWe>270KK%>^p{J2< zKF)-EGHRPj(C7!^S+ZywI7_CpN4?jYtYny@gpZ!eU*czz<{nV~V4BsT*U4RkvrH(n zteftJGxvxYI3Rq+$Yl=B1Lj`;^ESfTf4335bAC=#{r`BOEEHHPm3za|irgkoW1=h8 zLugj1nzkC4zk}b1_BxyS0~wx=>0ra+S(B};kQb-{utvRD)5Q}CdzRvF?9-(+2oHnT zn5A_Kv&LW6v`F0gtT`k0$w#y0h&#tE?9UOmqXFE<&%_&TDppLC7rDwU#223fZAV6Z z005W?fw^UNY|%z&7k)-!I)M0r$`IP@nOPP5BKH+vI=qZE9)>7Eklaf=6HPGiO=;E> zHE^bp8s&abX)*8S>t_Wzd1*Yc;!5S&k2}dTJoeATkjG{d-^GhLx~)tGHSr_)Uf-;S zRn_lAn;2he=>xW?ytL*=d__v`3@`Yf9{_6B?W~h= z1D`sHO3+OX8M82nk8-lg@|~gGa8IWzSxS0pgR;H{bkCZVe=7Q6)9g>C>(BLOMR|>u zEu%4W`{$5kEZwC*^j?}Gx)N)}0at%J!!~Eiv!_XcsSHju=jZ+1bHD^`QhltjRDPE~ z81*m$31rx$)_WWor@g~PD0rzH<4IFX>1}4HEq#(Y>EK$k{`T7YJlsh+CT1(Z(TzL! z?BqO;Bz0X-p)an(9mD1uK~g@Wo1`O>MWb*2bZFgZd4H zyvc7bcAfNDOdWC`D5eo&YTgP_O)mx;>R1O<1CSC^anfBfnC|(f5<+Qt4-32%tlK?^ zCx$%~StBv;2p7yvZ9A?}`ou%pd+ZmeoLG}w2tY^kp|!;BBMZQY#}u~~tnIc4o2OF* zbHx$uc;Q2C!aM)d(1mIaTz-pE;$(kJreJF zm8|f7C@0xNJ1=Gy%p6af%(?%gGr0O4*3#Dx9}hv-ZnHY@SU!|NX?9mlEc1Z*D7iq* zH}R!0>l$0xwQ=-{x<4|z;}KRN6Mc((QU!9X#&c(QXY~SlH`;_&SdF2fWjvfIDSg;3 z=)T{5h>bv1N3k+L7&G{(f}xK#7IWhG$Zcl7S2YArVe$&o)m$&l5YKvNIr?7&fl<(_ zr}<-?{kH!X{Ca_hmCDX5=cmj#G~!a*#Gs|OiXpd1=8Lzm67!Kb)0pnHKU8KK41AO7 z=7FD@|8gC)dL7!yBN+qr$)hs|P zqWCJF&f~7b;=H#tqw00f+*UqYxvB|D`dyefj##5%znqc*$<0rhuUahU|71v`qE?CR z=n&)&ha{W)^-mYEf|2EIl686ubBv`e%@0FVcks;v{lO(i>=kEg1EZj_eW!sqYa9aW zQ0k@beij_w1Z^$Pd+sggKE}Xh#TFdan_MF4j82nGlo;T7AvYRmMVP>tuq|>at}Xc< zdhE*^EH*^DRp71Xkly>S9C505ATV^kp#h-xjn|ulm7IyoJt}4GYxgrJxskggaZ}k& z;a7as7OJ|8`@Lt7qTh9I-^ZHIW;oGf7)u4hu?Ux|3Rj-rS%taZ)hHOT_P(rg*uh;@d$pnq##{@!$;_`4lWBNh+47iUt=bIfY&ncr5|hRH_yLDRtynEpEv2^m$|)PRX_DsBJB}%cij!- zri77bAh%6ciEVjVP6O!G8Aog1Sgw?d?P7Zu!>Cv!Zs&1aP@=YUzrBKL-D+oL&e>)2 zJv&nz;X^viOk(XcLv4dGTo)M+7R>E#+Yr*j5dBxF-0?(1HzNvJsIXGJmcb4OZQmqS zq?hOHVpIMkh;D9p9&X^k4FBsMMgHz(`mbpG>0g-Un&pQRvmsoTwogq>VR~VHzV+s7 zux+B|21dDqLwNDKxjGBUfG+ncPkZ47XMaD&v%9;e+V5#=x9`Hp)?WlCT7++W*i&>- zM=l-&(RO1>vvbJY{+NR*tByPDS1O$n#oUEoTEcOJy?ykAyi6!4QGy9WHQr zF%FSh6~It_-_ST1nP9GD$MtY*UcoF(XmZ^n)g3m5P>cHEVh;{w@bo$qMj{W?-$>vTjCdn~YB-ZefDb8*DCxs?5Gv(e+r1m6rp z-kW~iLxoNTfOy81t9?t5w0**nRj?WP)<%j;bSODMT9TB}FB4rtWJx9BuV z1aNy_%)BgOqTD#I?mmx$5QR^K*4;B>(eoC`Mm2oz{Q_UCVs_K$oc zN_pmnDEg-i7{g}9Ha>=moSr(o&CV&d%2a=5bT{!~L1|o9&I8GEn|;VWA-J?YY;%T> zT+ut9W;*h*(!eSZ&Iry+u!qI!YyMB}&fCO}6|wIqS-rDTqz6Jv2j5_p=5)9dI6YL0}&qxK3HnAfY*>@#yE*+}DGM-_$jmbEf{BzB0cl{!hJ0A>6v zyA3SQ24pH>o>gBCpInxDL(JTZAd~zi91~W(PCRD_8{W{#EHy0uX^v3;y&qmj4ZU6^;IdIYrSKUqe z)3c+O#qU<;oJR@{m^01Ncym2>1S(9?H4HeNdkm?Xs%xbM57tL=Aj_Obv-TkM1yxH& zZnPH%fuDp|0QpUy0V7ggpaI;(B8t2>TW*xMpgM+hNzPm{iNKlVMK+SFK*g zS>MWe!AKoyM^ek;+x965R*Sqx!ny%|NpK86OF8JcTmMD|-Z*}JfAif%6klsF^Ua2Q zwq>WtOr|BRY={_7h;6fZIZ5pvC?3s7$O(Y@_U_A&*r-tIPu=7TCHAFj>jqmLD5h4n zDqT-hr*;V4c8|qL@*AMY@Cyx(1XQH8yLS38&zF&$BW zt}7|n;Z$m5TL;eVUWH_Vx+ZW@UoqHVrMnUFVJN@+uRqT6Fxb95%TS*9{2%`Oe=NI5 zU@e0dPHTp!td1!V9_-XMH4S8W#_DIJ(9a(BQaWmE}!~ zr$FxsMz|-W_LyM-vN`w$7FJ7W*qX8chq&va2$7 zRk-EM9)*dUYTmmwN&W1H5suq}gRRldVJDrMH2}}#b449-x1rf=eyCKc&nE|aY*t3q z55^pftLc81M@%m~2w5=AmhdsU2>A0D7JG$Cl`cLZeJPFEAkqsG*7V0)R(d^7c6jHD zgOG2+j@6@Nu=UDu7x|Ih-ziG0r|m=f{Ei7-9~)vKgkU{-E+v6F7=dyX2)1#zJ8OVi z(Id5-ow5k@`tp=-A_|hM8L5{A@7QMjg*O!R&hOMmrZ6{h<=iS{D3$%GXCEmNZH%)T zJX`X=)8QF1R~}xZ>tw9|mVwa-yiR_k(1L>GhB6jQ28Lcvs8zDkyMO61Q+%4|i{W&eShy_77odl?75slvyf>=;-cG=)jB=1~>!+qkva`cwBid zjE1nuVUB(+Q3wQqaz5!RT($S%iCV6T4&B&DF;A%9Xn_(^38yNLDB2D+gSDjHXERNl~wb z(}o-J;b33*+Au~8oTKMRztB{qs&8mdE})q}_%+qeu1&IV?y9igf?C!9-gmQgB{>{n z1S)owW%jZt7G3Gg-81yq=Wz_?P|o&?ur}Uc-Sl@%3Q`>3tQjB^P5$V+;amr$z0WBf z@#$sZnb!!Ob&dfa#2Ma(L{KA6%$t`uunI?l+0ZQogm>*TxM(N2Fz!;!bnuoeW}_@` z7~4Qzt0J4>g%9RHj+&1qpUL>+63PZ)u9{E2Ab}@Ue?Cs__=`{Xo+P=1B_KHV#`2Qn zKN2d1d)J1CJ28~DhH3O~n~c0&N^5`H7{j;qEG>Gt{~#BW-5#fE5ObO7UMpF>xRZop z1a5UCH!(s_;~-32}voBgk$;(w1DS^vcifwxCz ze~%mfLU8GS7M}Dl(D~3elVP#F83!Kj!pQQgq1JMDA-(i*<>Qhk0jjtNio7)!$$opI zFae9d@H}blg&&6t+LnO1Kft|C{cTg*067MP8+Sx~L$E}Jei z1@-}q0rQgh7DCKDjf3`*BHA9z-5nIk$bim8Bol=6Z zP3`Z9B299xfhQJr+3z~?!)_Q9?e(6<0C0|rxp}bfS}HwkL(jq2(pNtT%k&oX&FjQa z*C_PK@{i+Q2}83+<=tkPS?5-VJku6g6M3Y&_SCgrlRW$x>ta<)k=Z5(XAIPEDbq+= z%tpN%KC$nO=~c$qUMCeQVuh2ewl&3qivk_~%U3$?=fgpj1KS2G4y~oh=kE4cr5uiS zKl6+lu76by+Gl_Y3$MuKlGu86xiJSV^RIE);l3F!F)-Xl35K((68U%bC9ltJBHL@T z=O6%=JQ5>*C(#d{1j(gLZJl@&rdxyn$J3y0I?_jk)su&v6}tGc7}wJfQu~Y}9>2w} z($DTw3!^o`|L0Wl>L1-IQr)k&>fU!H5dFXM%>Q(rM|nif=_*?XlQqM&`;!d!`AZou zpNv$lC-&S4ieJX{lN43tFNCiuQ5+8HgW@^AEEhe9RW-LLPe>*EdE=Xhi2UV}YgH!O zxp?7Nr6OWmr|MwW5>fW6)>D~azwFJg7kl_Cz5f8Jw!?Vuc-tgz4h~9H>N_HxFMFjv z=dHRw0VlY^{SxF%Y-k{_>RCl8yqcRnQX`)turLsR(f?xJkB(V{%UzhPmtsL7D6Z!n z_FNu|3z+*npnf%xXOFb~6NK=AO?rY<6AaC1mGaZ{ewad|I@67UqinkxQ}m>tG8a8>L&RQ=d#g6OE8sn$_Arp=@}+a2gAdHWcqn9OrhjCUI+M<1 zQ=qByhZEVjn2+~*a%vFbbh`~M<5F4x^oZDp?45`?KQ&!{kWwf+$a5^RxHg_NhF&8B>Y&YQ zLl~Rsz*;)7Wr7A;10Qz~MivcfBAx_|Sfb$Ie{0Ma$4yKok$2{ga^0VGe58I+XopWV z9q1uP4e;>-e=pXV1?KO4{gY5=K;TLZ9fETlIP>ZLXaxmXQ(vAwv~_V6@ecK}a# z&BT5J@H!-7g-T)LDO+oH4YKZHo|*94v?J6VuaS~6)Nit$D|6TgEl8*RJTZFrCNv(G zCZk!6*{vj*_q@D(KyUZ~Sx%ql_d0TNu&Z_`+JakRN_tG)@vK!Ui#$8)egS!w8fs{1 z6^h(wjrEZD56_Lq@P%BN*);Vp^u9z=IV-`ffK(ZO?yag2?j@lF7Y5IG)RJ#jf z&022i0wgl{QFc9-o7Ne9@rv!#%E&Or`yW&iR+GBVWctQ0) z%w^y}GAi?ZVJ+H5dz)6dx;s6jXjaQ&zhmBR8bFO{Sv(NQ$NYD1^?eie@F)JqT(Ee2R2RmZ!klnBq|k{w5s3MO@6zB=sMDg!=visq}LA0 zk(;hf$qmzE`w)C{!7&2%c~%ad$>!ALHj+=&%Xv=Ouh<0AKq9xmg3yK5to`wQThK)2 z`X(@{*G*79PCxAJHKhXt!!X5g*Yo#Pn|5(Fqo{+KK6#vX<{Ho*h__B>Qan*P893h; zfGvgGcCkZByAN0&$g5t|-oWp&=BWUMTyuQ2R2Pgfr{t6&KH9n?Z`v0~?jl;P73DcJ z=>rOh%Q!qu-F%}OxI1D1-Fcw+!b@iP^jK_%;oAD5rsWRuKBSJ)L(f5(FTVmIRxxNi z)RSuO1*{2Zu}#_7(GKGGz*oX|@5>=VMs%T+6>IRh-fw zUgn7S$80$sBuJ8_!VBNGPj@1oHY*7h)f+VWpwK1Er=^ zGRg(ZY23qHg2exa7636B7jsG0Qt;`0M7~r%FCLzd>1%I8TsrDXRHC4T5qP}@!AZM` zIrjXUC*J3c~Nmx}oPkPkaMLCiAoB`bLLvK}BHGxh4eMe+*e4)XOfE?Dk4dGBn4f1q`FE?TzN9cYa^!Ho1LY z#fSDqPNhs}c84y20b;S1ojxp~$JiY!R=&>+cZ7VHYA-r#-WV;lqw@(&(sykZq!(|m zvFqT>n_y3i&ZV0C-abLRuzU?8pB>qA4uC=nLV;IYsX_}hRsBo%ZQ4`6SX5+JS}UJQ z#h*S=y0a!XM;$tbF|j}wgJRYR%OH-WytkY0l#F7C{a1F@J?|eXU#=+zX7~>&yl#vu zcYpWt|M=Sj`+37D{&+cNt--VUJ7Qi#%#15sAofz{4Js3>mA{xrhAR^r(-pejs+QnX zv3^r?7?DW7iRXtutlFsfGY-Mqk!A^_T{q59$Xme(P5@&M6v*7yMzc;$P*syh%z$Yf z`#Da3(TbSRN!~fC0hSpi!wzl_k(xn`xU(IJOo6F(Jg(M;u;|gAa=u!T0fEGJ6kltr z5_B610$0y5iDBG?8249!EW(i*ol*4jPqnSfb>@@ed9g&rc#WrFkxa9dI{y#{x{WbG z76Hrm4V*i*Oah$sdA=hLQJpSkH1keLWgVo4ZIu-Zi^6*6(K?%TJk7KdLfj9{+3V6@ zOqL%YjZd-jyPc$b^zQzSs5`Ovl74_(qtS-7Q%GZL2BJr0C%x~nwbM?fpN}|nGQMkg z3Y*Hr7aH{z=qvsCC%wFmzk7b?>w=J`=YxxqKnrt`j;(Ra9)2S&BVW@Z-%;U8EB`X* z$fV~t@(r6RR?@EyokAId&X3yM%io%;ks6 zve?QxQZ2|yeKd#Zx(C8O!xAmCgYZ2xf47mPuQq^)SGPc=SYI0!w|e!i^@;gy{5j#)Obk4E2Oa(CTHuBk^|>I>7( z!%ZVmE?21;4(H%1$+LvYmRV_Zfq(8j;2X=#H1xMiRVB82WySoe)Z1FQbUfyOM)|7< z&es8#lunUMGdx7U9@6HX3H06jk-H*Dd%7dt$O|G@Iz&tv7YJNUuUuunlRT?BpSr83 zl*?&VL%d>e-^p<-*C!kA3~i<=~o!cqWq z?mN}}GrPVod8MmoKvT?`NRKe~DA${XRRgM1Kpw~y$6CRm{-!YuWK9~;EA;95OEte5 zE%1IEkMt5b?sG35&LipAC9o#}`pW0SR^|Twikk+n9{{)Nw)JQV!=&gP+^^4&wWfb|+otP#aYLR22n{rMXYFSD$ss4g7uY$?Hn zH85si-~%1QK`cbsKRN4aJBd%~to+o(rZUug^n~8UNKwS@=0d4FW5hVk+|GWG_C{JT zzormAu)(buVD-(5NkppS-dhw4u9&wU0|pv$2MN1s_eb{i%?=&!M%U6c{p4$e@Ec)! zR<&@+Ag8SoIZ`>PhBeB4^P1qc{^L<`MaBV>PM5E6DQ(ixMHhx_Q6^f{S0pIe?PfFQ-)&-J-$<4Tg`?!of7A@;oz&Y?r-|2$k{XEEAz4Swq^gwL zc~2Q;@as0cc4!z5R~ssKG$Z;|Nx(S{`KY-A$ zJhIT72YaZPC)yqDnkZSH;FZ)OWylEAjE}{4s*nOA>pY5nu{Camq~NqMTc)xJ3?XK7 zQ>wJeIB5v&{Ca8W&m!LnPFh}S^U_i*F|ZDGzV!n2r4t<){a}fYsnAn`7666aOg9GL zJYXhiO=;k6LT{I8Q@-e8t3%#ig7kaH@ZB8g2R_?KWM7;92h3pdb$TNe;nTRZb<0|Pfi9ukCdpLTD9Id|(NWOh|c_JMI)c6G?G@Ptp z`vH-;yzC_9M#6YE4{YkmfpkjTvnf{%$eg&Os7mU8wR8Nwy$jn6p= zH;>r{&CG90#7kd6iR_n^|Ej9Jt?w+`ll+@cM`B}nYV+OUxI%*bh<=bzm0rBUpHk*A$NQ^>azK1(3i{TP1SeM7^8uL2jij0i*19lUHBe1{!cNp9gx_Q ziEsP!Pi$djrIW2(NVXi~xHt`GTMVibIHhYuaF)!>IIU~uQ|Q#x{ujaPZPiQrcv+(3 z=h80bmAo}{MaR1z?bc4CuNp!RYo5Q?6ha~PM!|Gt*>ub$ot1zat<^&acTFH=g{HeH zsAK-LW=lcM^s@g<(*Y-)XQuKx-F*{ythwAMDB@Ude&`B`$|!N5D?n=UQ?y*}=7C2~ z>k_r8>>NCw6wTh8)lxw|5(qJo)?e%Ej9b?McUXKF9P;jsGw*arnM|3l{DZVU0sg+T z3{I^5-dj)NB`Kkp{YXJ<dU*yLrL00FI06S_5owz&6ZuuCE_=@_%Yi+z#yGp@O9~8|DzGQx7=!h!n zRBr%xa!bG;a9Xv(M5^E{ZRq=SKyv-gA`Mh1x%U~n#q+RT*8Qq++0XVE^1FTb@`>iY z2tw6>Byu515u@`&Oga_k1iAM4LW`>+Qz=?57W|w+R@4LR zL5}vZ)FP2UsNyC|U1{1z<%UNv^G7~t(1imJ28{Mf!Mbn4&52tM1x++c4keq zmN&Qdv2y{`otJ6&>%Vk&S)a@s*fxQlPZzqL`=EhVX#0i^(fI|RVOhmVc`{L{v7hMu zNBqK-Umfln1^0NTnRVZ<q3WQ4ODw~gIM8cz|%S9~! znhB7ECEZ`Cd^e^?bHg9UXj*RDS!*C9^h}2c<$9#MYOg>&o~vWN*X8x`${@2-4T8Bz z$_63?e#R09u)K|KgDh`SHA=>U+TR7h{ZXDYZam4Tta zi#Uz8)eEdx{wtG~JxBF^N_C7&6*0N6N=LtJmYsEb(`~T&pt+Y_NjuV~k@S#u;?A!} zwX4+(W3wJ9K~nm`rC%;b^}XM2M*@y!_)|Nsj+oI)X*dh2)E?VT7jF1_=Zx~!l`WKH zf9w36MKTOk-Qy&kBIuqtpPg0)V%-SG&@n?f*I&TeSBzVH#8lB2KxJUr-vHgK%{z>* zoLpg(5BE~lHYOT$X$vZf;!b2&w&<+^<=lc4U}#FeaNBNPCmT7>ak(MqVsiLVW6@BS zVta*lovOxx$?`UTN4O!?oe!fg<{tSBgj`_gs;`iY3!SP*N{)gNemEN*R!($WS4s_y z>~5=VE=E zEcS=w&+IC(TCGXXOET2z$oHNJ{(IOt=8zfS4@c^HHXP&9+l@qLO2k@T%S;pN5f(-3 zLtbhS4faBu#zcL5rG=>vjwSxw$K$Xq3%E{N*bZB=bz3jZpoiMa*kBjO)#~8~1ResC zCxzNB$In+6k9rRG7l@IDYAexqEJ~vojAzRJwx#caetmJTg7M5|b0iR&>|27&*4XDR z_;cJ5Pu8Y*R=$$EUnl#&Gv=tPu(GPK)^LYi@{0@0LGSdHSDVGtE)#_Ha^dfbJANV^ z!f2V{D=pwVuBtG9R~QymszY7v@xFHw{H=gtYq6)R#x5*F;a8ZM452rgCF{7TL*Q$< zdxRILG<{QiILcKD(nuH9FJd!}wX2qR#@wL5y*B>Aw#fVvP5v~Legb{p?_=#!V!qMa zz*Gh8*Ng#06CAW=k5q?~*=%YLUKxdS4skF8dcaKkEO2LsDh3?LYi#AF&*c zE8-ik+jsKV924t#6j(4t#D;l-v9;7egfo;PDT!CkI0@!A+o|gNV$*_^E5So#5tshy z%lDU}2q z6>8x}U(cpSOWSLh>e0y$1<4?zJq0jVCv~ceqt3gDIcX>qf4pr#BX8vnMt&z!CT2*1 zxl3Ma_@ot>q^Kfxp0U7=fFYxL8I(Pf`ptNSt%5AbROL%fHXsb6rtk|vlPa{PdDVF- zZy0mL`CQBILjH9Ntign{fRy0dX|(7%r)k|<4x4@_?!MN|d0LU(edi*<59GLO;Xr|m zPHifgM@kOo`Y6Lu6skIFUtw`-<>ErldyVS2=sOzy0(a!6R`z=x3Z%kluylBFPCftjO z$D|2K%%gNS%xT3@LTSxqQt_^8R)wDR2VnF9sO}oZnrkv`chJGbQj(OvM9y+> zTsO5VC5G4aftMBqc`KS+A&jR&q+jm~P|c6`4}Qfsr-Kf(E`$JU=_hl|)VQum?jN}k zTM_Y3ACg3WABHg}s3X=$H0{puV*0!b?U9q-C@+(Y?Tks;GfI~87RmdTd5)(8y`{u9sl%N~2si3diZhr7P=(}tLm z89t>2O`$oD&PP_F8@NNuZV78>Vri(1a80+d(7ip>M_G0PSax2buSzP599b}TP8|dz zzlhgqn{=o7M44=@?mW7|Vx>~~;7(Q{Manw=oLVoWYnz6(xs&QvC(`D-E}Wk$4N;evhOob2JV#l zv~Pv2C38meP0Py2-y33q|254JTF_bk(KPcA{kX5S>3~ziFzho-pb&r?#0Vzzb)M@J zNru}Oj30NC-ao)MSLjBO|0A}ii{v0-$fs4PEjcQB@tlnHivy-b%3Xb(O56)|2r5@P z$usGpI(^9)ZxUp(U+k5gpu@=DeDiaG(4;g!I@kw;Vq*0$^?d+9n_W3nKG4On!|ujRddP(rKaJ!*46+MqJoG}o+i z#`LE*YU02&>!$L`uuTj1ahJ{VDhCqr+r5%kw#Z<;2_XT~E}O_Z4{`S9!7vHPFmivY z8@$=?D+A*F>|@eFNX_$jJSxA+5!J}UEM3LY)Kn|rz_N(^bX9dY! zf_T1*dzKbhZ28m4kXyR&0ZSz23WV2XHfPt4gTS`qpbBNrg|FxZ`0?o}u#vOLPN=L) znZwJVs!@>bep5|qW&ER}JksH-K;6PQUsm$o0ai)aWwg$XncT{|b?g|RA(2x>jv~%| z>R{?5@)Dhh`5CC2bYF8J+Fdpiyw-;Y zz_iF=>p3TuzU!MXYAGj;(z;iqm)AU%- z^HA{Kth*^kkWUJ^Rv#MJjsNwW<1hm`u0`-Y_i7C`j7q|g(g*7_(`|ZNe=2m%S(H!o zA6vWMks0W<$PMkaZY)y|Xn*^@BkQN39Bs~dXh(+gy|sOAPGcebXL}Q^(*YR@bRZnq18u0&C2t+<@VT(BS`o+{R~u*!_h?6hZNNa)-g4_K&z z(XTMl+;t!DZ(PqwdaibLk2sk~OwV>jTzz&#T-)Jb^tQ@7#;QxJKjVh_CH$z+MS}a; z#xSXp?OD312~U{fsBM{`T(px8Ar5@((OwEUovTO5BMtS7(o6RBPqr@*5;%_(#rsJi zW2H;>WmVvqiatq6s~GPKp7Vuk!buUssEyOoBO~K6l@`aMadS^O4VR zN&*v3H>88gEsyWlSe2xi)!hSh8S_{*SgfQK1(LX&<$q58ji_dWCHwH2heVcfoQ3{w z(?tx+c>X>&$*-@Hu#O_~S3>|O_!U;^JE=kAKPU5BhuWVX;Pz-kl>B=t&Qk{+YaeH* zWDOV#6k1wC+$%_*wc??ql*JpflCOi>uMIpuuU#wlCtz$IUbtbJEN;WJO(kG98Pmfg zzqTZa5*+4%x)o*MP9oK*SSuXuk|{o6qlAm5&~NXl+jX4e90or8Sz30@JvGuyI$hi} z9}d(N3PtDh@^h0M^uo@05=GqQpQrjg>vOK2Ig{nyNA%vr^6|(v>Ky=(zupk@oxx{! zxwv5=O^S7iGxO45(If4BnR)OjCX^)52YO$bvP_iA>{10iYC3K(Fg^b6{d(x~Q)&Of z@wO$8>|WE&FVw70G~v(NyEf`}ChfwEx>w8{*X#EL&WOn%v`x(I-`>7xWxM9*>9*8m zXj|DH>qrzLwhM8*h4v$GN4mr<2i=f&m>sBnC8NT5P#yB-@+@v?ug`egd8M_}DeK~) zLdMpYd`&SAI$`D{t~M2ica2@0;HIacIGC&_&%WsO)!kTgdE>k6F+|FT znt_h#_T)=`<3Pb0MM0wTlS_G_P?Cl{!V?Krpv`wnxLI9!JOS}<#h0ya(bJZR(bn>1 zi_tW+J%1z};{MK14@$fa_QZN9>HouqHB2<&@{eBl8(i9_DOPrx$L`dzrV10Z3`Vou z+8R$Cwna`IbUXVXwRWgZxH(0PeJ{;VQvb)#+EW3cj-2acphBRT?x!)&QLO3dh#Zh|ZxFW0XOTMQ%)3wS+) zy28Zr=G|1@+j3HZyaI|Z%BnDFcl;3Jjtm?A$FXVN=+1-+5dQ!o>GLBu0jJlK>r@nA}7uhN$d5Qo=aprbbN#8Uvf~u)yX|Jj!w~8i?_VH7cgcXpVz5VGQ zZ_S#fcV*t^Jszk2Die(@JSr<9;2VhoO&n6&3wd7Sxaq3oI^B2 zy0HJmk*g7yX)fa?u6jFK^G^mxWnRl$*sDN{B_?? z)%P&xo72zPAcEdkY{c>B$5P@yKt|?;}P#Bl3BJIkG063r`=ElOR(x?SDJM= z$2p}lpMxJbi&7FMDg`m<)C>ptW5)8&oQ5_+QSAbGgAMK_K=qg|ndbU>Ft}E!bEE+^3Vl5PfaJubaszRP+%Hz8o~@xw zSn(tep{6qH6F7qZTu9uN*X_KYt^|D6x#$;B9~-x5M1<24H(kYRG)6Mh;5fHFDyGE= z;YAA;tqL7}j5^;yw_mLb6>kRp;*TZ=(G&qbeXD6r-eIplk@g(A=?EhR3L0zH*Zyfd zzWKHO!B%s}7eCZtSG>dyq*xRLJMDV*?n4k!?cm>sHae_U_U$Jx&&q2F)G~i1_X+3Zre?kVFwXP+6INnw>tQ zQA(PfDnF|+_a%e@?cp@0A`W0(pWDe2@$rAuu=Ft0e|%>cAZ@P`C4!$}q%&peup!yz z!+A>mVfye8UNlljV9LN4HhGv+gfl_&k^L{k5sfRJlAQP;&Ug{$1i7ebUdjhft#9wQ zC=a4?uru_#l%SzXi_|GpTanEZJ8>UO<3`cNM2754WzV(W@1@48a4p(n(y?z_dcRPH{JJBry=r4Ean_mm)|yy_1^4P%nlO_dtJ5ka1XWI7bzr&L!bZ%0NjK$Zuf1 z#y03!h?T5KWF@sS%cgN4IamShT#A%Fx)$pm-HrZARD92;D_A1Ean(6@*12)~EAmUV z8AdK17d|tW+D8rF6}Qe@W5*VgA+FRe_{#Xx3!Nob_4K$eS9Z(K`0)<=VM;(4jLnxe z5=UT#$>f^6t69!3csIn28S!EIqEO3@qr9hZF_2R&YG1sx??E8wB1z-DXsU29U-*i@ z*{6;DQYj#+<1C#OrFx6)nkq>sMS_BObn9v`h`r68bbBEQR3}B)6ynNMoM^&_bQxKM zTqnuYT0P1vsOp%-1D2GTpW0EnQm$Ai;UEw0P?KuAyc{L?BRqL3C1D)hVwHnwbXU1r9x(Vi>?A?|2TeEB9OPa<)BOep@Lo;1 zlC-GjWRZACWX-V>#ZoV!UaWo^S!AV2_{)-vqbn83A~EG#MuhKZ^J0lAM5g2e7N_-r zk_$-;rcLfDmC@vXL<_){Jt5%|ESe1if5St9Rpv%wv0_ow+ybRAh+&}>dVzgk=yftR zwH60FO53GeX9oQwiY?gI6=CVF@Gd*<_pA&jG z#JszzPX=YR+~zZL)T6WSUrFnem^+R7vG#Qh?aKv$HPFmB?*{SEQKI=VnQgx3exk+h zKz4+%AmewuypqQT|4owB~fNI^^b;Y~NEVdRyP2=LleW_y>iDx3ZN0LD|pzd5qV~ zTLYAT%vr1Kw*Tu{$A=k4@*Hckn$nYs%z6giLN)|BCtyqATW$&!dWE%NQ5ZUB2O@#G z)e;C%;qcI`otIE{1!HO?8Shb)k;rN>WPma%A4if)CR}(f!!AYvgTLS`y*Ec8IQ#Gy zM-~M__im7M7a3Qv8Ks(-WK90ysbu#TDOb6Mh}5*|%bUxVd$A((3%UIRpV`Y6r?0Gp zeZPhVmv(w!f0G-0&S_*i(>GS~pfq|K9Zewx`66l&qwR5oD6U-z=Yd=-HA)4OD_Lx6 za#Bz8bzzi6hlfgC3PkUcZMe5}DMx4tGHk=O5*C~N>o1${*4z8q&7O&zTNA0C**fG? zBp8svP38orx?5amAKIh#_OHkWyVV;{5Xr7luTP5{5=gRl9OUlx;~nlPUE5Ia7a9;b zX)M@xBHaf%Dla+suEF|x;6K|*6=hY2?RdFkjm90*0;<-qcR1Hn8moX#1kdoy_q) zCSllw7F8amJiMaHkgqt-W!u!$t@MfGb@4)+TM7B&x@}XV%ERoi8wHW9yiMVRXXlcB zhR8Q4^ zpjI}uaPxN8o=G|s;i`p23I4qdI_tSc{Zet7-6u#BxNG9#NV6Fnr*3nvosF9FY*cv6 zInBqMMK!h?!z6W$@?TAry2jcfo$;CEtuZ8d)p0AG*+NA)WGtDNL}V*LL@G z?47~}J-7nl9CVKa4#`@M11hvd)V;wu2hu)=s^QdSVJAGLoc+HkoH)7FTr7L)*`%TggDunw%LV7$OH{Rfde6^Lb8}nVqLbs~x zaX81bwZn(9{NtXeS=NPx&aSo!ux^ua4T!sKf@9V@cS*V!0TXF&igfs-Qm6iKU^IIo zvlSR0L->T`&=}Kv<}?})+?iqqMeWV1OHSYd>&$*>uW%Ar{iv^`{+@#a#JmhhZ#1f+ zkk>BXz9eK2&?jstV%e0&^1ctS z{cV0}C4PZ!J)pCR3||$|0nsR2VZw2m_n_!;^7?$XfJJy$fnMiZA%3Y2tfdX@jPv$g z5G|)Oz@W?(co?;%7KmmG`HezV*AXA&fsp8=nTc9LAyl51suKl^+I-q`#8id4Qy1|1 zRfzfe!k&=$)j9o#df*c6N8apiLPfFD5NQa<9x8E0=ntOx(|UX0$CDpA>#A#bm3}wzys$qR=@ahk#Vab7)h*~Qs~(DW2Js6-_(b?=v!~>;M86(O(8cULVK|2aAK? z{^t}>c-^>?tnFot)`y%4r}gwp!@!ME00$C#(pvfWbv3R z0DskwzqH_Ip!y|9iLI$+TmeL$wQc1%?=>9qv_J8&0+h9t4_62R>=CZ`0fpcR-{4^> zS^i*$8Tv0;4Pp!5Pe!r42a>|9vAns>|N7HM$xrAh!6qc1#$KQn+=5|_jCVX;e~<3b zdYZ(^9>LkEX1^Y3FU5bY;2himv)3zTFG^UkX@b7KOe&J|OqrxcTq^7MapgA&$k~pu zUE$VhL=|;59oc5pPUyYb(&pA4AfT91nt|6X|@%kK;#3%MB7@ijv?`IhQE`)Lcxbis1g4});|X!h<>Amj!S zG0_FQ=;_cXCO+nnU5`AVrWmBtKsEZaX4EnDc-dxpF0Cw{$*p$&#Xj zXZUjE%K~llRTOAoGkRFSXQ|P2wbEMdBHgEP{LG~y|HzJUa=X2=Ji6R>CL00J0Wz*( zX>#@MCb0?)H5=`$2G}4D6U{{Ng)MktBz{k~wq3g7yD+K-;T)eKr&1HJ3{Sf0I7!X5 z9WR|W3La{mOfZdp#eFKwphN!#zd3bO)hdX|E3nP}RdzPOz&MpN@f|vUcOsU-*E@_s z;03=1jmY2Imd5q{i z4S7N@Q4BDKcjyX>NK6k^%SQY9=N^kv!t&?XO>t%?L1j$e~grdtZ1CzpzJ#~q0-Bz1F~WzY^k^+d}3(W|ls)94<9H>ZrEXzh4S?S)Nvh|(*QTHCumcx3{MGWZN zFEt&_Uq*YN+Fr3=aqc8dulh_>^D{obhb7JK@>I#{A3OmxMtl1lwQ@n9+T(m(j_i#l zR*LzWxJ-6ayXQ=+?%9~2RUk@=#L!80WuNWOYXf%o79N1W7mZ6}XJJNioNs?VR(-Ul z9Oa+%ndY52L~rJx%P|gg8X>EFS?x=nUfdS_4Ot!XA*k*asWbP*j>=O?BIO?n6*=D8 z?KDvhTRQWVcRKAQLFJiYo@CAURL3@=4TjhNT0z4=NhwY2%gqf_wxeHRW~XV7ds}-v zp8Nfhz~M)aY45&CbJR5s#i8h;taRx&fC1->Eu(9*Kh+Gqn^`H^ ziu_=!FFkqhdupMQ4Yg+Ct(LAqRqO+~jM3G_g~!>|pV!&@|Id7H2sx?p0yPC}IeWYs zdVcs1xRk|o^K42Aea${?u*13;0wiI}i$m&%o7$V7sp`J^aMLS{b z7^R>Kn{@u1rszeegvl;JgYtUnUuW7}D{A$5{%DcSTc$fW2+t<$`^^veky9%bzS;Ma z)Y-eQK&+Hverl+J*r1#^G7iWIx0xu1&wCxq8j9C1pLy?bmt--EtwiqjyJfL2buK^awV_6aU%beSZ@bJBfj2qCn*jR+*I zf5}8A%BYHawcKkoF8X1fzAxYpDT~v^&*A4MMt&y#5B&4LI@ve4Jyid3#vYbblSA6F zrhZ~qF?MoeWy8U1if^EHfp{pP0&c7NP^<=1Pj;E9aM7WT%^Puc%iY`+#S|}0%vEAt zgeD!_dZ0I@hi*8#$rc*gag@?L>Kn%Ow0%~5ryxB4j=`Fg8ENtt`5w^J_OL8`0&{~n zdyWesLR)u0>9m2mH+zB_UziLlI!9N5da}NVEat&O7)RQp5?QN3&z~)L99huaEx?Oj z=X~s2dSxpXkQBO`MX79F-8r*ZWhTcn#u}G?h7snkS#13|x~TcCiO|Z2jzwNX#w5&) z1<1NMf_t_FN16FEw}ww!1XJI!W9zi6XM!izcczeB_nzoo^qt#+Z=*%kVatnJA)on) zBi1d@yCd0)c^Ta^)imod5^sZ`#Gm(LMq$Of+G|r#H7G5qp%e5nGq!Ynn-0zPj+E;% z^SU(c5InnTYXxeJCODjSj4D6pV@w_7Gme$ z@w8XnvAge)K6Od>$>^D{XB^M(0+hzQ`R6)Q}r1{F|i4I}i1JxSwBC7YWhXGnq zZl)I|Dg|C1Z6VqUsdaXiD)RMd8|+&r>OA47h1Fr&>-Cd@XHSlQ_nBLl z;hO`Y4?wP4r&sE9y0)y36+S5!j-usI{R|1f!wKCp3t z`N(cU6lWNBaF?>y1RLle1@;bC&6|nP6*2sv)t6!bH^U3ib#-3yDkMFw#5p^oh+346 z%}samFyv09)N`x|5FD z%{q_6l+nqY&C>=FWmZekbA{mNwEcGN_S@1JSaPl&YcVe(X@&|^P6LhBTUmfA6Wqd1RWhAhz{qOb-R1?rPFzu z?oYzDfwp^;Q)2JJqG|m-mwlrw#6M>p$1!}Zfkc$PU7&#!-ax;(iM#tZgMVgmkrC+D zv=swOINy(Y;f>PRP^fF}R`BLmjZ`j9>Ki6*Oo%G1-Uop zW;0g*f%B77>hi%44wz{a3z@&v?)6XiF|`t;=I9nPM#m1YE^Y>uE1W+7eYcl(JTM=j zP;(}}HFcJ%g{sqmJ4>nqdIfv*{9{@W*U7Q5Yf09vZJSeDcG-C}U43c=)P?_dC`xzZ zr#2HRixt7v;x7RWG#mOfhz835g5G7Fi^6h#1_%3sC&YI$0#z*^{Fdh-OOKr|`WN?$ z&1gZ$n${T6+0!Dm?xk76lZavDj-z#uKx-Sg;JL1c-D299I0IpWE$aTdBI+jMT%|q- zcj2+u1(dy`Yf^bn$aZ6dZ?w#*BXGSxN8H{pj_lMm*YMrfP`CCn?UP>yf3-gBX^Hv8 zS$`#-C~`J4YW>%yBL-6NPk+t-7`Dyti9=M z?T7kpv8EGaz`^1{e>dXAp`JHgwD{3GOODo64$z(^&l2Z7x8z|~q_#W^vKCknHo{>y zv~^W>>~@7~^Y&Vj7J{1cz(!&>Dm z@Ffg6j^$e1I&7YV2gIUzDjxm-<7bH#9#`A7TPMqOM4SB^X6bBUOrKk|J?3xg>yZZi zBiVp{ZBGAD_Kw}X$S{zWLB0cMRW&`c8H1tS%a;V%NMh| zdYJ`zGVxK%aK47}DJmIyLIq2q3W%}_9=&JJ= zTG{DHoPR)ePiO}jgDb1(tYhFAVqf)G4RAmpZWM}OHN`w9yE{PfRB?R$#v&jp2(^2s}Q>h0e1t!kuQTshT!$Z(h=xH74LVj3-y zK#x0#Gd`fk)tFGmKRk4-JB4tK9vq#=X#&OfTdQk#c4-hf94`pWiTJArT_U8bs6o^8 zlJimT(7%_L4wREVu6k|P)BEskRCGz^;sXJiOpbF3ofi*pf(hz>#5YSGOc`gNB{(bs z(+fYkroGD_OS!MxF>L<$t6~_+ZXT_=_2Q=zym7fkgtKxgt`7gS_^wv+eOxw2`JcLo zs_LE4NqTF1jgF4@9*-eRZ71{lS5MLSgp040E!`w9>Vsz=@C?I$NNR}@7-37POOB@b zMGP^}8A@zdM!68wC8O2iTIjVfmsHqG_x{_5V6qVPEf;{SR6n$kWas;+A z+&Y%;b5_y!9qnzMmK+SgW~W&jl|JpCedFi=d$o@j3~zh&TiOgffx0X52c1F)J!@uX z%_jj%bT7rMHso~c{W4=>rgs50HE;0r<2$1uU;g@@B+&wo0ndcH7ZzDA8Yhm}V_!ed z*JncaH_v{-%ma+Dda0iF<<8F1a{Uo|`H>4c4XX3+P*CC?uimOj9|?LzH^wITfm~?o zkD}YTi!Sd%W+tu10rzBO-nZ%DKNTjYk&7Z?K?I5VbvWxmpQNwl!aF}hEcK42c}Bi~ z*GBdfh|1uU`sT88!Gd(;0ysk(Ay*x`3fu9cTn9rO8|*HO)Sb}CH8+d4r!}g&fY<); zzs>*r$JVZdN$h2~m+Jz_RXDQFJfJM%04qjR=DZ1=C-c0esRO*atr?!Ww30&Lw?Jo>`J=tkc zlvEz~5XsuO`Jh;pcCFGm^3rI36}T>%Z&jdks(h}}rBEkOi?+zT z%{#QgD5-gA^(6VSK|tMpl*PsF%tK(m+U$&#b=UiuHo5cq+Q+J+OXG?&12qm)bH3HH z-it4LzF|MxXRZ&rLmacj>A_Orh6_q)?u*8Q4ulun>ZV`H{NC$W@4DF)$`NM1PU^($s|n*4{YTWp_|`s+rpsQcQnOKco@fTGwO4R z#mn8-l(FvLHDkpU*t{1GCiDwwtLAek*usKC=6UY_>5b8e?3&Z4uvl#Kv=e}L?fcab z+o+^@5B|ID>wzZu@J}-`cWKY@A7`-rOp{A_(TmF_SXUkL!}F5W3j+>jy;vT;#Q3=A z4JPHak$cz#rMryDR7d`%CMPPVK#0?` znQp6W64?A2x6rf!iEKgtw$8<4IrSmjA|+L<6?xXhxf@Yw;m@ToS{!!><(DHd=7C9u zRW|TvdGa%t9=blS_~#)+x&{+AjWI&Q(T>^9CF-=#URJrgEjVQhQ1P12hal?|!9iacXpS&;RQV3?n$Yg((+vCDdeL4D ztHmD(y3w#l{YIk1@*L_Ra)h@D^b2GM`Q9>Fe#$^rgtrcYW{WC^95pBpzz_B7$NzyQ zL;m3hR0n+B|LEz4NRUb?_C$D!%F5tW+0W-V6AkO51_te53-!^;FPGLk#vT%BSN;9; z4zbv`(FeacQpw)( z8VsT{A*&Bx-k|H`MY{B*rk}_=*U%_SQbaF3B6uktI*KlLM`Fre2_DU{yLSpTk+rO~ zx{1i7MjRCibh}_lyP1$Y-8Mmy>y9tI26SQ9`o$n^S`?*3Xz9`TBE&ZRlf=3f`yAt|WcON_^Ekxc~15(De28wY>8 z+HS&ftSO>#I_fiVkqXFnwH>>a0Z=u^){D?OHp;%Y=UTP35%*zi^_A#h-rT_&&b49@7*-gM>Kj_@t^Po%SKk{vrRj>chK<)nkAORnyuc zlc0l0{d^>is+6oDV;L=J7N!$5NRdoQd=?^lh4vZBl!By zGUA!V{yGEaYMOM#w}?;4ZQDZ)C%;&!)^(faxdIfYD6!~~=?cuzEJ_A^N+V zbeNm9NzOClUc0Yh4pOo79Z5EQ@)*(25|kBb;>WxxXqnyi(OAdwJr<@HC|5|P0oU_0 z9c0VkU3U!L6Sv=IOx4G7&w(>sfKENM^%V`zNmxcVid=X}XJv}1YOd%gHjC|^6IJo;S2oJAI z~~L zAMtz4Uu$;Y`H}qdXA#1)FJ^yzlqv}AXCIssJ-*Vu(}a$7e=^c4j#xXP(_DtFmhovt zx?zebFQQ0XQ|g}_lUxle7%heTL2U%~0sx;#-+?dbtLgV2-?-^}GIBnlRTH0Q1|YI*m0%s=KFRnP!8f%08`Q zB9~PoM+VSIemgvZ>xe-6)?iLvIHW=SDSH-8(2yD&DGQ@oNEyFaWE{#n^o|IZ%U|Yb!2> zSHW7lNJz(1*)qxhrH-*;fIDE=~vO4JWdfb8j z|KbkkO7kBh*X{_Rmsowp1#MxU;NlqIjWwx+7)*O0J|4H^PgsHFAljF;r3c(!cuzEc<#W*X6D`tH`!2KKV=ps||#Vv=-KP@O; z`3as*>gP>sjSh`;C2F<*5^JrS0!Zp>o4$EiHnITgeLDymw^Sv2?;t`-+Z>!Kl-M7=E}z z3~7tU04uJS@|qez)IcpZSLfN?MQihyrh8gN%*W*I1W3(qb*p5bA`VBu=d0bmOq4CC z4d)SCvei4!9L(3tvO0FQ1F^f=3Q@MRTlk8~Hjf1a z{P>Pe4q1qI#h&!f4rHBAjCGy#^`Kbvl^;V^ZUNL`u8~=uSygz|=Pt`>djS!2br6pqT8uBA zNum0mFj`iSGW^6#cv;HE-v*1e<7IDC$cQTs6JbNbr(3sxSG576A0SwHKZZ@4SIV)9 zmdL-&YkaA4d)bI8o`ogRSn${9Mb6$tt+B^^J^?aU4QlwrYm;+&tOy`E8@YJT8k+07HSV>dC|(0URo!*eY0dr zIYXS}aBI;w1nn`%hYj$)5tft~{vyj3w0P$_(@!tXR&Ldc-Q(tBMkqh)k~&$uch%Z$ zu<&^mb&kLA;LfwM!YQiQ0e@IP{*Zy_QCxVgHVhXfd>XEyY3F3t?eYX0o&5HbdujC zv%b=>z}#xaPAt4m$&Ol=altN=liGu*sU%ygUa&FukasV{{?olFjx6zgF@!^;moQ(9 z)^lTUGSA4FgSMC1&SXwF54SzVgR4qGmjxyCB6mc4(&@x>jobdna~ZwL)4K5|a{PBI z%Z6OOzxLQQn_Nc>KHJeZZn{N`b{g|t!7d*GD+ZqW_ZM!zbDBl2?;H1;I((=hoIu7w z(oQae_LxOmpidU2=yh!9R-D`N^D>xc2O7ocVigEKpgrOs5Q5NF3}vr(aaRI8amwH~ ze(#(nhNRAV2AW6iU3%bIiO6BfhiAo)Lvt~c9Td*29)dnRp?7zSB;IX}L+NON$a7E1 zrEExJE-J1*NXo4B^}+n!6AfHuGkj>=+Vm8SfqLeH*(0}h4Abq6vdC|G+}xSl_(H43ay)40JiZkwGutM22$NlqWNj?H9d30uyBhEr~Is$)u;uZbAG4I%W2F^rtK z@n~e9U@Qs07V6Xce|h5sVAIL=`a8o#{>DzWfsI>XmU{Su<1BwX750^ZKmYUj)*eWR z=V=Twn)2d;FeB7= z+Ix0Y07t@bP}^lQHK>>wzA~Za@HhGSUrF@H>!SkhxT!_vM}X_DQUtc!AI6egt4-q> zGy6`prAaQTnYl}G5}%`V&$%GDT4*HUn9Az$9`{vvO%K;&NQdLN$9Ip-Z&VLII+H?- z*}zSA0LX^ysLS}7z*E^4<5AjS_RpqUX@m>!(}bz#iiSfK+s7983r2xbQQl2Ylq|bL zohKTy6Ep{fLFj>`0nU1lp7-T&Ko8D4VvOEi7uoUXD?U zy>sA=wa3%l1u_rs^la-P!lWRFK5uZDk_+?v&T0uq!7Qp!OlM7y?;P3B9o75}Zoc(< zdG`K}uD0K86Kk=>S4ikpSL!2BawB4F>n7^^Z-BrEtvlQPp*FW-k; z9>=Fo=m#D}PYNKn6E&*S;n#D02-!q-$Q(sOwTI&@@Wo0= zWgl<1K*d7-UoQtqo;~hBzPmJO`?8(6s+3&_OawT^n}Jf7=qSw%ANvQO(%7e1g^GqPmQT8OMTYj3gB#(H*d5P8 zO=9dGwHQKs(vBO~e)lqow!&~LjX3|Nn(-MWp#>gvQrld;pIu=WlasGexw} z^MmN-UH9XWQy{{**R7su)BNi&c)E&V*oN=P_Sv6%i+8t-9a_Hd%juQO z8MVp8@r@_7$P_4K_nu9RXYK66@p0VVa!jqBij;_w{}d{J)1B)saj$`1Lb` zU%zfv(TWGsh3cP)2Haat9-)0G7;KOF%HRK|(oJa`lZxZ>Fd)&nq%vfdeP(VM?pGpJM zW<9i3D(KxyZptz#kfP>_FPGX+>=A|+Mv@WD%@fjc&B2-HyiThIdkBnfMD!kneO_?P zyw$jEFbwpeqN`fe;k`wHP(85`?z_~0ueTOQHGpQ{9EiKq}9P%a40gm>cS||d)>9@yJZ6FJAe%Hghau#}WjEwIj1`!L0c7w4u7sOEt z%QL-WY|PsHihkgmRo)M(3O36$YjzJRg5GAaE#C0zRG2WD;iE1{$?KJ0bn$MX7nScI z+>RKIr!FYh4NSGbSzO4>*eN+3f#R*rmKK^f+k3g<$3c8-TzIYbC2oXgS``iYr}+tkCvelHz}q z`I`U6HfpOv%2{8h0uT_s-XTo^L)FF8{iTxnwu?zY-TaT}b}7%$821l*B+tWKap&6} z=)2En7cssMCTP30euk)%PgFx7kb%%35*gO}G?X`wGNyH4f-8*`iEv~{< z?)q?H5zOQWmrY{dBWp(Eqtl+RRD1~cYvh_5aZ^P}a)pCSG z%az6(Q(<`re?&Bq_jmR~k{;~5OGSA+}a~rZBfCNkdc**+rUU&r^*FH<8IT21b z(N;lW#%5oCL{o8dyLrHi!?w&3Rr;bLa<>wp?RwwJpVj~Yb|j7~XuE>*GqHd#Cal}+ zwC`%%K++dRxYxbZV^NvK^rxXatDGpm-y>D0SCjW~5umT-Z!P{ZCcZ^ZE1xrf`PM#$ zC;Q1Mo8mI%H=}uCGD=_9&TURAdf`3(X{ThC5!M|u;*}C$+)W^1t_d^hH z8(C;OD`*(b1MGh2Tl=XC1_6P>?fc4xK9io3dOrBJ=cIrRlt|;}Wc~^KwLl7eY1&oxLJUVx4f+gP&G<1G z#h|ljvA_)8dp^1L9noLuoaijJj(V{UhDDH18%x}DP@#U?7x^)^RIM=~J&$7vrwSoi z1@DLezmNgK-4clIIX>PY=M#G(HYC?kfIzf4nfv*i>AS-4?;6X&jxAwI%I{>_!lj$MAhO}0QO)TeZ8Rz4 zim;G=dt^u#x;q2xzreTt5WDjXRfsLhd+{nEo16BDxQc6@d2w4apP&qeGjo6sptPjYv$OTzHs{;M zW*t#!Y-(;!{#Hpi^+D5Ive)CY#r`DPG9K3h7UjSv`)K_n`1tEl|DM!>Bh9!;vW=)- z^~E;gEy>Js3UafX=q=N*(h#o@<~>N7(W37bc2mhl9?AP7tT@!x35mZH-b6QQsqsfm zX$JercKgkr0}$JYJ>!Z;u?;%{$u@6MY~czjof-@-MhVa6S?Zaz_Lv(C0mpC7j|#{H zPCS__T!h}jw0hk~gchCb;pr|iG|PqEbDv*`4d(CiI3_`?B_cXzSiR4vtkMsQS8MNT zK=WM zXHUXZvM~5MHf)w4mDU!|-eCF*@=W0Gb6@@X;-o0~Ec7qRYYtDC1s)Tm3IfX!y3c5o z_qR(szyyRjO>1(qDBAFXMp4uy^qAuXA!GMwiRNf`c{a0r4GQ~!FR3?j=T33y@?`WV zb+vO!*;i8P+(j~Asxx^z84`rZuM;{c;-QQ}fe``pHB;z!!>|hlTQ&zyoIcQa(a`|k z8Pe)q^C*0p@lcTT)V}0s%mCW;dE(>`4UX@H2Ua)i-j3B^DoAx!vW9$F#0`iBR3Z&wq4h4q-KFh*qrn`c}fT*wz^mL9@PAPjuTANJc%2!3_*` zB=p|+=X9ZGEN6v7?d|Onsi1DD3%Si((m#VIewTcIixs4sx*JC*d=jN=q3y?^#Wt_~ z%BL^=0+>f&=Tmm)Yv}Mv6LumFjf_0k7bPCcF4ou6Ybs;=`O)Bc7V+Y_Z%M-A-YaWu zV?2MY3(g|Ec>>;JfA4?zx~i}!*rqKC3ew%(-Cfe%CEeYf3nC!h-QC>{O83$o(hb5= zyVTEn@E`J>KZnmXGk45A$0~>8<7!3-@l54L=;VVovlvHfmXSYyHhetJ`kQ z!odYrD!*yel~9^MDJL-A{^+s*shD3!z~KJIRDqlfsx6I=q_^q^(Hp$ihE~y$7cV@&PKl|hX7T?x0#16`4C=5F-oBzfM z8x0+D^d4UEZvmbzhOrr5!Aeh@WZAD-FE7{k$8)7Xk%m_<$n}2h+^|wEq`Q5pj+FG+ z8%I;I*@Au$AN~XvG-OOT^q>e?zMf$TV)+5z9GqX{+*HO8U2sSXmTqm5pIWo`)#W2| zGRqz-S)F->2&uFzBCaImGqklD$|+_K9?=#QCJA`zoLD7$rn@rmLYVt4WsyBU!?t_& zUU^Tk=Ot);r~>V^#{oYNdAn&pnndQ9CU#5|M7K4hCxN{e3g|ujNo8_JQNKg-CoS_( zRMu%#OO7)(N1Lqf7v+nbpmMm>eUL`a?5`o>&dxE7Zz^J znrmY@D^|T$_7JUy8j-wcrtuW>=R$2V7G<2rbR{BZehx_vF4P#*)>-n(cYKt^35H|* zl5V-8p=z~u=(clPu!Rn~|KkW@+YfmCZziGdu>#iyJXa~4F8ue&!gGG@jhljM4>6bDcWP4&4e}eX*^OxIlK(Q7|cBA z&3U8Hf5${I-jlH^?84mUOblfl2ls3N9ZY2=L(z$8U>>Lr!)hzrj_zQL(qEy$h`}~u%O^!xA73fcEpE==%pXok#m~Bv zQQxq(QxGOYK$5oYaa<dmsXSHRfToqb7*?}Q7>;`yo~b1QkwX63Qf zIeJS;A7aL;SKhjMF0avMCs&}lJOA_UnOEuFCkx+}V5yH;%_@1LCagtwcgsTAIi@lB zUyxrihL?ASzJH$?`VQ^t6z;r(tw0dLEAaP550P}w@pi6CzgW4KrP{-y<&9!xYF>)9 zRrEq?wk?Q|>^mOeRoWF3ETMDi(*gSa6WF6IblJEeQAX~uzVZ-tIku~;@g6+X8V6o{ zAO^ggjK`;EFgIPbPv9TDf`9>USBBp7hu0VW5s;xG%7L)|lUqk5v-At_75qBR?GF=0 z9)L`tZ$XayETEbNrVvrS6;A~&RDPSP>v`YBVE5n5^O*+g{f*X4CuFLI&ZqKU)#BF%x6*Z+yv>9A@nlSyn#5vg*@C#{{1ibn#sU z`A1ZEhKKUMgGq8Ck&I$1+vHCTiH=>Al3C4LXok34#4uY`?3F9C|}3=5IVHoX8j8Ixzn)^_nN;oV*ZYk7MR>;4eMyFB5u_d7BM!Gv?Hc^(klOZ zLQ&uJ=UaDl#7RDfp5Y_n2rXPB8ZZWf-FQZ3<78Asn~y?;c()j^>ra)DSh9PR)hb%8 zy<_6c0CAYvH`SBC`?$fifzv!{{6*<{D#GByV^=CtXvu1eWi7d?Gs~(z7d?-v;kP8V zdl8}M z@50r_Kf2xi>a7{6+W`ymZ{Vdq4P!dT1B`-~~W#v<-*$?qyI< zgd;?SlYmj2x)x&76N!Z_rk??co$qrRUV?Ad*Iptqss9;RkD|?V!j!Pa12du$m;6>J zu4SSictvGzKhgo($4_{mQe28nBff)VU*n8Lmr$Z4bM3F|ulbgU>qL0GKh-6<)xjz} z=ziJOjmS?8OvI^y%^yz*i_qASP#%zZ&MFvl$6?abIirgH zFhH$npo2aj-3^CdpEQ}nS|6W1$+}YO6X`|&{44KbyxoTQu${2bHjyZI9Y;HO!KC_* zEN1wG$#EXn*0(TDm+G0`!2rU_gm2=s{W(Z>jJ;FtutS+KJN&Kt5g;x^*u@k`nq?hN1 z;`vD)mkh%bRF-;@Meq>QM%~PWYo2mYZ=*VHjm6eO)R`_P*P>n4-wm2o>kDi zc)tL2eS8~d454!L-{-^q)u8`M!+0Nq+q*-A!j$3)UQV}Og#=;hb9OIwrQ&ywV)xoh zQ!P;|NHj3_5i-s6{&dLBVy>4_tcGYH4B@ar%9-gamO^ac!|f8WQ$Sc`h?hxHWw!mH zazit>qKweFXDzCPv7AK}ak@}n8qe77&-ObGad2U;f}p6#etbS=-x4Bb+v{)tDhQj9 zfDKb#l2SLwz`nm%U?)AwACqYw78il=RfTmV20y9SBFnw;kBs2B$oU4{4r*)EXYjIl z&(`kp)Thlajm!rg1N5WKI(g&=8EIQC(adw{Y4#o~ratq6~4atkYG8 z({PE#|F(fNOgXI3g2=owM;)gFnJah48zL^)a#hf#5bL4X3lSIX13o9Qs3M+9<*dYW zu`9vMnp^PVqo}R085r~zcot-uPp;d1%MP**@0HWVtj${<+l(MM>@dH}VUsmdx-o5E z>FCQQ4*wumbZ=%@FVu05jP*Q+YHix%)95wfbGMG$a>BtGtQ#Ri^|Z6iB|~-T&CI}3 z07sq8js_U}7hlt?lX(!zlZ|NX0pDFCh3}6H!CTH5DerIR>PfySE8{pT zeeXdd$-ms32rblaz$k%k_(wOxx0uUlnS1(KXAqdMPL-MD(b}zeFzq9 zg|unYEtbg+$3^nahFiE78I5YgvYqy0{`ZILAUXaJF<6(hj`_Ju$!j@sySWP!MQ|!+ zJn641 z>b#ySWUkCdaNnWSWhUksFN6V`JmZMk>zp=4+{b0Ku^nCql8+-Cno0><-+~l8)WbQm zPko8JbI4N@pNrO1vtk`y_l?Lg=J5O`YKNHjLGbE|w#N>P0u6a|ypn`a%q*=P-FBKh z-4;A$$8&w$UWp)^+{~vPM~b}3=bE$!j=H>0t~b7EEdf|W^#7xuctTUn>MAGv%$f(w z$P)~qv2CK@ecI%JpdE%92?Dz4(bN+TBfrH4OrJ}1bOh-w;HnHDecY0ZtBJc(GAkcS zBSYp5xFx4j8R)VZ4u_LjN!sApjsXOj&7R#Sc(v3La|UnpwVB9UYezDUldhI@bfx|E zU~>^^OEjmnL&t`S1NrIXCbl5 zRDO-_0ox?Ex?`mwGYmBgoO;10Nz00MI{m3zy3|XHF1;`3;eLPpTJf@uhDm>eNV)yU zr-tJm<$*+Q^`t`IXcmVaoZaczo3F%1Lt~qAg$&6hBgJ5I>gMu~*rr_@6OY0J^&5+= zy+%xf9&%2gI0QXGU^yY{HrTZ&{Z>L&O07uFFAZmtwQ}2WY8A!)*NV*z3Zl27g#mO< zHF6pwdmHZIVi6%4e<`yU85?$AR^o-mbZQpxhA--4S zp7m1=?RgnPVZ28wcSD{TA~7GSALNw{f4;rJaV+Q!;Mo|?JR;r+{`PjKQ24X=%Ur2a zDbQK;H<0f)$A!Z4M`aik>6v-e&Vp6~E1tbjDz(ySt@r;y|9}4ghYtUJbn?Us`%TYA zpd^bOx|D+c>TVU;SyWFaXZeJ&6$kl?7_73-O4)an=^8vJx!|&*$M8>_o`eNYI{LFM%(Dj{ak$RC1BktL&kuATu;biZ~q^kH2g9{5tY?3ot#^a|^ftXSZ*tAZ)dNNk(&gy*5tp+6mCCHCqHvLQ4A;CFh5+u;?GSxs1 z|AIEPyGLU)&F&;ey(}t{jaoF8Y)vl9LFl*Z_I#S>{k*<|Pe4-SdartIQ;cYUk4bVZ_6k;}c>+8|ie(7xPN?qYE@!T`i z;XRw*UY865vU~i%E_kV%be+ZQRcVp#ybZgY_ z+VBt1G_bA`!4=vRD@<_T$&|vqU`W5BX?1CENUH!v{C<9WC3xnWB_A~aDqW?3aVfv@ zX-RvX+6U7W5INFk!)mj|*Odte{*=)N=N9X@V}%mD(E@w8G0wazhs;ePF}qU0L;;YUQA~d64$J~~=hK|l1ft=U z<>LU4xvZpat#iI@T|ptOWEy7r&ll4y6>;evER@>a=lUnYp+fbk2+v^SnNFXd2`)N> z;viz-oj;R0c=#uzC>Hh8L@ZqU&Df83$Nz_Dw zciztVqSPEn;bF8pOXd(GT)h?}9}p%2bAOYU6!Olr_)o>zT2Wxz*sqo=uzkM?r=Iyb z{g3cD<1zggC+U_K%bBBz7Cr$U4epnMlKO4&9+3hGuhC zOt~CIvva$_COJ0i)dT;c9uFIZ5}*3M$n~n@lcRd-=mx7k4A#+OnW`}O!S%BTngqDv ztkoLBis93mV^P*&lN!Ib#5w@)FPcV%BYfgK)~!caX&1Sgu#|sje^Ui}4lyL3+I#O} z_AM832(P!ugnMCAy~kWTtF0+W{^AP4si{7s*gcyU zpSMw-yLQ|N@Tl4K4Gyen|0z`9&e8uUmZo`lQ z`y$SZ#yz=wtB&@sMFR`6{t`DNPB$GB!p2O>$S4)3qu7tAW@W7`po()|ru?p-);k_- z&z_q5t1D1Q($ljvmRR_t>(Q&U?TM0XlkIf`|EL!r2zZ3--<)68mOeiEq8@?CEGAvk zYtb50n@o&|L~|DUeh5h#D;J}|KN?Wz|BnxZ{U1w8CeHOgD2@%(AATJCCVGw)5|jmV z-v;_yMwGg=U-p?4VdWKa>Pa4+IPd;H3xIoam+6;vOV^Zs%BrCg!jGq2>P>h0Z;`)8 z+|ry@I3U;s>{2^8R*@`RcsZT}%rX{*N}4~!PfL9cAaaEheEU<7Wn|R)NZnFY3fJCw z=#H7VuU$Mlcu<@PKj7JD8?8cUMdnOd6uDplAo80a>%rinC99}ty=R7m>afKD^f0xe z43SinMq*U@gGd_hI7VX*Q|pZ`cMH;#vFa<-&>0Jj8v(0c$2B+VI;l>05y`p6=lVK( zvGbyJ^~Av0-kx9P9;oV(#eC+S>yh8azo%yVOGa{MjQqJB?aad56o&Y(bB8}3>p?F{ zc1olAK5l;yZ*%^uljRf=Pl7S|Lq~eh$u2V(C9;rr2Rq|g zyEPA2yZ-p+{>_S_1Du)?)z1qeGx$%GglydFk`D)@BY_ltQ$tF%u2f=++7UN0@<&Tv z>BwM=Lha9=uhrN5Fi8qY(tR46@@;x3FMf5CNu)|z{M3c_7cMC#mIxvlH3g)zlP5?3 zn0e$%M2&hxOftO{zz=xDvTW*#f4RD1efc?)_!2R*K^Ra^b9$LuFPnxvYsNS;WMn=E z-&diFj5_4NO%!s0|4wS!-`M{^kFXC|(EHsc2Zeg{83zY+r@V;*dBQjcJ^6(@*A<(A zwt2&pL~@2p5|M+3lQ0;rY7YczNs%{peqdhO=D%=;{%ebf(?rLBVHgE52inIUe2YMD z)cHa&s#?g6*2B^vw&v}EcLRTSeUWfEd+bWksB+4a138P{D;(OS-AX&)nR6h7#7rs* z*pV)5(2`Pklg&_Ro}g1x?B?T%#@t>PJs_i8xbNUT>I&obO8Z@(o_#<0-FTq2!X}m4 zD*8{*li^g*@{x$|1m-b!H!lOs>g)QTcUuvE&5+nlw^MuACHV;9?OKAIY4kM~1$;io zwI4ODPQN@Fzdn80`y7T`y0rdfRkph2j5z`}UkEu#91A|^+;|b=?u(GXxF%3nH8@Ww zG_0m7A>`>>*Leh$^*+5!jBAqb>FgXcEA6YzRRwokYE|p})|VAr5R*D!`LDEm9G1{b z{41N){raVqV5X13C)Oou-g1LeHRF2QXWa0d+v5%kRE3Kz0#LkqPcX`A#{daNaV4;_ zXP6eNSVtr2j*@zL6V-hK&=zTkxQlo*Gn~miEex$qG%G;iGxeoA@MZgk;^VXF_bXmP zYTj$?ARMjw^s1fxu20eJK4oPVTw$6U`iIHIFzCfske*zI6&=cC7Q<_kQ!x1)Ytj#OqdIevh_O?+CCkNn*x^kCy>yw6v=aNs4L2CN z-VuLcbz$nT6Ii@Pv2nr3_qYEJQ?c@gz?xQ{!XKVP#-J!M0gEO7k;;c^@{N>x))jRz zL14o}l4U>?$4Y6_PuXw1@5A0FD;k6f$bF9PjBcka)Po#1o zgM-WD3fQ-GHSrnSu}uKwAJczMB@fq+m60U_MHw2+CnrjX_Xwde;p$~0BK@s0tL_v@ z^R$Z#52R9ETL>|#EVKC{GN&T=2S{PX6uZ517L=#INnTYrY0I+?6IE=NZ8z26kD;Kp z+kJ`jJjUW6T*_GNH1mzjLud1YD(#6%j1LgMQWJD!?Igz9oh)HRe!B_pnA!dmI_XO9 zoK(VWf{0w`OkGWHD7R=#|FLCZIN~ZLKxnrvEyjM0@p81(XFxYAp4;3MbGU$(uH+o| zyLLl#+lJBn2x;zqArIuXs~jupM7xP4`Um)6#(6ezbmy0`v zB&_99B}j2YtpzNl(r%6+I;l~j)>#Yyjx6hdnE3A)`t=KChjhWR^Ma)_DE(gnmQW%F zg?+t>GZ;7dCCz-07yWFv2=4J|hdjVo;$yiwb@%j=5;&^54@Jjv992juRwS=ClG$W) z5dUbG@rG=AOGz98jLlWb74jDVJUtxWsPK}BFJQpMpzN_{R@@D~|A#)m1qb&+adf`V z%snB%a+J&{6el@O7yN7+AZ<{;$u%Sy9bP*i9sdF)>sT1ey5|jh3%oi2r^Xs%i~Hhy zCpPeMJvw%~_oMDp8x+xW`=AD`_nx&jg(Y44WTY05D@?61sJNQ!W z+R{D*v33UIoFHZu z$d?*fqfl#Og}q$t<(l15k>G|J3p_C7yxWv5qMmSgJoxDMPKsFWr|mK9@`#6Op81@> z(iTc1!eLV`r0hjrgt`;ZfCwqI;ewu+@vH?YzYW=Mjz%cXg4;sTGBZD|TTX3u5|b6P zYTUqwb>U>{0AYb+d(e}4LFj+}wJ-56FPW>MN5cMZmzkb!j&I5VGpe>V&qX`F(JSpu z3GlAS?{jEK|KTRmG`s(iRqslsd{b&$5fp}DY3Zkduu3tcR0JlO{bFq(4k4Kn%fV(n zxez0t-panXNKn=&qC@Q-ii^;>rKFS}phs;c(cjJ;pjRm>t9%-d=F+DgbrG=kx2i>- zNc%Nq&4yRWcaSyE)Q3oaYii*0c;@1dSevzu;p&?;+uE*r)R2af4ezhHLV%evPS$mx z?fZ4@>~tIlICGe!Fhom`S?qRH59A&|9*puACmO=F_fMuy#rpXxjTr^TRN3)4S&RAw zk=1N2>x=WH2Ve%N^WclyqV3bC2rqZp>BSCPzAZ;ZOHJ^CDpTiI zx&ec*2hHRXsnU|Z+G73M{ND{-rmQq0*}kLSW)dQd?E+T#)ufEac-FdT)$ol`fx|;d z0Nvs(6X9omsI{B<#ZM~JZWarZ$o&2m_Wi0%+RFYt9Nri)N-@)|SsY_4EE0cu?{GCV z2WBm`YLW4U$j3zkheW1|mzHOv?)F584NE4tmrENC?rxskApagnw?to29CMIopSY(S zx7_@{zMWJfnGT2n@otJE&-C~c7sct(A7DD`veQq0dUqlXeBJp2r@7Z3LgqVbdd~;7v(fe(`=XYi~fyF%9ths zZG2Y*4VNcQcuZWm#qLbgbqpH>rH*HMZmY5XAXy4^q{05XxX=*HL{TJBGl$?Fn4-lx zAwg;1XgLNKWFMFM61^JL6(cMcU|Yj#_aiR2FBn$dCAQg_e5$vpb)i7cDcHt+KaqtS zO)$t~9&1|pE%P9tamGZRiE@$*=lHWM@%gET7^QYV3MoLhYBDZZtbRLXYU@(x-VXIw z<7Rb5uc1P#xs5G|{fEyQ^b1Mts(F)h%lQz|-b+pQgTs$FHizFEz=V`GjivDsDJl9E zxqH5P;@$KqOG0j+fHR{S6#h3B64-w}f82@M z;^LH6YH0eYUs_E{T-g7_GjJ^Nks}DpqC*Sz`{*9@z3C3Xk>y4h*`Ev^S=Dj2qr!nKfkc@tWYCjud#kJv}~Ma-@d6$$h)yd?fse z`FuF1|MuJHT(!_n^3kiWwJciSn`T))I)=Pi;T=PYcK=6n@qvZrrS+1DE=mGy{(B}c z1Cvb)e+d)Kd5k$GMZW*V>yT$1 zM15H!4G^@JSA2xOsZi1tF0?B}9_wgEcsOsX4Bz!&iQ1l-35g zp0J7c6hPRB;a`XL<6Gyeg7_KS0@t*za^DV8D9is&qEwqrTC-Uxae>iyqb)fG#_`x+ zJaY8XXKz~~2u+G<&K^w~#HDPRJO8x15ZK-Fe;tLZuOA&%zJ=XJnRY4ii{`w(rsYRH z$jrSn(HqJ3RozYs$bw_VIgJKQ2CqZ1Epb|zLaLF%Kl9%Ag+9=W0cwI2N0V6knt0=s zT;V!1(5qi`RF*ddH?oO{h?MTH?!b>;k55`}`wzT;m#5NpKQO)j@YCtdwM=}P zyor9Ys#1UVPO6O^d2viMCEnyZ_q!%CoHsz@|Dj+1{YoJW7f3=I?hFm4mDb7dLCeqC zQ2gezcrA=lA;+HIL zAQreaz}?$?Px2okKrtxqJJmF&5wzMP)*&f{Te)0&wH;2mwK=!rqSWf2nsDV}IiAv; zWCmY!#O28+*qH2zX5*w-clz|E22KNe#Y)jJ(?Kf*zsW4`3CAF#sspPFCPZaX#V^e< zx?f`iyBZB`G7WJ_vK3rUezXyFUUNSgxpSLvVItdCHj8m^9ulMaXOMgc#&(G^3$v z2ZHc6e9(nSxljAq^fk4qePI{q-Nyr8HGd?@U`~N442R>y>)Az=&P|66 zl;xw`p+dqi)zKtymlFCu%Oa|B*~D$EOA4wa7r9kH$C{%(KEZ+$L!{eB=+k~3janT*8}2UNgH&7 zupI*AQTS#DEg`YBo!^5&>dVs^EfkJvF}wS2*oR&$6^RCqqXR*tE+$fYFn0;5l%GuM z3}%+<+(rtOqR7OU5IXi_Ppb}Ft6*%%|1ns$Ha))V4)%4qL+Jp)5f^V)eXdrj?~)_z z}Ay98pa$f+r&cU5Lpc<#S0x!V3xtT;}LV#mwftHi?G{G zYOQv(iK`jAT$c7q@CnY6N17QWU2X9bl)=@mmc;Yah#~u1qc`mHgZ&8T0lcgo=e~^@ z;h;C0D&O;SZNOWpAqL&cqy7_?WQ$=)IM#UHlkq+&+A-@7p3T`B)t!_U<{*Zq}5%Z&3RcsmaXQ@aD zg2u$0}#YcL{dU){2YK zp?C$<#Xx;G8v(%H@fiEj9hPs`Zlp#nM$4w`UO4H1a(N>W>`ml`S;$c8;gIPf@UyFw z9)dSlAd~(1JRzgqj1m8~*F>1BfAW!GdV14`U%eqI6CQ$z{TI93+cG*8nBtj+2#n!H zd~iX_LCmI!;@yv3lbu^hpJVWAoME?WIs|jF`=$O#69sqVd2TW?gMa(`vpD|98vnx| zJFVe)LDOZ?D`v!9Gur1L&^FbZ5>;>ewjFj|Y?kfEyG7tAPb1EGhN8N6LPRk^;juvYtDDt?MsNrKoA3<;qg}GN!Oj702)qXeo+hI#L|Cc7*T! zf_m+j^%PSM6JzwWkTNE1%&H#PE8@;PX@iy7VUeN&dle;xY^PUQRO@I@J# zgi6H3NAWrl@~p5C7|x^KarOZk3^zN+n@PBo`yD}|a!Pj`L0mVG4a{SN4LUUyf6O#nt4w=;ip2%LgE+fX}*{!)6(l(CLD)H%|Nq z0hP%o)WCb8Bv)p~u~c)`1N(zDDbR}kpnYw7)3X5^wnNN!hx61`wtA<94Yy^~3&m3V z5?dkk;BU}+oA~Xm1)D1eI@s#I-qpAVt2^`tfPbJ>>& zRL6`%1~Ng$J#V*%Kul^}x8BLG#VJi91Qs$KmeV#9I`v{l{qOTGuy2ixSY-5n-54bO z*xC^MFB1K8LYT6B6)qVvBq2;*MDwTkmeQN2rPObq0a<^QWmJP#T6JNX`X&RDbCAR( zc8<<=cMOVEc7d!^_{2Qe!(X22I*T5g+>Ta-@wr5czb(~oyN6$WLQ`juX_x46H4pQz zrwy_R3p>0X=~TGD5@Z#Bm3H`d`SaAz;g}`l=X3I#`aGSfmXb`5QD_7W9Esl0N+gq} z27YWS_KuLZg_Xr;`PpgvN;RLwd--KU6?e`+P7fkn$-e{&0YQS2y zp!k>rU{UV@Hu0)$F=NTaWj|P#GQ+rD^4wwTGD4ArxA_;m+A6dA;(gqGHXOO1a zB!23HtDLoE>&4`~6mNMfRuxs7x0jzoC&S1UR5i>$r(JSf(i!1! zwZYH1Bo~gq$@xi{o=l*o8F*vfY4P|5f_>g%{F5Z+6U`V1$LY zqvE|yp#Ec|+cO;Uq=K30pHE4`WU7Be_Y9k&4!g>*l1kje*E-0mSr3$Zl*4#Z3rN+q zIVBwL_BM=8XrTIk7v5IJBq^3i`954`OPN-k4^=F#UNWX@eL81k%{|8sWI2yH$Ad4Q zKd>SKTvv8a*hmOHk9T=zGXU=ksLr43D%2NZViE=^xrjI7zpsHLvTES-^(?fK%f-VJ zs)iXZw!*%VfswpyP~BIm7&sq&&VRa|OqTWL#bp}Bnr}MB85;zSmU!Jw`1o!3W3}yTG%>|(>I%|0sCfWks2%(x5HSU zuZet3p(Wz&2fl_z9?pVC+9K$}Z2SgVR~VKYGq69SBURyUFWHW*SNw1dZ?%sb%N}40 zmnXH-AH^xAsL3}9NQVBj(lQ@q6G}@l<}l4a$%hy9J@$$m(>Jvd;Ilx0-MK zz_&@Kl`azUpk<2>6ZM=1_3;H!N*7EeRr(y4je}4k)zR)H#lUUvqNPk8VwVxjVk=om zNlJY?o^|STDZM|=Pxd?GN}m1Y6875v=tuX(k93vwuj~cPV|CrPNZUPKHxs*y`hq>7 z5Rd1~$rOXwmgs`fVz`+Jr0EeLIw^T)`X3vX*g=0PNn2e*AnxEQ4HX%kB!-;s8$pL7 zpF0X(Vc20~1y>npG%)@~Qf&-7Op6OHOfImrkVP`wSA!{g(-bZV6u!rdweOc5OH76| zqE$tHx!43;;}|Dt6~z^Bd(4U6k66$KVG z2`u(bdS+Pj$>S+x20y6C^|dR7$>jR*@zo)x`vYyEA^a!uoey{xPZtjqnRC0xZm;Jr zZl0c=kcX?e;HH7M=+2Vw!g_Z9Vkz$~of{X$SI92NBdBEZ3 z;!|FmgmvTuVqZGOxR%OT6AI%V+cv|T2@8Z#oii(QFH8LE{O51FmOe(L-Fukk8HBb) zjih4jbl{8*db?)R_!;aRd*-|o-}bdbfmI|$T97s&v~9@Dh?#vVRc-ojx+`KbquM&| zk8^|FkD(v_ffO2Bp6Vu>8*zKDuz-gH`^8JoUD7>CsJ7rIOI^e{tM9dxb7b@W>$&va zB~pU|DU!~|s*qhH*3gMeN!--sIk<2lwr85m9R&@?duf86_{Nb*FzmQ3m>@P(O7Ryx zD|L7WK)?ar=5Uk9Jn@#ZyMjL#I~{Nw%XH?I5|>yK{dlOTB^7FkEV+D>m`0hqsAM~R zC~W2k5-SD<;-FVc-((1r?&hW7hW8k!t%8=aqz0;quW65!<$~jccIcQHxd2Po?91+TS5VXfX+k28|14_bKg(hCsa)Af}R6gA`#3+JzWDKx4)ZK zT^$zRUxBFlZ=Qk)e^>Km`55r^qXa?~mdm_!*5PFSEtSt6nXiZo+6=AAiF&D|kx3Q1 zop@bj%ZPzQOrb(2iSVD)oe6kCcghHdg#M!&`37}6adVuFLaBwu2CayRevP(0Ckr33 zvGmt?5!5xVLn)}r4z6I*pKY3_ofDBUg(}l2HsBN|KVLUs(gm(W`z)W_sphVSOi)jN z&WECrWqP+#<5cqm4mII~n_J_{dSPijOE=!M%&>W0zgrEjgkYVu9BQj6irVC&f7MsZ zcRbs?_juK5QL$?%G{I7C(TDcmd*ZcvFWC*MCv-P+Yil?nentrhp{M3zS3It3R)j|n zicfgI39UxKV%ddr#X>@BAr$lRiHAv3#~@u$ya-kXX#52nWvpfqpW@(; zl$7DU?5SNTUQzg~cZEtgmQlXvd&x5E+pBV|SR!Xw27N z^F)KRg)oL+v681w=>1W0r+hUzw_1x!3_}uO;-dq|fVQaWQBGsGHk(ig;2ZN$ z(mcDmiGY1dT{E3W3#IjA5+iW}ao@Ia@n0EN7zMY>GP?$|Ud+p5kNjUv$apu5XH#d# z55GRjT}eIz!)Cs3W!|iq&Rsl^mpoCm0k%lM1m7<~a=?ahVCO!&#VUNp_RuruK^H*) zereXIpAZ;*&K`0U(M9;L zY}HA@3LgI$8z#xo)|r}cp_KwY5(OyzePG;9FV!1pi7$o>!Wnd&St?q*N+0@sc~%j1 zT6S#Ua*+Gnb|5VCwQu~vit<;6OH~@QN}gR}(vrAtWT_cGF1NT?-)44QghtM1{Qy^~ zL^#J2Bf78i{ItC&e&Mq)Ao_V{?nRT)%HLyjTNt7A6+XmsS&1KVCwUvJS2^$RM_(!> z7@IZ=E|$o~iMpGxfh$(+YoT9&|9TD!>-O0JT!!DQ1|0{blItxE*6w+!GQZ7l2$J@! z=LmMl?F#0EB_oyd)ecx&9JYkNN?rk9(~#yls) zoUg1KFN<+fyQojJ`pL&~mTw*CN0zjcz9m4*P;33dkl@FPq1n4-*W&U#+cmSd0nkDB zvYRX06%f}`gv+ha$?h4iFVWkL(&FRV84meI-cD!Gc&sEcA{)on>>Jb=f-5x+u$b4u z8}UAne4e8>zG(!69Q(F_z;nzFM7~Oabb4V5Vj|=)LjShV@~!*g@jtRVbp8{`u~^sM z#|BTDuy*lfBqErB{x*pylsiew>gWhg>6#R!b+|Gb--E@2Y1)Tjh+$O;MvAmD8~icz zZ6yDk(79`l9@5_<85Z9->jUMR0^+eios2KJ0={<%x*i=!)YtWWebznV0ZE+q*Zrc^=4lnavQ>~LF8)Ih8IbLBSW!Wl+P0_m7V0n0XyAtP0 zkI!QOfpZjKOSYeRbXZxAhJ3gZ`>JNOdKgrfrsPV)EG#xOsq8D23)Sf_2HOE;WoT+F z{M1w6tebFj$d$I3Aix|g!c6-)HD|kBc>}3;Ecd*tXI<>9a9yqt3s>Cxxan@)88tot zIM1dnxB2VIpZ4SP^Ybz3)bJat2!K6!8t#nUhOqV)v9?!udUC@QTKo@VXX}3w=K1o< z-1`8XTRcx%72R2AODNY7K1BWdKv@Bkh(!jh0y#y)4?CDhx|oP(v6X(Yzz0sFNCid}w(GW0Hi*0QG+81!Gq`wgp|WjvM&oK5$x}9#Wd>>rA^4>QhLz)*{AU zBG6LImjqH>VhzJT*mmnsZzQ`%_R#%lKV0M0r(Ece0%)tqta#QFV_$cB$=BXlU+kQB zXU%xGNVH&5sa@1B?Ka1OyU4b!nzx2~gy6ZVkrq)ek&*9bc)pg&aM!b}$-9WdG9h{% zXx3}ha9(*crsZZI(oLPXYkgD*HT7}JiUVD_a>`4rFX#{{rKbj;H2qdl@U zm<&;NN9ctzl;ZXcFW7XzOD{Bb7hgMBe0_ZQ1O)`LdSJX?)><9klC(&t0|WpNoY&Ko zj^zM;$^kfe<&VPDECdy8T7_&GN)_dL9h|o*D*>G!EyG&#e9jD`rxi+GcinbM6QIu>Q5)fNf>}MpsZ>@K;s=xe^tyN@~Ra4~vaLa1z zRa)3o5C>CUcH|kDpowT z^;>M|vt=|W)nDvsfgO$i7PPAkIyN8{C~tj`#-Gd) z>;kV~T%ES}v$sHG$L~r=P6}0`=zMzXvJ~|~y%F_CF)1$yrEmDmSnku!ziEifYAYwh z>JBJyx=xB5&?1a^_^o~u&55ZOPF3V>EW-occ?+UtfVm9ToasNgRvjwT3>s~rQ#J*a ztOtC-6$B&2wv#^j$kXf2XLdePFA z0zXg`?SmP#<5Ec^ZcWcTx2NH{&zM&bnJ(9}mjW1Y^{NB{6g5+(5wi}(M@(J$Ehrv2@)Af(C-SJHZ14x8M-m9fG^-MmE9SEx5b8 zySux)>&Epb?#g)iolWU6?X z_G!QbP0Ut4aig4dBVASsp@?NQhlT1sh&K3-mSkynrg5$wd{<=%{g>4uRBX;(OWvS) ztUs?Lhw`mlWhM2G=TJaq$VhE2p6}qSKSz1>zmH+$rscD|WU5cGsHEhIt7#I)@3)`m zP}4qN(lKA%W%r(K&&h?6E2eIrNzl#r*)j~%CPkr$;1=G~h$2QroSuSo-uoy(WUp7y zzQv^Hy^V7d+#L7)_w{`&lX2vb=atJc^A1&gm4Mg35 z7YPj{{h%6-*e^ZfuVlr{3yw4{GWWJfHv1iUSK$=m7u3;2tl3Tn-GsRQ2~Ftv^L57+ z;Z5-;oSvAF4MAksi+!(mV!ZVI3+L8(tF(GGlAlXGi_>cpQE} zyy)PpU>%+0e)j_M#Bi9vJzubnEm0;yr`EBvXc`FtFtcu>j68YX1k-&Y6kyGI4Ptgd zuYx0MPAwLbyN(sX+v76UPc**1{vJi!4t(cr$KQQ7 zI&BBfPv_9BiD?YhYpuSg!&=2uduUAZGn^CqIrrkPkF{e%9v|(>j`N83P1*j2wEI)zhdnCSI{{jYPLdLDGTtGD1Z+E{EX%uT^-9k3lzY=;ODGW1LM3N*x3rMaSI!`HgRxA^@3c#`S0S90I}=p9+xr* zY%5XCM&(m8@PyBS2Cj=1ab^?;udU1qZjmr0@%!-Kt#6(=WAs#Rl2)b>#F);RU>{i! zc7-)w24nht2||{S24!0Vc_onUZnoCuQrFVCxV zZ#7-^`p-T*QE>fHKrDV*-cJc8Jl>YvI{PgIXh3V`o@_}Q@rn?H)E7egnTOB878*95 zpAj72Vpsomr0lVmU*)|pBWB7)5wa=LM14o+u*+RSGGVhAUL3tf& z4SPC0ad3d!^KhA?kL@qHO`qS^cAo`VX3Ne+rPkcw;e*1 z`20{JMpHKQ11sT;smkImR$_a$!7!M6qufFBUZqMMw~vv>W3OzhrIaW?#!(i|&(u>k z8A9WsBEr6H1FpMA^|(}3pn*J!E?0>#1?I z($3N0ukXp0v-Tej+5gRx^L_G?Uisp!@a}8zY3UhU=I0So};s4MgDYdwcR=p2|%J_$Te)pm5}mjqkJhj)7!4_U?3Z@I6|8i zsWmR7rb;Xo-eA!pNR%n%AwL94Du>gim^qt811cH%7}-|5x6!r*_bt6E0*^&W3fQe1 zI!&}xv4lS8@lK&)2jhp{YA)cqL2OO#n>&ix~ zd$W6oR^T!EiL#7Ns&WaSo)s88p_^(7LN3@4HMD*t@|pkbH;?;Tx4g^pIo6e;-Zo@3 z=NK;O8TjxO<>iGf>hR{t$Q=-~F8nYo3JxRNK&mpxRMum@+u{)MaXZ54{SpOY;?R8j z1kf0Q(^f*Lj7U^i!#bVe%Dqm!U>=v>r`i|4hvKD%kt8ZLNjfDToB>N(+&WKTrpG|g z@e0)rQv4x>U&qT|`C+-?QBO=^ppQQlu5wB|K8ZCug>Wu7na(H@%rSUGI5h>G!%4hj{hNB$>k)2XzdU8sv<~ zwiA|2n?+W-y4!)FJCZ0l;j)!mh_6XfHx^K^Yk8~k_gTiH@~*4w)1}245=>`$i{%ox z$*SXX$6@_?)rz9KBV#R>oh4Dr&tw2%pL_6@1Ll^;i#3 zh$SnfTI=)(iM~phSyA3b4|@%-Nykfs|EFqc*VofNLD}T03je3gkm? z7|VI8;}8S>j&kO>w*K-pYT`}^tHCA1NtfLU#KP8yS7%?8>vM(FwkB?t?YW;qAhWeo z9~v%kv)H67n3j7R>aCv-e09#5J*bV?Dx&JlAaS3Tf^adfo2-O@-CHB9+-!W_MX8|k zKF<;Bd9@WE?5uF9y1LCtyvNY?mQ}*CA3r%*<&I8Cnf}o+qgj?-ScU_7ucIDkZR~&X&3<}eEzUHI|Ae;|L zy82rm=vBBR2baq?dzULkv1A>x~zmwJTQ!F!Te(_FY8X4ExwnZ$@jZ>>;T2m zp8Ny^c>J-RdMsNuEh-JAPjSB|taf zw=isHeVG@xQHYt%FJAxZ9npiL_=@qnSnhA&yxyc@tv*keWJRyAC9A`7MSYH($0|K% z_5CG=YX=a($-~>H!{+M3KC8p+x^p*1G#~Ptkad&}ys9t7*=#WL7v*P3_m8*h%Aa>Q z&GyF#^JCnlL+C{^zP`HZ*o9I3o-Az46}3<4y=cA zl7Um^P3d*l)D+^-^kohr=s4~6X&_>y9YCYWc9&cfp;u$X#<6@DKs13-a_bruuO_A( z!?R|H3mL!eZ$=@X)NsNRzu3Ps>{7FtmOwmqPrE(n^qMBqk3pj+s5({;gy!G~1d#%O z?ryR4op#% ziMPw+_1J#X94_Ro(iVhALmLju9>P{s2Y7O)+&*^| zvV8utnT(&*b(bcpHwG*sr(5U;!0v->YetwJ+LyN?gp8y+!WZ^20SkF)60IrIhD4NU z+=tf=?|RUf+^icB6DqB-`^j{UZib9sKmhx>o}qMbuO&CpyVA4>_l5(JdoP8J&MeVs z$MJmEKDmdPa;&GAp?%8quiV2|zGCI?6$O;5#~9x%ZhQJV1fE?b>(06x-VBbkOeUMS z$2YNAQ7f|(#I8x)6jrq8tZ5F;l_^T;oO0DmVaQDZDLk|7Dri0R*1=l&Rg}=wzcS+o zmomu?_~I_n1sD3>lg5a=|1=ps+;1JYhuiM{LVRsO1cbY4{k1(GAA64fMlx_dpICmZ z)WIc=G$N5qwJd>N!I*DS?Pd%nWc})v}YEp!`{Qx zpfczpL`ftsGhdEW5xKnYn)!32c8v=X zDmIYH6AF2a8-!WyvM_99T2ccUKHHA8jeGE*Ij}APb{mXnhQ%27v=2o)b-O1`*Hi-G zZ0&}3RvGVjIh!IkOt6+)5y30D)mJaU9zMs1#@@{Q&gz%wFz3v7W6`^=??$b}r>jWQ zn4=e(6UY!J0t%_C2CA37h!J&IfTIM>#+@j1^;{RCg&&-8Y;Jxs0%^YY)C*46EK zb&j?FkrxL4zQlZg{!2QZ?)RxDhonj=y$(jQMuub(I*I^%TE?y*+K^|&FrRnOXQI|& zk+EHkmbMrMc@RcPvMRZoz{UWdbXp8W%hiv-cWjB)19*T%1UGVmkPR^Wjc?C)1?kne z?GEAJ%#l=hT^ki^Pq01k&Avw+q7ey5tb^4UdndM{VR?it`&xe%WtbAIQfdUS$y&e| z*=@J5Z*D((%}Q|>f9dRs7w)-t8V~!8fiJKzrQM8XV9r2IakuTpSKYY23~;!sm~Uiw zz?sR#&F&8mQ+pvB7mSZsc`RnK_qJQK+^Tcs-Q`KJu3x`y&}tZR^eBMI%w9SsjeV<; zK1n#_P2bT!si9ge;Fwc+t}`le2*;hnsfN8@8E`BuSVBdqN|vn(n2jAY8s^<+aM%H= zOsuG@`=s>eZG-80_$%_9G)nthzaHERK(`z7+6m-%x=b_xp-UN@S5~Q_Z$VzytRIJh zvIoB3Q_x;ji66D`LOag=enuq{jggB}!8($RhKyYQ_01zqkpz8?&vp(H`*NNNT1NZdo@43NnFgM=Pc;RX360siX zElUk7YQJLO+A1}VF+i(tZ5mmVI?$x9Od*{s?axKyMm_pQVh}c7+mp&YA0M{8h`w(z z4rPY?4Hf15VSCDAeBPb6u67^k+fMO&bb*$`wlemUzTHlUcOzl=8uV@xdfV-BycO*x z-O~=OUCY@q(!`ZtLv%ztobScn_3s~BLf?SK?0AZI$;M!|_D8F7nackD5G2l~{RWWZkOOW{2HotqHun zr)EV|M;#vD$-Y<(=}5V>4I97o!)x33w};!F$BmSJ{DlGki0g=m+K)SL?Ns2xnmB{@ z!sNV&3$)`;Ui}K;W87+I@NnDv z?o^>PTH(OA(~5*s#GI3z3YLcFN=5!*~JE8NjlZLrPt)@ zi3vaJSX{E5Xv^|YG6B+>f|7WeDt=$9PwTh;I_=v0{C+{HGFP;#$xnj_xAw)$yLG8P z*zJe(+47((*^>0sb}Q)}|LDz18gIQ$gvvCnI2Pq-Z1qjiW+SRG@?LQ%oA+_p^(Y1W zlLw#%BaUc`n?M0Q#&dvd&->CIY^1*m4?=)IA+o62c3vmfj{Jc=T6vH0lA9TD%dF%OG>(eHqrUPwgWQgj4bf zDLr{Mcj?D&IZ6(Gi*`6^g0Pi%tv*&vOXr`yZ5tbWT$hJ-{9~>(!#aLM#|I0&JwsH& zl1vLJKQ3m-8AcX5jgb`b&s|+U5p~!RXvqKdIOT&JK3saE)l8%}T-HVIYdcA+6)kq^ z>n0xdvyk;nIJ3hbmAfqc@~zCU)*9V8l+*z3-2U`n=d~EQfTi?y7RKEbKIJJ{J_BXUgkIObMPM4ji^JP%X%6M%IH%vssZO6z`0U7ck)OzbJ^BC(P2 zFYK)rqG_F8E34@Jaoic5(?+6sl#BJ;y8KXC-8>cT4KTrD` z@$GfJnb)0R{6E35NA{?V97+(02M3pJ<}|d1mVzxWg|<_Hj5Id9#a^#`fcD< zp0-`PV`(i~2NTRPQ&mGfzM=1Um;RJ}e&xxsn+1}oscEEchuY}xyFn`3i0?%dAiih& zOWjfeU&M#(oDf#TR5)Ff_E3s$6LZsrw`9G;liQW3$+U%X{YM%s&05w(;wWCbUlHQ= zIn4E|Wh#gTuXw9&jdKqI&o4&mJ2)jn$yWY)n%7$>g5Um)A%CaChpN0@!R*P?i=ACG%lrSazuz zLRTTstE1gvpopP+FIgHOjK<1;n#as{S>9ku7n34}nE>iP3c z))H&5LT#Mr6XwoH8t{2L40L%5xXqP*v<2>jUB8DiakcdTFpartTFo~;1koZJ6#rxu zu&i7ktLL7NU;~OI7Ymd#sO2|GblO_T>{= zo*vzDU`&?01HTbg4+?ER%(6hXo|_%X6qW~9lG@kmuh}c-i}A7=ydMZC2Dd zdaGNsWM9HZKh=t|#_^?o-?w)XXl6-JscrVRE>Q*gk9HlWc`OGvAdc;&pjQyc%AYkJ zjogW?A)Z!qu(|-tn4r_dpJ%*EMlDhNX+O;v#Of)kl&4@lle#)b41~P|9LM8qA;f{-O6|hKl@;#wvl4R)lqkaW9b&k!K>vD@3Na9GZPk z7sB)Ti7r$?CUQvatvDE48kIxD&A;YD?x)e~yZa0dpw{E_bU|QR`-v(68u3>!8m*v< zhYEp<8wtl6@<1B$zIQN@$bYm07Re2na%0DLmrpWb&c(AvuwKp)B|D5l5bjtutdhB? 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

n@ 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�M%64)c{T^)E0)(eZi3t*7Z++-wq#$ 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%0D6Eyd#0JEb-}N)eTz}_)X+86uhH)wu;`H~e%rcik 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

O=d&Gbn9h0->Fvr-fJc!$d>?QT=mdDF?spoS| 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

wcjjNQ;~YkJO=G|paL=bF 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

#~PVDa^W#ms>jj?2D-%Ld~ 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

$Y4k_*+h>Sx!)+qIX8mr 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

    +j4{cTaX@S6dt0=)HvGX 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�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 z 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

    pO&K{Q(vYO?-=}qRr6>D0J>3XAa>Xt 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Ξe!Y}-fv6N`c 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

    vSz>;>Vf&|_e~D&|Q4#qbF#=k` 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

    l-~9 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]+%MQP- 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 &1X&IK3J;eqXG+%yq$|WjU+g{|0txR@rG>=X4p^ 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

    d*0pj+1HNKoW3u}+t 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

    MaQ;5KaT?cvM6%8$ba|niI}*h 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 O6rcutwvI%b4iU672*Za#4->>t`-n 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 t^xU-haIDAoE>&R|V~ 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 z0KNbK00000000000000000000000000000000000000000000000000008^}007b! B?zjK| literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.c new file mode 100755 index 00000000000..ab3ebf8a05e --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.c @@ -0,0 +1,386 @@ +//***************************************************************************** +// +//! \file w5100.c +//! \brief W5100 HAL Interface. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "w5100.h" + +#if (_WIZCHIP_ == 5100) +/** +@brief This function writes the data into W5100 registers. +*/ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + WIZCHIP.IF.SPI._write_byte(0xF0); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data) +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) ) + //M20150601 : Rename the function for integrating with ioLibrary + //WIZCHIP.IF.BUS._write_byte(AddrSel,wb); + WIZCHIP.IF.BUS._write_data(AddrSel,wb); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + + //add indirect bus + //M20150601 : Rename the function for integrating with ioLibrary + //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + WIZCHIP.IF.BUS._write_data(IDM_DR,wb); +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} +/** +@brief This function reads the value from W5100 registers. +*/ +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + WIZCHIP.IF.SPI._write_byte(0x0F); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0); + ret = WIZCHIP.IF.SPI._read_byte(); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) ) + //M20150601 : Rename the function for integrating with ioLibrary + //ret = WIZCHIP.IF.BUS._read_byte(AddrSel); + ret = WIZCHIP.IF.BUS._read_data(AddrSel); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + + //add indirect bus + //M20150601 : Rename the function for integrating with ioLibrary + //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + ret = WIZCHIP.IF.BUS._read_data(IDM_DR); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + + +/** +@brief This function writes into W5100 memory(Buffer) +*/ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); //M20150601 : Moved here. + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + for(i = 0; i < len; i++) + { + //M20160715 : Depricated "M20150601 : Remove _select() to top-side" + // CS should be controlled every SPI frames + WIZCHIP.CS._select(); + WIZCHIP.IF.SPI._write_byte(0xF0); + WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data) + //M20160715 : Depricated "M20150601 : Remove _select() to top-side" + WIZCHIP.CS._deselect(); + } +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) ) + for(i = 0; i < len; i++) + //M20150601 : Rename the function for integrating with ioLibrary + // WIZCHIP.IF.BUS._write_byte(AddrSel+i,pBuf[i]); + WIZCHIP.IF.BUS._write_data(AddrSel+i,pBuf[i]); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + //M20150601 : Rename the function for integrating with ioLibrary + /* + WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI); + WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); + */ + setMR(getMR()|MR_AI); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]); + setMR(getMR() & ~MR_AI); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!!" +#endif + + WIZCHIP.CS._deselect(); //M20150601 : Moved here. + WIZCHIP_CRITICAL_EXIT(); +} + +/** +@brief This function reads into W5100 memory(Buffer) +*/ + +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); //M20150601 : Moved here. + + #if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + for(i = 0; i < len; i++) + { + //M20160715 : Depricated "M20150601 : Remove _select() to top-side" + // CS should be controlled every SPI frames + WIZCHIP.CS._select(); + WIZCHIP.IF.SPI._write_byte(0x0F); + WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0); + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + //M20160715 : Depricated "M20150601 : Remove _select() to top-side" + WIZCHIP.CS._deselect(); + } +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) ) + for(i = 0 ; i < len; i++) + //M20150601 : Rename the function for integrating with ioLibrary + // pBuf[i] = WIZCHIP.IF.BUS._read_byte(AddrSel+i); + pBuf[i] = WIZCHIP.IF.BUS._read_data(AddrSel+i); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + //M20150601 : Rename the function for integrating with ioLibrary + /* + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI); + WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); + */ + setMR(getMR() | MR_AI); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR); + setMR(getMR() & ~MR_AI); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!!" +#endif + + WIZCHIP.CS._deselect(); //M20150601 : Moved Here. + WIZCHIP_CRITICAL_EXIT(); +} + +/////////////////////////////////// +// Socket N regsiter IO function // +/////////////////////////////////// + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +uint32_t getSn_RxBASE(uint8_t sn) +{ + int8_t i; +#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + uint32_t rxbase = _W5100_IO_BASE_ + _WIZCHIP_IO_RXBUF_; +#else + uint32_t rxbase = _WIZCHIP_IO_RXBUF_; +#endif + for(i = 0; i < sn; i++) + rxbase += getSn_RxMAX(i); + + return rxbase; +} + +uint32_t getSn_TxBASE(uint8_t sn) +{ + int8_t i; +#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + uint32_t txbase = _W5100_IO_BASE_ + _WIZCHIP_IO_TXBUF_; +#else + uint32_t txbase = _WIZCHIP_IO_TXBUF_; +#endif + for(i = 0; i < sn; i++) + txbase += getSn_TxMAX(i); + return txbase; +} + +/** +@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip. + +This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer +register. User should read upper byte first and lower byte later to get proper value. +And this function is being used for copy the data form application buffer to Transmite +buffer of the chip. It calculate the actual physical address where one has to write +the data in transmite buffer. Here also take care of the condition while it exceed +the Tx memory uper-bound of socket. + +*/ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr; + uint16_t size; + uint16_t dst_mask; + uint16_t dst_ptr; + + ptr = getSn_TX_WR(sn); + + dst_mask = ptr & getSn_TxMASK(sn); + dst_ptr = getSn_TxBASE(sn) + dst_mask; + + if (dst_mask + len > getSn_TxMAX(sn)) + { + size = getSn_TxMAX(sn) - dst_mask; + WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size); + wizdata += size; + size = len - size; + dst_ptr = getSn_TxBASE(sn); + WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size); + } + else + { + WIZCHIP_WRITE_BUF(dst_ptr, wizdata, len); + } + + ptr += len; + + setSn_TX_WR(sn, ptr); +} + + +/** +@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer. + +This function read the Rx read pointer register +and after copy the data from receive buffer update the Rx write pointer register. +User should read upper byte first and lower byte later to get proper value. +It calculate the actual physical address where one has to read +the data from Receive buffer. Here also take care of the condition while it exceed +the Rx memory uper-bound of socket. +*/ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr; + uint16_t size; + uint16_t src_mask; + uint16_t src_ptr; + + ptr = getSn_RX_RD(sn); + + src_mask = (uint32_t)ptr & getSn_RxMASK(sn); + src_ptr = (getSn_RxBASE(sn) + src_mask); + + + if( (src_mask + len) > getSn_RxMAX(sn) ) + { + size = getSn_RxMAX(sn) - src_mask; + WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size); + wizdata += size; + size = len - size; + src_ptr = getSn_RxBASE(sn); + WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, size); + } + else + { + WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, len); + } + + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr; + + ptr = getSn_RX_RD(sn); + + ptr += len; + setSn_RX_RD(sn,ptr); +} + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.h new file mode 100755 index 00000000000..3396955077f --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100/w5100.h @@ -0,0 +1,1865 @@ +//* **************************************************************************** +//! \file w5100.h +//! \brief W5100 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _W5100_H_ +#define _W5100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "wizchip_conf.h" + +/// \cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5100) +/// \endcond + +#define _WIZCHIP_SN_BASE_ (0x0400) +#define _WIZCHIP_SN_SIZE_ (0x0100) +#define _WIZCHIP_IO_TXBUF_ (0x4000) /* Internal Tx buffer address of the iinchip */ +#define _WIZCHIP_IO_RXBUF_ (0x6000) /* Internal Rx buffer address of the iinchip */ + + +#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block +#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address + +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + #define _W5100_IO_BASE_ _WIZCHIP_IO_BASE_ +#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + #define IDM_OR ((_WIZCHIP_IO_BASE + 0x0000)) + #define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0001)) + #define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0002)) + #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003)) + #define _W5100_IO_BASE_ 0x0000 +#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define _W5100_IO_BASE_ 0x0000 +#endif + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + + +//----------- defgroup -------------------------------- + +/** + * @defgroup W5100 W5100 + * @brief WHIZCHIP register defines and I/O functions of @b W5100. + * + * - @ref WIZCHIP_register_W5100 : @ref Common_register_group_W5100 and @ref Socket_register_group_W5100 + * - @ref WIZCHIP_IO_Functions_W5100 : @ref Basic_IO_function_W5100, @ref Common_register_access_function_W5100 and @ref Socket_register_group_W5100 + */ + + /** + * @defgroup WIZCHIP_register_W5100 WIZCHIP register + * @ingroup W5100 + * @brief WIZCHIP register defines register group of W5100 . + * + * - \ref Common_register_group_W5100 : Common register group W5100 + * - \ref Socket_register_group_W5100 : \c SOCKET n register group W5100 + */ + + +/** + * @defgroup WIZCHIP_IO_Functions_W5100 WIZCHIP I/O functions + * @ingroup W5100 + * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5100. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - \ref Common_register_group_W5100 access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC() + * + * - \ref Socket_register_group_W5100 access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group_W5100 Common register + * @ingroup WIZCHIP_register_W5100 + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa IR, Sn_IR, _IMR_ : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC : PPPoE. + */ + + + /** + * @defgroup Socket_register_group_W5100 Socket register + * @ingroup WIZCHIP_register_W5100 + * @brief Socket register group\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAG : Internet protocol. + * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + /** + * @defgroup Basic_IO_function_W5100 Basic I/O function + * @ingroup WIZCHIP_IO_Functions_W5100 + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function_W5100 Common register access functions + * @ingroup WIZCHIP_IO_Functions_W5100 + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function_W5100 Socket register access functions + * @ingroup WIZCHIP_IO_Functions_W5100 + * @brief These are functions to access socket registers. + */ + + //----------------------------------------------------------------------------------- + +//----------------------------- W5100 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group_W5100 + * @brief Mode Register address(R/W)\n + * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of \ref MR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    RST Reserved WOL PB PPPoE Reserved AI IND
    + * - \ref MR_RST : Reset + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_AI : Address Auto-Increment in Indirect Bus Interface + * - \ref MR_IND : Indirect Bus Interface mode + */ +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + #define MR (_WIZCHIP_IO_BASE_ + (0x0000)) // Mode +#else + #define MR (_W5100_IO_BASE_ + (0x0000)) // Mode +#endif + +/** + * @ingroup Common_register_group_W5100 + * @brief Gateway IP Register address(R/W) + * @details \ref GAR configures the default gateway address. + */ +#define GAR (_W5100_IO_BASE_ + (0x0001)) // GW Address + +/** + * @ingroup Common_register_group_W5100 + * @brief Subnet mask Register address(R/W) + * @details \ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5100_IO_BASE_ + (0x0005)) // SN Mask Address + +/** + * @ingroup Common_register_group_W5100 + * @brief Source MAC Register address(R/W) + * @details \ref SHAR configures the source hardware address. + */ +#define SHAR (_W5100_IO_BASE_ + (0x0009)) // Source Hardware Address + +/** + * @ingroup Common_register_group_W5100 + * @brief Source IP Register address(R/W) + * @details \ref SIPR configures the source IP address. + */ +#define SIPR (_W5100_IO_BASE_ + (0x000F)) // Source IP Address + +// Reserved (_W5100_IO_BASE_ + (0x0013)) +// Reserved (_W5100_IO_BASE_ + (0x0014)) + +/** + * @ingroup Common_register_group_W5100 + * @brief Interrupt Register(R/W) + * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host. + * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of \ref IR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    CONFLICT UNREACH PPPoE Reserved S3_INT S2_INT S1_INT S0_INT
    + * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_SOCK(3) : SOCKET 3 Interrupt + * - \ref IR_SOCK(2) : SOCKET 2 Interrupt + * - \ref IR_SOCK(1) : SOCKET 1 Interrupt + * - \ref IR_SOCK(0) : SOCKET 0 Interrupt + */ +#define IR (_W5100_IO_BASE_ + (0x0015)) // Interrupt + +/** + * @ingroup Common_register_group_W5100 + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR. + * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR is set, Interrupt will be issued. + */ +#define _IMR_ (_W5100_IO_BASE_ + (0x0016)) // Socket Interrupt Mask + +/** + * @ingroup Common_register_group_W5100 + * @brief Timeout register address( 1 is 100us )(R/W) + * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0or 000 + * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5100 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the \ref _RTR_ time, W5100 retransmits the packet or issues timeout. + */ +#define _RTR_ (_W5100_IO_BASE_ + (0x0017)) // Retry Time + +/** + * @ingroup Common_register_group_W5100 + * @brief Retry count register(R/W) + * @details \ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1'). + */ +#define _RCR_ (_W5100_IO_BASE_ + (0x0019)) // Retry Count +#define RMSR (_W5100_IO_BASE_ + (0x001A)) // Receicve Memory Size +#define TMSR (_W5100_IO_BASE_ + (0x001B)) // Trnasmit Memory Size + + +/** + * @ingroup Common_register_group_W5100 + * @brief PPP LCP Request Timer register in PPPoE mode(R) + * @details \ref PATR notifies authentication method that has been agreed at the connection with + * PPPoE Server. W5100 supports two types of Authentication method - PAP and CHAP. + */ +#define PATR (_W5100_IO_BASE_ + (0x001C)) + + +/** + * @ingroup Common_register_group_W5100 + * @brief PPP LCP Request Timer register in PPPoE mode(R) + * @details \ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5100_IO_BASE_ + (0x0028)) // PPP LCP RequestTimer + +/** + * @ingroup Common_register_group_W5100 + * @brief PPP LCP Magic number register in PPPoE mode(R) + * @details \ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5100_IO_BASE_ + (0x0029)) // PPP LCP Magic number + +#define UIPR0 (_W5100_IO_BASE_ + (0x002A)) +#define UPORT0 (_W5100_IO_BASE + (0x002E)) + + + +//----------------------------- W5100 Socket Registers ----------------------------- + +//--------------------------- For Backward Compatibility --------------------------- + +/** + * @ingroup Socket_register_group_W5100 + * @brief socket Mode register(R/W) + * @details \ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of \ref Sn_MR defined as the following. + * + * + * + *
    7 6 5 4 3 2 1 0
    MULTI MF ND/MC Reserved Protocol[3] Protocol[2] Protocol[1] Protocol[0]
    + * - \ref Sn_MR_MULTI : Support UDP Multicasting + * - \ref Sn_MR_MF : Support MACRAW + * - \ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - \ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - Protocol + * + * + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 0 0 0 Closed
    0 0 0 1 TCP
    0 0 1 0 UDP
    0 1 0 0 MACRAW
    + * - In case of Socket 0 + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 1 0 0 MACRAW
    0 1 0 1 PPPoE
    + * - \ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - \ref Sn_MR_UDP : UDP + * - \ref Sn_MR_TCP : TCP + * - \ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register + +/** + * @ingroup Socket_register_group_W5100 + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5100 accepts the command, the \ref Sn_CR register is automatically cleared to 0x00. + * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR. + * - \ref Sn_CR_OPEN : Initialize or open socket. + * - \ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - \ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - \ref Sn_CR_DISCON : Send closing request in TCP mode. + * - \ref Sn_CR_CLOSE : Close socket. + * - \ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - \ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - \ref Sn_CR_SEND_KEEP : Send keep alive message. + * - \ref Sn_CR_RECV : Update RX buffer pointer and receive data. + * - In case of S0_MR(P3:P0) = S0_MR_PPPoE + * + * + * + * + * + * + * + *
    Value Symbol Description
    0x23 PCON PPPoE connection begins by transmitting PPPoE discovery packet
    0x24 PDISCON Closes PPPoE connection
    0x25 PCR In each phase, it transmits REQ message.
    0x26 PCN In each phase, it transmits NAK message.
    0x27 PCJ In each phase, it transmits REJECT message.
    + */ +#define Sn_CR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register + +/** + * @ingroup Socket_register_group_W5100 + * @brief Socket interrupt register(R) + * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit \ref IR_SOCK(N) in \ref _IMR_ are set, \ref IR_SOCK(N) in \ref IR becomes '1'.\n + * In order to clear the \ref Sn_IR bit, the host should write the bit to \n + * + * + * + *
    7 6 5 4 3 2 1 0
    PRECV PFAIL PNEXT SEND_OK TIMEOUT RECV DISCON CON
    + * - \ref Sn_IR_PRECV : PPP Receive Interrupt + * - \ref Sn_IR_PFAIL : PPP Fail Interrupt + * - \ref Sn_IR_PNEXT : PPP Next Phase Interrupt + * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register + +/** + * @ingroup Socket_register_group_W5100 + * @brief Socket status register(R) + * @details \ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - \ref SOCK_CLOSED : Closed + * - \ref SOCK_INIT : Initiate state + * - \ref SOCK_LISTEN : Listen state + * - \ref SOCK_ESTABLISHED : Success to connect + * - \ref SOCK_CLOSE_WAIT : Closing state + * - \ref SOCK_UDP : UDP socket + * - \ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - \ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - \ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - \ref SOCK_FIN_WAIT : Connection state + * - \ref SOCK_CLOSING : Closing state + * - \ref SOCK_TIME_WAIT : Closing state + * - \ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register + +/** + * @ingroup Socket_register_group_W5100 + * @brief source port register(R/W) + * @details \ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered. +*/ +#define Sn_PORT(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register + +/** + * @ingroup Socket_register_group_W5100 + * @brief Peer MAC register address(R/W) + * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address + +/** + * @ingroup Socket_register_group_W5100 + * @brief Peer IP register address(R/W) + * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of TCP server before CONNECT command. + * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address + +/** + * @ingroup Socket_register_group_W5100 + * @brief Peer port register address(R/W) + * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command. + * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address + +/** + * @ingroup Socket_register_group_W5100 + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address + +/** + * @ingroup Socket_register_group_W5100 + * @brief IP Protocol(PROTO) Register(R/W) + * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is + * valid only in IPRAW mode, and ignored in other modes. + */ +#define Sn_PROTO(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode + +/** + * @ingroup Socket_register_group_W5100 + * @brief IP Type of Service(TOS) Register(R/W) + * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register + +/** + * @ingroup Socket_register_group_W5100 + * @brief IP Time to live(TTL) Register(R/W) + * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register + +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017)) +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018)) +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019)) +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A)) +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B)) +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C)) +// Reserved (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D)) + +/** + * @ingroup Socket_register_group_W5100 + * @brief Transmit free memory size register(R) + * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE. + * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register + +/** + * @ingroup Socket_register_group_W5100 + * @brief Transmit memory read pointer register address(R) + * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address + +/** + * @ingroup Socket_register_group_W5100 + * @brief Transmit memory write pointer register address(R/W) + * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address + +/** + * @ingroup Socket_register_group_W5100 + * @brief Received data size register(R) + * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between + * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD) + */ +#define Sn_RX_RSR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register + +/** + * @ingroup Socket_register_group_W5100 + * @brief Read point of Receive memory(R/W) + * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5100. + */ +#define Sn_RX_RD(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory + +/** + * @ingroup Socket_register_group_W5100 + * @brief Write point of Receive memory(R) + * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(sn) (_W5100_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory + + +//----------------------------- W5100 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 ///< reset + + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 ///< ping block + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be '1'. + */ +#define MR_PPPOE 0x08 ///< enable pppoe + +/** + * @brief Address Auto-Increment in Indirect Bus Interface + * @details 0 : Disable auto-increment \n + * 1 : Enable auto-incremente \n + * At the Indirect Bus Interface mode, if this bit is set as ��1��, the address will + * be automatically increased by 1 whenever read and write are performed. + */ +#define MR_AI 0x02 ///< auto-increment in indirect mode + +/** + * @brief Indirect Bus Interface mode + * @details 0 : Disable Indirect bus Interface mode \n + * 1 : Enable Indirect bus Interface mode \n + * If this bit is set as ��1��, Indirect Bus Interface mode is set. + */ +#define MR_IND 0x01 ///< enable indirect mode + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 ///< check ip confict + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 ///< check destination unreachable + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 ///< get the PPPoE close message + +#define IR_SOCK(sn) (0x01 << sn) ///< check socket interrupt + + +// Sn_MR values +/* Sn_MR Default values */ +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 ///< unused socket + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 ///< TCP + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 ///< UDP +#define Sn_MR_IPRAW 0x03 ///< IP LAYER RAW SOCK + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 ///< MAC LAYER RAW SOCK + +/** + * @brief PPPoE + * @details This configures the protocol mode of Socket n. + * @note PPPoE mode should be only used in Socket 0. + */ +#define Sn_MR_PPPoE 0x05 ///< PPPoE + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001).\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_. + */ +#define Sn_MR_ND 0x20 ///< No Delayed Ack(TCP) flag + +/** + * @brief Support UDP Multicasting + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1') + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MC Sn_MR_ND ///< Select IGMP version 1(0) or 2(1) + +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5100 can only receive broadcasting packet or packet sent to itself. + * When this bit is W5100 can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MF 0x40 ///< Use MAC filter +#define Sn_MR_MFEN Sn_MR_MF + + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010).\n + * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of \ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 ///< support multicating + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n + * + * + * + * + * + * + * + * + *
    \b Sn_MR (P[3:0]) \b Sn_SR
    Sn_MR_CLOSE (000) --
    Sn_MR_TCP (001) SOCK_INIT (0x13)
    Sn_MR_UDP (010) SOCK_UDP (0x22)
    S0_MR_IPRAW (011) SOCK_IPRAW (0x32)
    S0_MR_MACRAW (100) SOCK_MACRAW (0x42)
    S0_MR_PPPoE (101) SOCK_PPPoE (0x5F)
    + */ +#define Sn_CR_OPEN 0x01 ///< initialize or open socket + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).// + * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.// + * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.// + * When a 'TCP client' connection request is successfully established, + * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 ///< wait connection request in tcp mode(Server mode) + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by \ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as TCP client + */ +#define Sn_CR_CONNECT 0x04 ///< send connection request in tcp mode(Client mode) + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (Active closeor Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 ///< send closing reqeuset in tcp mode + +/** + * @brief Close socket + * @details Sn_SR is changed to \ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (\ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/** + * @brief PPPoE connection + * @details PPPoE connection begins by transmitting PPPoE discovery packet + */ +#define Sn_CR_PCON 0x23 + +/** + * @brief Closes PPPoE connection + * @details Closes PPPoE connection + */ +#define Sn_CR_PDISCON 0x24 + +/** + * @brief REQ message transmission + * @details In each phase, it transmits REQ message. + */ +#define Sn_CR_PCR 0x25 + +/** + * @brief NAK massage transmission + * @details In each phase, it transmits NAK message. + */ +#define Sn_CR_PCN 0x26 + +/** + * @brief REJECT message transmission + * @details In each phase, it transmits REJECT message. + */ +#define Sn_CR_PCJ 0x27 + +/* Sn_IR values */ +/** + * @brief PPP Receive Interrupt + * @details PPP Receive Interrupts when the option which is not supported is received. + */ +#define Sn_IR_PRECV 0x80 + +/** + * @brief PPP Fail Interrupt + * @details PPP Fail Interrupts when PAP Authentication is failed. + */ +#define Sn_IR_PFAIL 0x40 + +/** + * @brief PPP Next Phase Interrupt + * @details PPP Next Phase Interrupts when the phase is changed during ADSL connection process. + */ +#define Sn_IR_PNEXT 0x20 + +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 ///< complete sending + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 ///< assert timeout + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 ///< closed + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n + * After \ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 ///< init state + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer (TCP client).\n + * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1'). + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to \ref SOCK_ESTABLISHED. \n + * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1'). + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to \ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring \ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (\ref Sn_IR[TIMEOUT] = '1'). + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n + * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and @ref Sn_CR_OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 ///< udp socket + +/** + * @brief IP raw mode socket + * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is + * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n + * IP Packet can be transferred without a connection similar to the UDP mode. +*/ +#define SOCK_IPRAW 0x32 ///< ip raw mode socket + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n=0) and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0]) = '100' and @ref Sn_CR_OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 ///< mac raw mode socket + +/** + * @brief PPPoE mode socket + * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR + * (P3:P0)=S0_MR_PPPoE.\n + * It is temporarily used at the PPPoE +connection. + */ +#define SOCK_PPPOE 0x5F ///< pppoe socket + +// IP PROTOCOL +#define IPPROTO_IP 0 ///< Dummy for IP +#define IPPROTO_ICMP 1 ///< Control message protocol +#define IPPROTO_IGMP 2 ///< Internet group management protocol +#define IPPROTO_GGP 3 ///< GW^2 (deprecated) +#define IPPROTO_TCP 6 ///< TCP +#define IPPROTO_PUP 12 ///< PUP +#define IPPROTO_UDP 17 ///< UDP +#define IPPROTO_IDP 22 ///< XNS idp +#define IPPROTO_ND 77 ///< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 ///< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// +// +//M20150601 : uint16_t AddrSel --> uint32_t AddrSel +// +/** + * @ingroup Basic_IO_function_W5100 + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function_W5100 + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function_W5100 + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5100 + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + + +///////////////////////////////// +// Common Register IO function // +///////////////////////////////// + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define setMR(mr) WIZCHIP_WRITE(MR,mr) +#else + #define setMR(mr) (*((uint8_t*)MR) = mr) +#endif + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get @ref MR. + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define getMR() WIZCHIP_READ(MR) +#else + #define getMR() (*(uint8_t*)MR) +#endif + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set @ref GAR. + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get @ref GAR. + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set @ref SUBR. + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @note If subr is null pointer, set the backup subnet to SUBR. \n + * If subr is 0.0.0.0, back up SUBR and clear it. \n + * Otherwize, set subr to SUBR + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR,subr,4) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get @ref SUBR. + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set @ref SHAR. + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get @ref SHAR. + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set @ref SIPR. + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() +*/ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get @ref SIPR. + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set \ref IR register + * @param (uint8_t)ir Value to set \ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xA0)) +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref IR register + * @return uint8_t. Value of \ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xA0) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set \ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set \ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set \ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(_RCR_) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref RMSR register + * @sa getRMSR() + */ +#define setRMSR(rmsr) \ + WIZCHIP_WRITE(RMSR) // Receicve Memory Size + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref RMSR register + * @return uint8_t. Value of @ref RMSR register. + * @sa setRMSR() + */ + #define getRMSR() \ + WIZCHIP_READ() // Receicve Memory Size + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref TMSR register + * @sa getTMSR() + */ +#define setTMSR(rmsr) \ + WIZCHIP_WRITE(TMSR) // Receicve Memory Size + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref TMSR register + * @return uint8_t. Value of @ref TMSR register. + * @sa setTMSR() + */ + + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref PATR register + * @return uint16_t. Value to set \ref PATR register + */ +#define getPATR() \ + (((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1))) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref PPPALGO register + * @return uint8_t. Value to set \ref PPPALGO register + */ +#define getPPPALGO() \ + WIZCHIP_READ(PPPALGO) + + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set \ref PTIMER register + * @param (uint8_t)ptimer Value to set \ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Set \ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function_W5100 + * @brief Get \ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_MR register + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * @param mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_MR register + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * @return Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), ir) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + WIZCHIP_READ(Sn_IR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_PROTO register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)proto Value to set \ref Sn_PROTO + * @sa getSn_PROTO() + */ +#define setSn_PROTO(sn, proto) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_PROTO register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_PROTO. + * @sa setSn_PROTO() + */ +#define getSn_PROTO(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_RXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE + * @sa getSn_RXMEM_SIZE() + */ +#define setSn_RXMEM_SIZE(sn, rxmemsize) \ + WIZCHIP_WRITE(RMSR, (WIZCHIP_READ(RMSR) & ~(0x03 << (2*sn))) | (rxmemsize << (2*sn))) +#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_RXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_RXMEM. + * @sa setSn_RXMEM_SIZE() + */ +#define getSn_RXMEM_SIZE(sn) \ + ((WIZCHIP_READ(RMSR) & (0x03 << (2*sn))) >> (2*sn)) +#define getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_TXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE + * @sa getSn_TXMEM_SIZE() + */ +#define setSn_TXMEM_SIZE(sn, txmemsize) \ + WIZCHIP_WRITE(TMSR, (WIZCHIP_READ(TMSR) & ~(0x03 << (2*sn))) | (txmemsize << (2*sn))) +#define setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_TXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_TXMEM_SIZE. + * @sa setSn_TXMEM_SIZE() + */ +#define getSn_TXMEM_SIZE(sn) \ + ((WIZCHIP_READ(TMSR) & (0x03 << (2*sn))) >> (2*sn)) +#define getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @regurn uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR + * @sa getSn_RX_WR() + */ +#define setSn_RX_WR(sn, rxwr) { \ + WIZCHIP_WRITE(Sn_RX_WR(sn), (uint8_t)(rxwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \ + } + + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)frag Value to set \ref Sn_FRAG + * @sa getSn_FRAG() + */ +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get the max RX buffer size of socket sn + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Max buffer size + */ +#define getSn_RxMAX(sn) \ + ((uint16_t)(1 << getSn_RXMEM_SIZE(sn)) << 10) + + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get the max TX buffer size of socket sn + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Max buffer size + */ +#define getSn_TxMAX(sn) \ + ((uint16_t)(1 << getSn_TXMEM_SIZE(sn)) << 10) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get the mask of socket sn RX buffer. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Mask value + */ +#define getSn_RxMASK(sn) \ + (getSn_RxMAX(sn) - 1) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get the mask of socket sn TX buffer + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Mask value + */ +#define getSn_TxMASK(sn) \ + (getSn_TxMAX(sn) - 1) + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get the base address of socket sn RX buffer. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n RX buffer base address. + */ +uint32_t getSn_RxBASE(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5100 + * @brief Get the base address of socket sn TX buffer. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n TX buffer base address. + */ +uint32_t getSn_TxBASE(uint8_t sn); + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @ingroup Basic_IO_function_W5100 + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5100 + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5100 + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif //_W5100_H_ + + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.c new file mode 100755 index 00000000000..8583eb1412c --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.c @@ -0,0 +1,514 @@ +//***************************************************************************** +// +//! \file w5100S.c +//! \brief W5100S HAL Interface. +//! \version 1.0.0 +//! \date 2018/03/29 +//! \par Revision history +//! <2018/03/29> 1st Release +//! \author Peter +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "w5100s.h" + +#if (_WIZCHIP_ == W5100S) +/** +@brief This function writes the data into W5100S registers. +*/ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_)) + if(!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte(0xF0); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data) + } + else // burst operation + { + spi_data[0] = 0xF0; + spi_data[1] = (AddrSel & 0xFF00) >> 8; + spi_data[2] = (AddrSel & 0x00FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) ) + if(!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(0xF0); + WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data) + } + else // burst operation + { + spi_data[0] = (AddrSel & 0xFF00) >> 8; + spi_data[1] = (AddrSel & 0x00FF) >> 0; + spi_data[2] = 0xF0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + + } +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + + //add indirect bus + //M20150601 : Rename the function for integrating with ioLibrary + //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + WIZCHIP.IF.BUS._write_data(IDM_DR,wb); +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} +/** +@brief This function reads the value from W5100S registers. +*/ +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + uint8_t spi_data[3]; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_)) + if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte(0x0F); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0); + } + else + { + spi_data[0] = 0x0F; + spi_data[1] = (AddrSel & 0xFF00) >> 8; + spi_data[2] = (AddrSel & 0x00FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) ) + if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // burst operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(0x0F); + } + else + { + spi_data[0] = (AddrSel & 0xFF00) >> 8; + spi_data[1] = (AddrSel & 0x00FF) >> 0; + spi_data[2] = 0x0F + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + + //add indirect bus + //M20150601 : Rename the function for integrating with ioLibrary + //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + ret = WIZCHIP.IF.BUS._read_data(IDM_DR); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + + +/** +@brief This function writes into W5100S memory(Buffer) +*/ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint8_t spi_data[3]; + uint16_t i = 0; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); //M20150601 : Moved here. + +#if((_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_)) + + if(!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte(0xF0); + WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0); + + for(i = 0; i < len; i++) + { + WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data) + } + } + else // burst operation + { + spi_data[0] = 0xF0; + spi_data[1] = (((uint16_t)(AddrSel+i)) & 0xFF00) >> 8; + spi_data[2] = (((uint16_t)(AddrSel+i)) & 0x00FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) ) + if(!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(0xF0); + + for(i = 0; i < len; i++) + { + WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data) + } + } + else // burst operation + { + spi_data[0] = (((uint16_t)(AddrSel+i)) & 0xFF00) >> 8; + spi_data[1] = (((uint16_t)(AddrSel+i)) & 0x00FF) >> 0; + spi_data[2] = 0xF0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + //M20150601 : Rename the function for integrating with ioLibrary + /* + WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI); + WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); + */ + setMR(getMR()|MR_AI); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]); + setMR(getMR() & ~MR_AI); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!!" +#endif + + WIZCHIP.CS._deselect(); //M20150601 : Moved here. + WIZCHIP_CRITICAL_EXIT(); +} + +/** +@brief This function reads into W5100S memory(Buffer) +*/ + +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint8_t spi_data[3]; + uint16_t i = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); //M20150601 : Moved here. + +#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_) ) + if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte(0x0F); + WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0); + + for(i = 0; i < len; i++) + { + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } + } + else // burst operation + { + spi_data[0] = 0x0F; + spi_data[1] = (uint16_t)((AddrSel+i) & 0xFF00) >> 8; + spi_data[2] = (uint16_t)((AddrSel+i) & 0x00FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + + } +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) ) + if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8); + WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0); + WIZCHIP.IF.SPI._write_byte(0x0F); + + for(i = 0; i < len; i++) + { + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } + } + else // burst operation + { + spi_data[0] = (uint16_t)((AddrSel+i) & 0xFF00) >> 8; + spi_data[1] = (uint16_t)((AddrSel+i) & 0x00FF) >> 0; + spi_data[2] = 0x0F; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + //M20150601 : Rename the function for integrating with ioLibrary + /* + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI); + WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); + */ + setMR(getMR() | MR_AI); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF)); + for(i = 0 ; i < len; i++) + pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR); + setMR(getMR() & ~MR_AI); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!!" +#endif + + WIZCHIP.CS._deselect(); //M20150601 : Moved Here. + WIZCHIP_CRITICAL_EXIT(); +} + +/////////////////////////////////// +// Socket N regsiter IO function // +/////////////////////////////////// + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +uint32_t getSn_RxBASE(uint8_t sn) +{ + int8_t i; +#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + uint32_t rxbase = _W5100S_IO_BASE_ + _WIZCHIP_IO_RXBUF_; +#else + uint32_t rxbase = _WIZCHIP_IO_RXBUF_; +#endif + for(i = 0; i < sn; i++) + rxbase += getSn_RxMAX(i); + + return rxbase; +} + +uint32_t getSn_TxBASE(uint8_t sn) +{ + int8_t i; +#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + uint32_t txbase = _W5100S_IO_BASE_ + _WIZCHIP_IO_TXBUF_; +#else + uint32_t txbase = _WIZCHIP_IO_TXBUF_; +#endif + for(i = 0; i < sn; i++) + txbase += getSn_TxMAX(i); + return txbase; +} + +/** +@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip. + +This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer +register. User should read upper byte first and lower byte later to get proper value. +And this function is being used for copy the data form application buffer to Transmite +buffer of the chip. It calculate the actual physical address where one has to write +the data in transmite buffer. Here also take care of the condition while it exceed +the Tx memory uper-bound of socket. + +*/ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr; + uint16_t size; + uint16_t dst_mask; + uint16_t dst_ptr; + + ptr = getSn_TX_WR(sn); + + dst_mask = ptr & getSn_TxMASK(sn); + dst_ptr = getSn_TxBASE(sn) + dst_mask; + + if (dst_mask + len > getSn_TxMAX(sn)) + { + size = getSn_TxMAX(sn) - dst_mask; + WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size); + wizdata += size; + size = len - size; + dst_ptr = getSn_TxBASE(sn); + WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size); + } + else + { + WIZCHIP_WRITE_BUF(dst_ptr, wizdata, len); + } + + ptr += len; + + setSn_TX_WR(sn, ptr); +} + + +/** +@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer. + +This function read the Rx read pointer register +and after copy the data from receive buffer update the Rx write pointer register. +User should read upper byte first and lower byte later to get proper value. +It calculate the actual physical address where one has to read +the data from Receive buffer. Here also take care of the condition while it exceed +the Rx memory uper-bound of socket. +*/ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr; + uint16_t size; + uint16_t src_mask; + uint16_t src_ptr; + + ptr = getSn_RX_RD(sn); + + src_mask = (uint32_t)ptr & getSn_RxMASK(sn); + src_ptr = (getSn_RxBASE(sn) + src_mask); + + + if( (src_mask + len) > getSn_RxMAX(sn) ) + { + size = getSn_RxMAX(sn) - src_mask; + WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size); + wizdata += size; + size = len - size; + src_ptr = getSn_RxBASE(sn); + WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, size); + } + else + { + WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, len); + } + + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr; + + ptr = getSn_RX_RD(sn); + + ptr += len; + setSn_RX_RD(sn,ptr); +} + +void wiz_mdio_write(uint8_t PHYMDIO_regadr, uint16_t var) +{ + WIZCHIP_WRITE(PHYRAR,PHYMDIO_regadr); + WIZCHIP_WRITE(PHYDIR, (uint8_t)(var >> 8)); + WIZCHIP_WRITE(PHYDIR+1, (uint8_t)(var)); + WIZCHIP_WRITE(PHYACR, PHYACR_WRITE); + while(WIZCHIP_READ(PHYACR)); //wait for command complete +} + +uint16_t wiz_mdio_read(uint8_t PHYMDIO_regadr) +{ + WIZCHIP_WRITE(PHYRAR,PHYMDIO_regadr); + WIZCHIP_WRITE(PHYACR, PHYACR_READ); + while(WIZCHIP_READ(PHYACR)); //wait for command complete + return ((uint16_t)WIZCHIP_READ(PHYDOR) << 8) | WIZCHIP_READ(PHYDOR+1); +} + +void wiz_delay_ms(uint32_t milliseconds) +{ + uint32_t i; + for(i = 0 ; i < milliseconds ; i++) + { + //Write any values to clear the TCNTCLKR register + setTCNTCLKR(0xff); + + // Wait until counter register value reaches 10.(10 = 1ms : TCNTR is 100us tick counter register) + while(getTCNTR() < 0x0a){} + } +} + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.h new file mode 100755 index 00000000000..549e8383b32 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5100S/w5100s.h @@ -0,0 +1,3323 @@ +//* **************************************************************************** +//! \file w5100S.h +//! \brief W5100S HAL Header File. +//! \version 1.0.0 +//! \date 2018/03/29 +//! \par Revision history +//! <2018/03/29> 1st Release +//! \author Peter +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + + +#ifndef _W5100S_H_ +#define _W5100S_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "wizchip_conf.h" + +/// \cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == W5100S) +/// \endcond + +#define _WIZCHIP_SN_BASE_ (0x0400) +#define _WIZCHIP_SN_SIZE_ (0x0100) +#define _WIZCHIP_IO_TXBUF_ (0x4000) /* Internal Tx buffer address of the iinchip */ +#define _WIZCHIP_IO_RXBUF_ (0x6000) /* Internal Rx buffer address of the iinchip */ + + +#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block +#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address + +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + #define _W5100S_IO_BASE_ _WIZCHIP_IO_BASE_ +#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + #define IDM_OR ((_WIZCHIP_IO_BASE + 0x0000)) + #define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0001)) + #define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0002)) + #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003)) + #define _W5100S_IO_BASE_ 0x0000 +#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define _W5100S_IO_BASE_ 0x0000 +#endif + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + + +//----------- defgroup -------------------------------- + +/** + * @defgroup W5100S W5100S + * @brief WHIZCHIP register defines and I/O functions of @b W5100S. + * + * - @ref WIZCHIP_register_W5100S: @ref Common_register_group_W5100S and @ref Socket_register_group_W5100S + * - @ref WIZCHIP_IO_Functions_W5100S: @ref Basic_IO_function_W5100S, @ref Common_register_access_function_W5100S and @ref Special_function_W5100S + */ + + /** + * @defgroup WIZCHIP_register_W5100S WIZCHIP register + * @ingroup W5100S + * @brief WIZCHIP register defines register group of W5100S . + * + * - \ref Common_register_group_W5100S : Common register group W5100S + * - \ref Socket_register_group_W5100S : \c SOCKET n register group W5100S + */ + + +/** + * @defgroup WIZCHIP_IO_Functions_W5100S WIZCHIP I/O functions + * @ingroup W5100S + * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5100S. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF(), wiz_recv_data(), wiz_recv_ignore(), wiz_send_data() \n\n + * + * - \ref Common_register_group_W5100S access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC() + * + * - \ref Socket_register_group_W5100S access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group_W5100S Common register + * @ingroup WIZCHIP_register_W5100S + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa IR, Sn_IR, _IMR_ : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC : PPPoE. + */ + + + /** + * @defgroup Socket_register_group_W5100S Socket register + * @ingroup WIZCHIP_register_W5100S + * @brief Socket register group\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAGR : Internet protocol. + * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + /** + * @defgroup Basic_IO_function_W5100S Basic I/O function + * @ingroup WIZCHIP_IO_Functions_W5100S + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function_W5100S Common register access functions + * @ingroup WIZCHIP_IO_Functions_W5100S + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function_W5100S Socket register access functions + * @ingroup WIZCHIP_IO_Functions_W5100S + * @brief These are functions to access socket registers. + */ + + /** + * @defgroup Special_function_W5100S Special functions + * @ingroup WIZCHIP_IO_Functions_W5100S + * @brief These are special functions to access to the PHY + */ + + //----------------------------------------------------------------------------------- + +//----------------------------- W5100S Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group_W5100S + * @brief Mode Register address(R/W)\n + * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of \ref MR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    RST Reserved WOL PB PPPoE Reserved AI IND
    + * - \ref MR_RST : Reset + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_AI : Address Auto-Increment in Indirect Bus Interface + * - \ref MR_IND : Indirect Bus Interface mode + */ +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + #define MR (_WIZCHIP_IO_BASE_ + (0x0000)) // Mode +#else + #define MR (_W5100S_IO_BASE_ + (0x0000)) // Mode +#endif + +/** + * @ingroup Common_register_group_W5100S + * @brief Gateway IP Register address(R/W) + * @details \ref GAR configures the default gateway address. + */ +#define GAR (_W5100S_IO_BASE_ + (0x0001)) // GW Address + +/** + * @ingroup Common_register_group_W5100S + * @brief Subnet mask Register address(R/W) + * @details \ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5100S_IO_BASE_ + (0x0005)) // SN Mask Address + +/** + * @ingroup Common_register_group_W5100S + * @brief Source MAC Register address(R/W) + * @details \ref SHAR configures the source hardware address. + */ +#define SHAR (_W5100S_IO_BASE_ + (0x0009)) // Source Hardware Address + +/** + * @ingroup Common_register_group_W5100S + * @brief Source IP Register address(R/W) + * @details \ref SIPR configures the source IP address. + */ +#define SIPR (_W5100S_IO_BASE_ + (0x000F)) // Source IP Address + +// Reserved (_W5100S_IO_BASE_ + (0x0013)) +// Reserved (_W5100S_IO_BASE_ + (0x0014)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Interrupt Register(R/W) + * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host. + * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of \ref IR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    CONFLICT UNREACH PPPoE Reserved S3_INT S2_INT S1_INT S0_INT
    + * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_SOCK(3) : SOCKET 3 Interrupt + * - \ref IR_SOCK(2) : SOCKET 2 Interrupt + * - \ref IR_SOCK(1) : SOCKET 1 Interrupt + * - \ref IR_SOCK(0) : SOCKET 0 Interrupt + */ +#define IR (_W5100S_IO_BASE_ + (0x0015)) // Interrupt + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR. + * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR is set, Interrupt will be issued. + */ +#define _IMR_ (_W5100S_IO_BASE_ + (0x0016)) // Socket Interrupt Mask + +/** + * @ingroup Common_register_group_W5100S + * @brief Timeout register address( 1 is 100us )(R/W) + * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0or 000 + * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5100S waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the \ref _RTR_ time, W5100S retransmits the packet or issues timeout. + */ +#define _RTR_ (_W5100S_IO_BASE_ + (0x0017)) // Retry Time + +/** + * @ingroup Common_register_group_W5100S + * @brief Retry count register(R/W) + * @details \ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1'). + */ +#define _RCR_ (_W5100S_IO_BASE_ + (0x0019)) // Retry Count + +/** + * @ingroup Common_register_group_W5100S + * @brief Receive Memory Size Register + * @details \ref RMSR register configures RX bufffer Size of the SOCKET + * The sum of the RX buffers can not exceed 8kB. + * + * + * + *
    7 6 5 4 3 2 1 0
    S3-1 S3-0 S2-1 S2-0 S1-1 S1-0 S0-1 S0-0
    + * + * + * + * + * + * + *
    Memory SizeSn-1Sn-0
    1KB00
    2KB01
    4KB10
    8KB11
    + */ +#define RMSR (_W5100S_IO_BASE_ + (0x001A)) // Receive Memory Size + +/** + * @ingroup Common_register_group_W5100S + * @brief Transmit Memory Size Register + * @details \ref TMSR register configures TX bufffer Size of the SOCKET + * The sum of the TX buffers can not exceed 8kB. + * + * + * + *
    7 6 5 4 3 2 1 0
    S3-1 S3-0 S2-1 S2-0 S1-1 S1-0 S0-1 S0-0
    + * + * + * + * + * + * + *
    Memory SizeSn-1Sn-0
    1KB00
    2KB01
    4KB10
    8KB11
    + */ +#define TMSR (_W5100S_IO_BASE_ + (0x001B)) // Transmit Memory Size + +/** + * @ingroup Common_register_group_W5100S + * @brief Interrupt register 2 + * @details \ref IR2 indicates the interrupt status. + * Each bit of IR2 will be still until the bit will be written to by the host. + * + * + * + *
    7:1 0
    Reserved WOL
    + * - \ref IR2_WOL : WOL MAGIC PACKET Interrupt Mask + */ +#define IR2 (_W5100S_IO_BASE_ + (0x0020)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Interrupt mask register 2 + * @details \ref IMR2 Each bit of IMR2 corresponds to each bit of IR2. + * When a bit of IMR2 is and the corresponding bit of IR2 is set, Interrupt will be issued. + */ +#define IMR2 (_W5100S_IO_BASE_ + (0x0021)) + + +/** + * @ingroup Common_register_group_W5100S + * @brief PPP LCP Request Timer register in PPPoE mode(R) + * @details \ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5100S_IO_BASE_ + (0x0028)) // PPP LCP RequestTimer + +/** + * @ingroup Common_register_group_W5100S + * @brief PPP LCP Magic number register in PPPoE mode(R) + * @details \ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5100S_IO_BASE_ + (0x0029)) // PPP LCP Magic number + +/** + * @ingroup Common_register_group_W5100S + * @brief Unreachable IP address register + * @details \ref + */ +#define UIPR (_W5100S_IO_BASE_ + (0x002A)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Unreachable Port register + * @details \ref + */ +#define UPORTR (_W5100S_IO_BASE_ + (0x002E)) + +/* register for W5100S only */ + +/*------------------------------------------ Common registers ------------------------------------------*/ + +/** + * @ingroup Common_register_group_W5100S + * @brief MR2 Mode register 2 + * @details \reg + */ +#define MR2 (_W5100S_IO_BASE_ + (0x0030)) + + +/** + * @ingroup Common_register_group_W5100S + * @brief Destination Hardware address in PPPoE + * @details \reg + */ +#define PHAR (_W5100S_IO_BASE_ + (0x0032)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Session ID in PPPoE + * @details \reg + */ +#define PSIDR (_W5100S_IO_BASE_ + (0x0038)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Maximum receive Unit in PPPoE + * @details \reg + */ +#define PMRUR (_W5100S_IO_BASE_ + (0x003A)) + + +/*------------------------------------------ PHY registers ------------------------------------------*/ + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY status register + * @details \reg + */ +#define PHYSR (_W5100S_IO_BASE_ + (0x003C)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY status register(hidden) + * @details \reg + */ +#define PHYSR1 (_W5100S_IO_BASE_ + (0x003D)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Address value + * @details \reg + */ +#define PHYAR (_W5100S_IO_BASE_ + (0x003E)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Register address + * @details \reg + */ +#define PHYRAR (_W5100S_IO_BASE_ + (0x003F)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Data input register + * @details \reg + */ +#define PHYDIR (_W5100S_IO_BASE_ + (0x0040)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY data output register + * @details \reg + */ +#define PHYDOR (_W5100S_IO_BASE_ + (0x0042)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Action register + * @details \reg + */ +#define PHYACR (_W5100S_IO_BASE_ + (0x0044)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Division register + * @details \reg + */ +#define PHYDIVR (_W5100S_IO_BASE_ + (0x0045)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Control register 0 + * @details \reg + */ +#define PHYCR0 (_W5100S_IO_BASE_ + (0x0046)) +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Control register 1 + * @details \reg + */ +#define PHYCR1 (_W5100S_IO_BASE_ + (0x0047)) + +/*------------------------------------------ Socket Less registers ------------------------------------------*/ + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less control register + * @details \reg + */ +#define SLCR (_W5100S_IO_BASE_ + (0x004C)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less retry time register + * @details \reg + */ +#define SLRTR (_W5100S_IO_BASE_ + (0x004D)) + + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less retry count register + * @details \reg + */ +#define SLRCR (_W5100S_IO_BASE_ + (0x004F)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less peer IP address register + * @details \reg + */ +#define SLPIPR (_W5100S_IO_BASE_ + (0x0050)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less peer hardware address register + * @details \reg + */ +#define SLPHAR (_W5100S_IO_BASE_ + (0x0054)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Ping sequence number register + * @details \reg + */ +#define PINGSEQR (_W5100S_IO_BASE_ + (0x005A)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Ping ID register + * @details \reg + */ +#define PINGIDR (_W5100S_IO_BASE_ + (0x005C)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less interrupt mask register + * @details \reg + */ +#define SLIMR (_W5100S_IO_BASE_ + (0x005E)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Socket-less interrupt register + * @details \reg + */ +#define SLIR (_W5100S_IO_BASE_ + (0x005F)) + +/** + * @ingroup Common_register_group_W5100S + * @brief DBGOUT(hidden) + * @details \reg + */ +#define DBGOUT (_W5100S_IO_BASE_ + (0x0060)) + +/** + * @ingroup Common_register_group_W5100S + * @brief NICMAXCOLR(hidden) + * @details \reg + */ +#define NICMAXCOLR (_W5100S_IO_BASE_ + (0x0063)) +/*------------------------------------------ CFG registers ------------------------------------------*/ + +/** + * @ingroup Common_register_group_W5100S + * @brief Chip Configuration locking register + * @details \reg + */ +#define CHIPLCKR (_W5100S_IO_BASE_ + (0x0070)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Network Configuration locking register + * @details \reg + */ +#define NETLCKR (_W5100S_IO_BASE_ + (0x0071)) + +/** + * @ingroup Common_register_group_W5100S + * @brief PHY Configuration locking register + * @details \reg + */ +#define PHYLCKR (_W5100S_IO_BASE_ + (0x0072)) + +/** + * @ingroup Common_register_group_W5100S + * @brief version register + * @details \reg + */ +#define VERR (_W5100S_IO_BASE_ + (0x0080)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Core 100us Counter register + * @details \reg + */ +#define TCNTR (_W5100S_IO_BASE_ + (0x0082)) + +/** + * @ingroup Common_register_group_W5100S + * @brief Core 100us Counter clear register + * @details \reg + */ +#define TCNTCLKR (_W5100S_IO_BASE_ + (0x0088)) + +//----------------------------- W5100S Socket Registers ----------------------------- + +//--------------------------- For Backward Compatibility --------------------------- + +/** + * @ingroup Socket_register_group_W5100S + * @brief socket Mode register(R/W) + * @details \ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of \ref Sn_MR defined as the following. + * + * + * + *
    7 6 5 4 3 2 1 0
    MULTI MF ND/MC Reserved Protocol[3] Protocol[2] Protocol[1] Protocol[0]
    + * - \ref Sn_MR_MULTI : Support UDP Multicasting + * - \ref Sn_MR_MF : Support MACRAW + * - \ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - \ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - Protocol + * + * + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 0 0 0 Closed
    0 0 0 1 TCP
    0 0 1 0 UDP
    0 1 0 0 MACRAW
    + * - In case of Socket 0 + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 1 0 0 MACRAW
    0 1 0 1 PPPoE
    + * - \ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - \ref Sn_MR_UDP : UDP + * - \ref Sn_MR_TCP : TCP + * - \ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5100S accepts the command, the \ref Sn_CR register is automatically cleared to 0x00. + * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR. + * - \ref Sn_CR_OPEN : Initialize or open socket. + * - \ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - \ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - \ref Sn_CR_DISCON : Send closing request in TCP mode. + * - \ref Sn_CR_CLOSE : Close socket. + * - \ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - \ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - \ref Sn_CR_SEND_KEEP : Send keep alive message. + * - \ref Sn_CR_RECV : Update RX buffer pointer and receive data. + * - In case of S0_MR(P3:P0) = S0_MR_PPPoE + * + * + * + * + * + * + * + *
    Value Symbol Description
    0x23 PCON PPPoE connection begins by transmitting PPPoE discovery packet
    0x24 PDISCON Closes PPPoE connection
    0x25 PCR In each phase, it transmits REQ message.
    0x26 PCN In each phase, it transmits NAK message.
    0x27 PCJ In each phase, it transmits REJECT message.
    + */ +#define Sn_CR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket interrupt register(R) + * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit \ref IR_SOCK(N) in \ref _IMR_ are set, \ref IR_SOCK(N) in \ref IR becomes '1'.\n + * In order to clear the \ref Sn_IR bit, the host should write the bit to \n + * + * + * + *
    7 6 5 4 3 2 1 0
    PRECV PFAIL PNEXT SEND_OK TIMEOUT RECV DISCON CON
    + * - \ref Sn_IR_PRECV : PPP Receive Interrupt + * - \ref Sn_IR_PFAIL : PPP Fail Interrupt + * - \ref Sn_IR_PNEXT : PPP Next Phase Interrupt + * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket status register(R) + * @details \ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - \ref SOCK_CLOSED : Closed + * - \ref SOCK_INIT : Initiate state + * - \ref SOCK_LISTEN : Listen state + * - \ref SOCK_ESTABLISHED : Success to connect + * - \ref SOCK_CLOSE_WAIT : Closing state + * - \ref SOCK_UDP : UDP socket + * - \ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - \ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - \ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - \ref SOCK_FIN_WAIT : Connection state + * - \ref SOCK_CLOSING : Closing state + * - \ref SOCK_TIME_WAIT : Closing state + * - \ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register + +/** + * @ingroup Socket_register_group_W5100S + * @brief source port register(R/W) + * @details \ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered. +*/ +#define Sn_PORT(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register + +/** + * @ingroup Socket_register_group_W5100S + * @brief Peer MAC register address(R/W) + * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address + +/** + * @ingroup Socket_register_group_W5100S + * @brief Peer IP register address(R/W) + * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of TCP server before CONNECT command. + * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address + +/** + * @ingroup Socket_register_group_W5100S + * @brief Peer port register address(R/W) + * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command. + * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address + +/** + * @ingroup Socket_register_group_W5100S + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address + +/** + * @ingroup Socket_register_group_W5100S + * @brief IP Protocol(PROTO) Register(R/W) + * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is + * valid only in IPRAW mode, and ignored in other modes. + */ +#define Sn_PROTO(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode + +/** + * @ingroup Socket_register_group_W5100S + * @brief IP Type of Service(TOS) Register(R/W) + * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register + +/** + * @ingroup Socket_register_group_W5100S + * @brief IP Time to live(TTL) Register(R/W) + * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register + +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017)) +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018)) +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019)) +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A)) +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B)) +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C)) +// Reserved (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D)) + + + +/** + * @ingroup Socket_register_group_W5100S + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4 and 8Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 8Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXBUF_SIZE(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001E)) + +/** + * @ingroup Socket_register_group_W5100S + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4 and 8Kbytes. + * If a different size is configured, the data cannot be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 8Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001F)) + + +/** + * @ingroup Socket_register_group_W5100S + * @brief Transmit free memory size register(R) + * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE. + * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register + +/** + * @ingroup Socket_register_group_W5100S + * @brief Transmit memory read pointer register address(R) + * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address + +/** + * @ingroup Socket_register_group_W5100S + * @brief Transmit memory write pointer register address(R/W) + * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address + +/** + * @ingroup Socket_register_group_W5100S + * @brief Received data size register(R) + * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between + * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD) + */ +#define Sn_RX_RSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register + +/** + * @ingroup Socket_register_group_W5100S + * @brief Read point of Receive memory(R/W) + * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5100S. + */ +#define Sn_RX_RD(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory + +/** + * @ingroup Socket_register_group_W5100S + * @brief Write point of Receive memory(R) + * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory + + +//todo +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket interrupt mask register + * @details Register address to configure the interrupt mask of the socket + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * + */ +#define Sn_IMR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002C)) + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket fragment field register + * @details Register to configure the Fragment field of IP Header + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + */ +#define Sn_FRAGR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002D)) // and +1 + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket Mode register 2 + * @details Register to set mode 2 + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + */ +#define Sn_MR2(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002F)) + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket n Keep Alive Timer Register + * @details Register to set the transmission period of keep alive packet. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + */ +#define Sn_KPALVTR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0030)) + +/** todo delete + * @ingroup Socket_register_group_W5100S + * @brief Socket n Timer Status Register + * @details + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + */ +//#define Sn_TSR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0031)) + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket n Retry Time-value Register + * @details Register to set the retry time value + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + */ +#define Sn_RTR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0032)) + +/** + * @ingroup Socket_register_group_W5100S + * @brief Socket n Retry Count-value Register + * @details Register to set the retry count value + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + */ +#define Sn_RCR(sn) (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0034)) + + +/*----------------------------- W5100S Register values -----------------------------*/ + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 ///< reset + + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 ///< ping block + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be '1'. + */ +#define MR_PPPOE 0x08 ///< enable pppoe + +/** + * @brief Address Auto-Increment in Indirect Bus Interface + * @details 0 : Disable auto-increment \n + * 1 : Enable auto-incremente \n + * At the Indirect Bus Interface mode, if this bit is set as the address will + * be automatically increased by 1 whenever read and write are performed. + */ +#define MR_AI 0x02 ///< auto-increment in indirect mode + +/** + * @brief Indirect Bus Interface mode + * @details 0 : Disable Indirect bus Interface mode \n + * 1 : Enable Indirect bus Interface mode \n + * If this bit is set as Indirect Bus Interface mode is set. + */ +#define MR_IND 0x01 ///< enable indirect mode + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 ///< check ip confict + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 ///< check destination unreachable + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 ///< get the PPPoE close message + +/** + * @brief Socket interrupt bit + * @details Indicates whether each socket interrupt has occured. + */ +#define IR_SOCK(sn) (0x01 << sn) ///< check socket interrupt + +/** + * @brief IP conflict interrupt mask bit + * @details If this bit is set, IP conflict interrupt is enabled. + */ +#define IMR_CONFLICT 0x80 + +/** + * @brief Destination port unreachable interrupt mask bit + * @details If this bit is set, destination port unreachable interrupt is enabled. + */ +#define IMR_UNREACH 0x40 + +/** + * @brief PADT/LCPT interrupt mask bit(PPPoE) + * @details If this bit is set, PADT/LCPT interrupt is enabled. + */ +#define IMR_PPPoE 0x20 + +/** + * @brief Socket interrupt mask bit + * @details If this bit is set, each socket interrupt is enabled. + */ +#define IMR_SOCK(sn) (0x01 << sn) + +/** + * @brief Socket-less command register bit + * @details ARP command + */ +#define SLCMD_ARP (1<<1) + +/** + * @brief Socket-less command register bit + * @details ARP command + */ +#define SLCMD_PING (1<<0) + +/** + * @brief Socket-less command interrupt and interrupt mask register bit + * @details Request command time out interrupt and interrupt mask + */ +#define SLIR_TIMEOUT (1<<2) + +/** +* @brief Socket less command interrupt and interrupt mask register bit +* @details Socket less command ARP interrupt and interrupt mask +*/ +#define SLIR_ARP (1<<1) + +/** +* @brief Socket less command interrupt and interrupt mask register bit +* @details Socket less command PING interrupt and interruptmask +*/ +#define SLIR_PING (1<<0) + + + +// Sn_MR values +/* Sn_MR Default values */ +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 ///< unused socket + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 ///< TCP + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 ///< UDP +#define Sn_MR_IPRAW 0x03 ///< IP LAYER RAW SOCK + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 ///< MAC LAYER RAW SOCK + +/** + * @brief PPPoE + * @details This configures the protocol mode of Socket n. + * @note PPPoE mode should be only used in Socket 0. + */ +#define Sn_MR_PPPoE 0x05 ///< PPPoE + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001).\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_. + */ +#define Sn_MR_ND 0x20 ///< No Delayed Ack(TCP) flag + +/** + * @brief Support UDP Multicasting + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1') + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MC Sn_MR_ND ///< Select IGMP version 1(0) or 2(1) + +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5100S can only receive broadcasting packet or packet sent to itself. + * When this bit is W5100S can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MF 0x40 ///< Use MAC filter +#define Sn_MR_MFEN Sn_MR_MF + + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010).\n + * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of \ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 ///< support multicating + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n + * + * + * + * + * + * + * + * + *
    \b Sn_MR (P[3:0]) \b Sn_SR
    Sn_MR_CLOSE (000) --
    Sn_MR_TCP (001) SOCK_INIT (0x13)
    Sn_MR_UDP (010) SOCK_UDP (0x22)
    S0_MR_IPRAW (011) SOCK_IPRAW (0x32)
    S0_MR_MACRAW (100) SOCK_MACRAW (0x42)
    S0_MR_PPPoE (101) SOCK_PPPoE (0x5F)
    + */ +#define Sn_CR_OPEN 0x01 ///< initialize or open socket + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).// + * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.// + * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.// + * When a 'TCP client' connection request is successfully established, + * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 ///< wait connection request in tcp mode(Server mode) + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by \ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as TCP client + */ +#define Sn_CR_CONNECT 0x04 ///< send connection request in tcp mode(Client mode) + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (Active closeor Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 ///< send closing reqeuset in tcp mode + +/** + * @brief Close socket + * @details Sn_SR is changed to \ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (\ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/** + * @brief + * @details + */ +#define Sn_CR_IGMP_JOIN 0x23 + +/** + * @brief + * @details + */ +#define Sn_CR_IGMP_LEAVE 0x24 + + +/* Sn_IR values */ + +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 ///< complete sending + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 ///< assert timeout + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 ///< closed + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n + * After \ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 ///< init state + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer (TCP client).\n + * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1'). + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to \ref SOCK_ESTABLISHED. \n + * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1'). + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to \ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring \ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (\ref Sn_IR[TIMEOUT] = '1'). + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n + * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and @ref Sn_CR_OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 ///< udp socket + +/** + * @brief IP raw mode socket + * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is + * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n + * IP Packet can be transferred without a connection similar to the UDP mode. +*/ +#define SOCK_IPRAW 0x32 ///< ip raw mode socket + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n=0) and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0]) = '100' and @ref Sn_CR_OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 ///< mac raw mode socket + +/** + * @brief PPPoE mode socket + * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR + * (P3:P0)=S0_MR_PPPoE.\n + * It is temporarily used at the PPPoE +connection. + */ +#define SOCK_PPPOE 0x5F ///< pppoe socket + +// IP PROTOCOL +#define IPPROTO_IP 0 ///< Dummy for IP +#define IPPROTO_ICMP 1 ///< Control message protocol +#define IPPROTO_IGMP 2 ///< Internet group management protocol +#define IPPROTO_GGP 3 ///< GW^2 (deprecated) +#define IPPROTO_TCP 6 ///< TCP +#define IPPROTO_PUP 12 ///< PUP +#define IPPROTO_UDP 17 ///< UDP +#define IPPROTO_IDP 22 ///< XNS idp +#define IPPROTO_ND 77 ///< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 ///< Raw IP packet + + + +/*----------------------------- W5100S !!Only!! Register values -----------------------------*/ + +//todo +/* MODE2 register values */ + +/** + * @brief Clock select bit + * @details With this bit, system clock can be selected to be 25Mhz or 100Mhz + * 1: 25Mhz + * 0: 100Mhz (default) + */ +#define MR2_CLKSEL (1<<7) + +/** + * @brief Interrupt pin enable bit + * @details This bit enables interrupt. + * 1: Enable interrupt + * 0: Disable interrupt + */ +#define MR2_G_IEN (1<<6) + + +/** + * @brief No TCP Reset Packet send + * @details This bit prevents sending reset packet. + * 1: Block TCP reset packet send + * 0: TCP Reset packet send + */ +#define MR2_NOTCPRST (1<<5) + +/** + * @brief Unreachable Packet Send Block bit + * @details This bit prevents sending Destination Port Unreachable Packet. + * 1: Block Destination Port Unreachable Packet Send + * 0: Destination Port Unreachable Packet Send + */ +#define MR2_UDPURB (1<<4) + +/** + * @brief Wake On LAN + * @details This bit enables WOL packet to be received. + * 1: WOL packet can be received. + * 0: WOL packet cannot be received. + */ +#define MR2_WOL (1<<3) + +/**todo + * @brief MACRAW No Size Check + * @details + */ +#define MR2_MNOSCHK (1<<2) + +/** + * @brief UDP force ARP + * @details This bit can enables to force ARP for each send command. + * 1: UDP Force ARP Enable + * 0: UDP Force ARP Disable. + * + */ +#define MR2_UDPFARP (1<<1) + +/**todo + * @brief Skip SRC Hardware Address + * @details This bit can enables to receive without checking the hardware address of the peer. + * 1: + */ +#define MR2_SSRCHA (1<<0) + + + +/* Common interrupt register 2 values */ + +/**todo + * @brief magic packet + * @details + */ +#define IR2_MGC (1<<1) + +/**todo + * @brief Magic packet interrupt mask bit + * @details If this bit is set, each socket interrupt is enabled. + */ +#define IMR2_MGC (1<<1) + +/**todo + * @brief + * @details + */ +//#define IR2_MGD (1<<1) /* Reserved */ + + +/* PHY status register 0 values */ + +/**todo + * @brief Ethernet CABLE OFF Signal + * @details + */ +#define PHYSR_CABOFF (1<<7) + +/**todo + * @brief + * @details + */ +#define PHYSR_MD2 (1<<5) + +/**todo + * @brief + * @details + */ +#define PHYSR_MD1 (1<<4) + +/**todo + * @brief + * @details + */ +#define PHYSR_MD0 (1<<3) + +/**todo + * @brief + * @details + */ +#define PHYSR_DUP (1<<2) + +/**todo + * @brief + * @details + */ +#define PHYSR_SPD (1<<1) + +/**todo + * @brief LINKDONE register + * @details If 1 Linked successfully, if 0 no link + */ +#define PHYSR_LNK (1<<0) + + +/* PHY status register 10 values */ + +/** + * @brieftodo + * @details + */ +#define PHYSR1_RXPG (1<<2) + +/** + * @brieftodo + * @details + */ +#define PHYSR1_LPI (1<<1) + +/** + * @brieftodo + * @details + */ +#define PHYSR1_CLDN (1<<0) + +#define PHYCR_AUTONEGO_ENABLE (0<<2) +#define PHYCR_AUTONEGO_DISABLE (1<<2) + +#define PHYCR_SPD_10 (1<<1) +#define PHYCR_SPD_100 (0<<1) + +#define PHYCR_HALF_DUP (1<<0) +#define PHYCR_FULL_DUP (0<<0) + +#define PHYCR1_RST (0<<0) + +#define PHYCR1_PWDN_ENABLE (1<<5) +#define PHYCR1_PWDN_DISABLE (0<<5) + + +/* Socket n MODE register 2 values */ + +/** + * @brief Broadcast Blocking bit in MACRAW mode + * @details In MACRAW mode, this bit is set to ????to block the broadcast packet. + */ +#define Sn_MR2_MBBLK (1<<6) + +/** + * @brief Multicast Blocking bit in MACRAW mode + * @details In MACRAW mode, this bit is set to ????to block the multicast packet. + */ +#define Sn_MR2_MMBLK (1<<5) + +/** + * @brief IPv6 packet Blocking bit in MACRAW mode + * @details In MACRAW mode, this bit is set to ????to block the IPv6 packet. + */ +#define Sn_MR2_IPV6BLK (1<<4) + + +/** + * @brief Broadcast Blocking bit in UDP mode + * @details In UDP mode, this bit is set to ????to block the broadcast packet. + */ +#define Sn_MR2_UBBLK (1<<1) + + +/** + * @brief TCP Force PSH bit + * @details When the SOCKET transmits data in TCP mode, PSH Flag is set to all packets. + */ +#define Sn_MR2_FPSH Sn_MR2_UBBLK + +/** + * @brief Unicast Blocking bit in UDP mode + * @details In UDP mode, this bit is set to ????to block the Unicast packet. + */ +#define Sn_MR2_UUBLK (1<<0) + +/*----------------------------For PHY Control-------------------------------*/ + +/********************/ +/* Register Address */ +/********************/ + +//Basic mode control register, basic register +#define PHYMDIO_BMCR 0x00 + +//Basic mode status register, basic register +#define PHYMDIO_BMSR 0x01 + +//--------------------------------------Not used-------------------------------------------// +////PHY identifier register 1, extended register +//#define PHY_IDR1 0x02 //not used +// +////PHY identifier register 2, extended register +//#define PHY_IDR2 0x03 //not used +// +////Auto-negotiation advertisement register, extended register +//#define PHY_ANAR 0x04 //not used +// +////Auto-negotiation link partner ability register, extended register +//#define PHY_ANLPAR 0x05 //not used +// +////Auto-negotiation expansion register, extended register +//#define PHY_ANER 0x06 //not used +// +////Auto-negotiation next page transmit +//#define PHY_ANNP 0x07 //not used +// +////Auto-negotiation link partner of the next page receive +//#define PHY_ANLPNP 0x08 //not used +// +////MMD access control register +//#define PHY_REGCR 0x09 //not used +// +////MMD access address data register +//#define PHY_ADDAR 0x0e //not used +//--------------------------------------Not used-------------------------------------------// + +/********************/ +/* Bit definitions */ +/********************/ + +//For BMCR register +#define BMCR_RESET (1<<15) +#define BMCR_MLOOPBACK (1<<14) +#define BMCR_SPEED (1<<13) +#define BMCR_AUTONEGO (1<<12) +#define BMCR_PWDN (1<<11) +#define BMCR_ISOLATE (1<<10) +#define BMCR_RSTNEGO (1<<9) +#define BMCR_DUP (1<<8) +#define BMCR_COLTEST (1<<7) + +//For BMSR register +#define BMSR_AUTONEGO_COMPL (1<<5) +#define BMSR_REMOTE_FAULT (1<<4) +#define BMSR_LINK_STATUS (1<<2) +#define BMSR_JAB_DETECT (1<<1) +#define EXTENDED_CAPA (1<<0) + +//--------------------------------------Not used-------------------------------------------// +////For ANAR register +//#define ANAR_NP (1<<15) +//#define ANAR_ACK (1<<14) +//#define ANAR_RF (1<<13) +//#define ANAR_ASM (3<<10) +//#define ANAR_T4 (1<<9) +//#define ANAR_TX_FD (1<<8) +//#define ANAR_TX_HD (1<<7) +//#define ANAR_10_FD (1<<6) +//#define ANAR_10_HD (1<<5) +//#define ANAR_SELECTOR (0x1F<<0) +// +////For ANAR register +//#define ANLPAR_NP (1<<15) +//#define ANLPAR_ACK (1<<14) +//#define ANLPAR_RF (1<<13) +//#define ANLPAR_LP_DIR (1<<11) +//#define ANLPAR_PAUSE (1<<10) +//#define ANLPAR_T4 (1<<9) +//#define ANLPAR_TX_FD (1<<8) +//#define ANLPAR_TX_HD (1<<7) +//#define ANLPAR_10_FD (1<<6) +//#define ANLPAR_10_HD (1<<5) +//#define ANLPAR_SELECTOR (0x1F<<0) + +/**/ +/* MDIO register*/ +//PCS_CTL_1 | PCS control 1 register +//PCS_STS_1 | PCS status 1 register +//EEE_ABILITY | EEE capability register +//WAKE_ER_CNTR | EEE wake error counter +//EEE_ADVR | EEE Advertisement register +//EEE_LPAR | EEE link partner ability register + +//--------------------------------------Not used-------------------------------------------// + +/********************/ +/*Functions for PHY */ +/********************/ +//todo move this definition to bit area +#define PHYACR_READ 0x02 +#define PHYACR_WRITE 0x01 + + + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// +// +//M20150601 : uint16_t AddrSel --> uint32_t AddrSel +// +/** + * @ingroup Basic_IO_function_W5100S + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function_W5100S + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function_W5100S + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5100S + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + + +///////////////////////////////// +// Common Register IO function // +///////////////////////////////// + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define setMR(mr) WIZCHIP_WRITE(MR,mr) +#else + #define setMR(mr) (*((uint8_t*)MR) = mr) +#endif + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get @ref MR. + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define getMR() WIZCHIP_READ(MR) +#else + #define getMR() (*(uint8_t*)MR) +#endif + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set @ref GAR. + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get @ref GAR. + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set @ref SUBR. + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @note If subr is null pointer, set the backup subnet to SUBR. \n + * If subr is 0.0.0.0, back up SUBR and clear it. \n + * Otherwize, set subr to SUBR + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR,subr,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get @ref SUBR. + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set @ref SHAR. + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get @ref SHAR. + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set @ref SIPR. + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() +*/ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get @ref SIPR. + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref IR register + * @param (uint8_t)ir Value to set \ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xE0)) //peter 2016.11.07 unreachable interrupt bit added + //WIZCHIP_WRITE(IR, (ir & 0xA0)) +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref IR register + * @return uint8_t. Value of \ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xE0) //peter 2016.11.07 unreachable interrupt bit added + //(WIZCHIP_READ(IR) & 0xA0) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(_RCR_) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref RMSR register + * @sa getRMSR() + */ +#define setRMSR(rmsr) \ + WIZCHIP_WRITE(RMSR,rmsr) // Receicve Memory Size + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref RMSR register + * @return uint8_t. Value of @ref RMSR register. + * @sa setRMSR() + */ + #define getRMSR() \ + WIZCHIP_READ(RMSR) // Receicve Memory Size + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref TMSR register + * @sa getTMSR() + */ +#define setTMSR(tmsr) \ + WIZCHIP_WRITE(TMSR,tmsr) // Receicve Memory Size + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref TMSR register + * @return uint8_t. Value of @ref TMSR register. + * @sa setTMSR() + */ +#define getTMSR() \ + WIZCHIP_READ(TMSR) + + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PATR register + * @return uint16_t. Value to set \ref PATR register + */ +#define getPATR() \ + (((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1))) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PPPALGO register + * @return uint8_t. Value to set \ref PPPALGO register + */ +#define getPPPALGO() \ + WIZCHIP_READ(PPPALGO) + + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PTIMER register + * @param (uint8_t)ptimer Value to set \ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + + +//todo Functions for W5100S + +/*----------------------------------------------------------------------*/ +/* W5100S only */ +/*----------------------------------------------------------------------*/ + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref IR2 register + * @param (uint8_t)ir2 Value to set @ref IR2 register. + * @sa getIR2() + */ +#define setIR2(ir2) \ + WIZCHIP_WRITE(IR2, ir2) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref IR2 register + * @return uint8_t. Value of @ref IR2 register. + * @sa setIR2() + */ +#define getIR2() \ + WIZCHIP_READ(IR2) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref IMR2 register + * @param (uint8_t)imr2 Value to set @ref IMR2 register. + * @sa setIMR2() + */ +#define setIMR2(imr2) \ + WIZCHIP_WRITE(IMR2,imr2) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref IMR2 register + * @return uint8_t. Value of @ref IMR2 register. + * @sa getIMR2() + */ +#define getIMR2() \ + WIZCHIP_READ(IMR2) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref UIPR(Unreachable IP Address Register) registers + * @param (uint8_t*)uipr Value to set @ref UIPR registers. + * @sa setUIPR() + */ +#define setUIPR(uipr) \ + WIZCHIP_WRITE_BUF(UIPR,uipr,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref UIPR(Unreachable IP Address Register) registers + * @param (uint8_t*)uipr Value to get @ref UIPR registers + * @sa setUIPR() + */ +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref UPORTR(Unreachable Port Address Register) register + * @param (uint16_t)uportr Value to set @ref UPORTR register. + * @sa getUPORTR() + */ +#define setUPORTR(uportr) {\ + WIZCHIP_WRITE(UPORTR, (uint8_t)(uportr >> 8)); \ + WIZCHIP_WRITE(UPORTR+1, (uint8_t) uportr); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref UPORTR(Unreachable Port Address Register) register + * @return uint16_t. Value of @ref UPORTR register. + * @sa setUPORTR() + */ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(UPORTR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref MR2 register + * @param (uint8_t)mr2 Value to set @ref MR2 registers. + * @sa getMR2() + */ +#define setMR2(mr2) \ + WIZCHIP_WRITE(MR2,mr2) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref MR2 register + * @return uint8_t. Value of @ref MR2 register. + * @sa setMR2() + */ +#define getMR2() \ + WIZCHIP_READ(MR2) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHAR registers + * @param (uint8_t*)phar Value to set @ref PHAR registers. + * @sa getPHAR() + */ +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(PHAR,phar,6) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHAR registers + * @param (uint8_t*)phar Pointer variable to get @ref PHAR registers. + * @sa setPHAR() + */ +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(PHAR,phar,6) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PSIDR register + * @param (uint16_t)psidr Value to set @ref PSIDR register. + * @sa getPSIDR() + */ +#define setPSIDR(psidr) {\ + WIZCHIP_WRITE(PSIDR, (uint8_t)(psidr >> 8)); \ + WIZCHIP_WRITE(PSIDR+1, (uint8_t) psidr); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PSIDR register + * @return uint16_t. Value of @ref PSIDR register. + * @sa setPSIDR() + */ +#define getPSIDR() \ + (((uint16_t)WIZCHIP_READ(PSIDR) << 8) + WIZCHIP_READ(PSIDR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PMRUR register + * @param (uint16_t)pmrur Value to set @ref PMRUR register. + * @sa getPMRUR() + */ +#define setPMRUR(pmrur) {\ + WIZCHIP_WRITE(PMRUR, (uint8_t)(pmrur >> 8)); \ + WIZCHIP_WRITE(PMRUR+1, (uint8_t) pmrur); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PMRUR register + * @return uint16_t. Value of @ref PMRUR register. + * @sa setPMRUR() + */ +#define getPMRUR() \ + (((uint16_t)WIZCHIP_READ(PMRUR) << 8) + WIZCHIP_READ(PMRUR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYSR register + * @return uint8_t. Value of @ref PHYSR register. + * @sa setPHYSR() + */ +#define getPHYSR() \ + WIZCHIP_READ(PHYSR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYSR1 register + * @return uint8_t. Value of @ref PHYSR1 register. + * @sa setPHYSR1() + */ +#define getPHYSR1() \ + WIZCHIP_READ(PHYSR1) + +/** + * For internal uses + * The address of the PHY is fixed as "0x0A". + */ +#define getPHYAR() \ + WIZCHIP_READ(PHYAR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYRAR register + * @return uint8_t. Value of @ref PHYRAR register. + * @sa setPHYRAR() + */ +#define getPHYRAR() \ + WIZCHIP_READ(PHYRAR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYRR register + * @param (uint8_t)phyrar Value to set @ref PHYRR register. + * @sa getPHYRR() + */ +#define setPHYRR(phyrar) \ + WIZCHIP_WRITE(PHYRAR, phyrar) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYDIR register + * @return uint16_t. Value of @ref PHYDIR register. + * @sa setPHYRAR() + */ +//read the value of the phy data input register +#define getPHYDIR() \ + (((uint16_t)WIZCHIP_READ(PHYDIR+1) << 8) + WIZCHIP_READ(PHYDIR)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYDIR register + * @param (uint16_t)phydir Value to set @ref PHYDIR register. + * @sa getPHYDIR() + */ +//write the value of the phy data input register +#define setPHYDIR(phydir) {\ + WIZCHIP_WRITE(PHYDIR+1, (uint8_t)(phydir >> 8)); \ + WIZCHIP_WRITE(PHYDIR, (uint8_t) phydir); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYDOR register + * @return uint16_t. Value of @ref PHYDOR register. + * @sa setPHYDOR() + */ +//read the value of the phy data output register +#define getPHYDOR() \ + (((uint16_t)WIZCHIP_READ(PHYDOR+1) << 8) + WIZCHIP_READ(PHYDOR)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYDOR register + * @param (uint16_t)phydor Value to set @ref PHYDOR register. + * @sa getPHYDOR() + */ +//write the value of the phy data output register +#define setPHYDOR(phydor) {\ + WIZCHIP_WRITE(PHYDOR, (uint8_t)(phydor >> 8)); \ + WIZCHIP_WRITE(PHYDOR+1, (uint8_t) phydor); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYACR register + * @return uint8_t. Value of @ref PHYACR register. + * @sa setPHYACR() + */ +//read the value of the phy action register ***This register will be cleared automatically*** +#define getPHYACR() \ + WIZCHIP_READ(PHYACR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYACR register + * @param (uint8_t)phyacr Value to set @ref PHYACR register. + * @sa getPHYACR() + */ +//write the value of the phy action register +#define setPHYACR(phyacr) \ + WIZCHIP_WRITE(PHYACR,phyacr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYDIVR register + * @param (uint8_t)phydivr Value to set @ref PHYDIVR register. + * @sa getPHYDIVR() + */ +#define setPHYDIVR(phydivr) \ + WIZCHIP_WRITE(PHYDIVR, phydivr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYDIVR register + * @return uint8_t. Value of @ref PHYDIVR register. + * @sa setPHYDIVR() + */ +#define getPHYDIVR() \ + WIZCHIP_READ(PHYDIVR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYCR0 register + * @param (uint8_t)phych0 Value to set @ref PHYCR0 register. + * @sa getPHYCR0() + */ +#define setPHYCR0(phych0) \ + WIZCHIP_WRITE(PHYCR0,phych0) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYCR0 register + * @return uint8_t. Value of @ref PHYCR0 register. + * @sa setPHYCR0() + */ +#define getPHYCR0() \ + WIZCHIP_READ(PHYCR0) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PHYCR1 register + * @param (uint8_t)phycr1 Value to set @ref PHYCR1 register. + * @sa getPHYCR1() + */ +#define setPHYCR1(phycr1) \ + WIZCHIP_WRITE(PHYCR1,phycr1) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PHYCR1 register + * @return uint8_t. Value of @ref PHYCR1 register. + * @sa setPHYCR1() + */ +#define getPHYCR1() \ + WIZCHIP_READ(PHYCR1) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref SLCR register + * @param (uint8_t)rqcr Value to set @ref SLCR register. + * @sa getSLCR() + */ +#define setSLCR(rqcr) \ + WIZCHIP_WRITE(SLCR, rqcr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref RQCR register + * @return uint8_t. Value of @ref RQCR register. + * @sa setRQCR() + */ +#define getSLCR() \ + WIZCHIP_READ(RQCR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref SLRTR register + * @param (uint16_t)slrtr Value to set @ref SLRTR register. + * @sa getSLRTR() + */ +#define setSLRTR(slrtr) \ + WIZCHIP_WRITE(SLRTR, (uint8_t)(slrtr >> 8)); \ + WIZCHIP_WRITE(SLRTR+1, (uint8_t) slrtr); \ + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLRTR register + * @return uint16_t. Value of @ref SLRTR register. + * @sa setSLRTR() + */ +#define getSLRTR() \ + (((uint16_t)WIZCHIP_READ(SLRTR) << 8) + WIZCHIP_READ(SLRTR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref SLRCR register + * @param (uint8_t)slrcr Value to set @ref SLRCR register. + * @sa getSLRCR() + */ +#define setSLRCR(slrcr) \ + WIZCHIP_WRITE(SLRCR,slrcr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLRCR register + * @return uint8_t. Value of @ref SLRCR register. + * @sa setSLRCR() + */ +#define getSLRCR() \ + WIZCHIP_READ(SLRCR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref SLPIPR registers + * @param (uint8_t*)slpipr Values to set @ref SLPIPR registers. + * @sa getSLPIPR() + */ +#define setSLPIPR(slpipr) \ + WIZCHIP_WRITE_BUF(SLPIPR,slpipr,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLPIPR registers + * @param (uint8_t*)slpipr Values to get @ref SLPIPR registers. + * @sa getSLPIPR() + */ +#define getSLPIPR(slpipr) \ + WIZCHIP_READ_BUF(SLPIPR,slpipr,4) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLPHAR registers + * @param (uint8_t*)slphar Values to set @ref SLPHAR registers. + * @sa getSLPHAR() + */ +#define setSLPHAR(slphar) \ + WIZCHIP_WRITE_BUF(SLPHAR,slphar,6) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLPHAR registers + * @param (uint8_t*)slphar Values to get @ref SLPHAR registers. + * @sa getSLPHAR() + */ +#define getSLPHAR(slphar) \ + WIZCHIP_READ_BUF(SLPHAR,slphar,6) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PINGSEQR register + * @param (uint16_t)pingseqr Value to set @ref PINGSEQR register. + * @sa getPINGSEQR() + */ +#define setPINGSEQR(pingseqr) {\ + WIZCHIP_WRITE(PINGSEQR, (uint8_t)(pingseqr >> 8)); \ + WIZCHIP_WRITE(PINGSEQR+1, (uint8_t) pingseqr); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PINGSEQR register + * @return uint16_t. Value of @ref PINGSEQR register. + * @sa setPINGSEQR() + */ +#define getPINGSEQR() \ + (((uint16_t)WIZCHIP_READ(PINGSEQR) << 8) + WIZCHIP_READ(PINGSEQR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref PINGIDR register + * @param (uint16_t)pingidr Value to set @ref PINGIDR register. + * @sa getPINGIDR() + */ +#define setPINGIDR(pingidr) {\ + WIZCHIP_WRITE(PINGIDR, (uint8_t)(pingidr >> 8)); \ + WIZCHIP_WRITE(PINGIDR+1, (uint8_t) pingidr); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref PINGIDR register + * @return uint16_t. Value of @ref PINGIDR register. + * @sa setPINGIDR() + */ +#define getPINGIDR() \ + (((uint16_t)WIZCHIP_READ(PINGIDR) << 8) + WIZCHIP_READ(PINGIDR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref SLIMR register + * @param (uint8_t)slimr Value to set @ref SLIMR register. + * @sa getSLIMR() + */ +#define setSLIMR(slimr) \ + WIZCHIP_WRITE(SLIMR, slimr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLIMR register + * @return uint8_t. Value of @ref SLIMR register. + * @sa setSLIMR() + */ +#define getSLIMR() \ + WIZCHIP_READ(SLIMR) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref SLIR register + * @param (uint8_t)slir Value to set @ref SLIR register. + * @sa getSLIMR() + */ +#define setSLIR(slir) \ + WIZCHIP_WRITE(SLIR, slir) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref SLIMR register + * @return uint8_t. Value of @ref SLIMR register. + * @sa setSLIMR() + */ +#define getSLIR() \ + WIZCHIP_READ(SLIR) + +/*Hidden functions for W5100S*/ +#define setDBGOUT(dbgout) {\ + WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout >> 16)); \ + WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout >> 8)); \ + WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout)); \ + } + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref NICMAXCOLR register + * @param (uint8_t)nicmaxcolr Value to set @ref NICMAXCOLR register. + * @sa getNICMAXCOLR() + */ +#define setNICMAXCOLR(nicmaxcolr) \ + WIZCHIP_WRITE(NICMAXCOLR,nicmaxcolr) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref NICMAXCOLR register + * @return uint8_t. Value of @ref NICMAXCOLR register. + * @sa setNICMAXCOLR() + */ +#define getNICMAXCOLR() \ + WIZCHIP_READ(NICMAXCOLR) + +/*Clock lock/unlock*/ + +/** + * @ingroup Common_register_access_function_W5100S + * @brief LOCK Chip Information + * @sa CHIPULLOCK() + */ +#define CHIPLOCK() \ + WIZCHIP_WRITE(CHIPLCKR,0xff) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Unlock Chip Information + * @sa CHIPLOCK() + */ +#define CHIPUNLOCK() \ + WIZCHIP_WRITE(CHIPLCKR,0xCE) + + +/** + * @ingroup Common_register_access_function_W5100S + * @brief LOCK Chip Information + * @sa CHIPULLOCK() + */ +/*Network information lock/unlock*/ +#define NETLOCK() \ + WIZCHIP_WRITE(NETLCKR,0x3A) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Unlock Chip Information + * @sa CHIPLOCK() + */ +#define NETUNLOCK() \ + WIZCHIP_WRITE(NETLCKR,0xC5) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Lock PHYCR0,CR1 Information + * @sa CHIPULLOCK() + */ +/*PHY CR0,CR1 lock/unlock*/ +#define PHYLOCK() \ + WIZCHIP_WRITE(PHYLCKR,0xff) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Lock PHYCR0,CR1 Information + * @sa CHIPULLOCK() + */ +#define PHYUNLOCK() \ + WIZCHIP_WRITE(PHYLCKR,0x53) + +/** + * @ingroup Version register_access_function_W5100SS + * @brief Get version information. + * @return uint16_t. It must be "0x51" + */ +#define getVER() \ + (WIZCHIP_READ(VERR)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Get \ref TCNTR register + * @return uint16_t. Value of @ref TCNTR register. + * @sa setNTCNTR() + */ +/*Get 100us internal counter*/ +#define getTCNTR() \ + (((uint16_t)WIZCHIP_READ(TCNTR) << 8) + WIZCHIP_READ(TCNTR+1)) + +/** + * @ingroup Common_register_access_function_W5100S + * @brief Set \ref TCNTR register + * @param (uint8_t) + Value to set @ref TCNTR register. + * @sa getTCNTCLKR() + */ +/*Reset 100us internal counter(TCNTR)*/ +#define setTCNTCLKR(var) \ + WIZCHIP_WRITE(TCNTCLKR, var) + +/*w5100s only end*/ + + + + + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_MR register + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * @param mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_MR register + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * @return Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), ir) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + WIZCHIP_READ(Sn_IR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_PROTO register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)proto Value to set \ref Sn_PROTO + * @sa getSn_PROTO() + */ +#define setSn_PROTO(sn, proto) \ + WIZCHIP_WRITE(Sn_PROTO(sn), proto) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_PROTO register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_PROTO. + * @sa setSn_PROTO() + */ +#define getSn_PROTO(sn) \ + WIZCHIP_READ(Sn_PROTO(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_RXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE + * @sa getSn_RXMEM_SIZE() + */ +#define setSn_RXMEM_SIZE(sn, rxmemsize) \ + WIZCHIP_WRITE(RMSR, (WIZCHIP_READ(RMSR) & ~(0x03 << (2*sn))) | (rxmemsize << (2*sn))) +#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize) +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_RXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_RXMEM. + * @sa setSn_RXMEM_SIZE() + */ +#define getSn_RXMEM_SIZE(sn) \ + ((WIZCHIP_READ(RMSR) & (0x03 << (2*sn))) >> (2*sn)) +#define getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_TXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE + * @sa getSn_TXMEM_SIZE() + */ +#define setSn_TXMEM_SIZE(sn, txmemsize) \ + WIZCHIP_WRITE(TMSR, (WIZCHIP_READ(TMSR) & ~(0x03 << (2*sn))) | (txmemsize << (2*sn))) +#define setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_TXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_TXMEM_SIZE. + * @sa setSn_TXMEM_SIZE() + */ +#define getSn_TXMEM_SIZE(sn) \ + ((WIZCHIP_READ(TMSR) & (0x03 << (2*sn))) >> (2*sn)) +#define getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @regurn uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR + * @sa getSn_RX_WR() + */ +#define setSn_RX_WR(sn, rxwr) { \ + WIZCHIP_WRITE(Sn_RX_WR(sn), (uint8_t)(rxwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \ + } + + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set @ref Sn_FRAGR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)frag Value to set \ref Sn_FRAGR + * @sa getSn_FRAG() + */ +#define setSn_FRAGR(sn, fragr) { \ + WIZCHIP_WRITE(Sn_FRAGR(sn), (uint8_t)(fragr >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAGR(sn),1), (uint8_t) fragr); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get @ref Sn_FRAGR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_FRAGR. + * @sa setSn_FRAG() + */ +#define getSn_FRAGR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAGR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAGR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the max RX buffer size of socket sn + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Max buffer size + */ +#define getSn_RxMAX(sn) \ + ((uint16_t)(0x0001 << getSn_RXMEM_SIZE(sn)) << 10) + + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the max TX buffer size of socket sn + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Max buffer size + */ +#define getSn_TxMAX(sn) \ + ((uint16_t)(0x0001 << getSn_TXMEM_SIZE(sn)) << 10) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the mask of socket sn RX buffer. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Mask value + */ +#define getSn_RxMASK(sn) \ + (getSn_RxMAX(sn) - 1) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the mask of socket sn TX buffer + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Mask value + */ +#define getSn_TxMASK(sn) \ + (getSn_TxMAX(sn) - 1) + + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the base address of socket sn RX buffer. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n RX buffer base address. + */ +uint32_t getSn_RxBASE(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the base address of socket sn TX buffer. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n TX buffer base address. + */ +uint32_t getSn_TxBASE(uint8_t sn); + + +/*socket register W5100S only*/ + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set the interrupt mask register of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)imr Value to set \ref Sn_IMR + * @sa getSn_IMR(sn) + */ +#define setSn_IMR(sn,imr) \ + WIZCHIP_WRITE(Sn_IMR(sn),imr) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the interrupt mask register of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n interrupt mask register. + */ +#define getSn_IMR(sn) \ + WIZCHIP_READ(Sn_IMR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set the Sn_MR2 value of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param mr2 Value of Sn_MR2 register to set. + */ +#define setSn_MR2(sn,mr2) \ + WIZCHIP_WRITE(Sn_MR2(sn), mr2) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the Sn_MR2 value of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n Sn_MR2 register. + */ +#define getSn_MR2(sn) \ + WIZCHIP_READ(Sn_MR2(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set the Sn_KPALVTR value of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param kpalvtr Value of the Sn_KPALVTR register to set. + */ +#define setSn_KPALVTR(sn,kpalvtr) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvtr) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the Sn_KPALVTR value of socket sn + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of the Sn_KPALVTR register. + */ +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(Sn_KPALVTR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the Sn_TSR register of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of the Socket n Sn_TSR register. + */ +#define getSn_TSR(sn) \ + WIZCHIP_READ(Sn_TSR(sn)) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set the Sn_RTR register of socket sn. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rtr Value of the Socket n Sn_RTR register to set. + */ +#define setSn_RTR(sn,rtr) { \ + WIZCHIP_WRITE(Sn_RTR(sn), (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RTR(sn),1), (uint8_t) rtr); \ + } + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the Sn_RTR register of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of the Socket n Sn_RTR register. + */ +#define getSn_RTR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RTR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RTR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Set the Sn_RCR register of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of the Socket n Sn_RCR register to set. + */ +#define setSn_RCR(sn,rcr) \ + WIZCHIP_WRITE(Sn_RCR(sn),rcr) + +/** + * @ingroup Socket_register_access_function_W5100S + * @brief Get the Sn_RCR of socket sn. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of the Socket n Sn_RCR. + */ +#define getSn_RCR(sn) \ + WIZCHIP_READ(Sn_RCR(sn)) + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @ingroup Basic_IO_function_W5100S + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5100S + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5100S + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/** + * @ingroup Special_function_W5100S + * @brief Write data to the PHY via MDC/MDIO interface. + * @details Write command data to the PHY via MDC/MDIO interface. + * @param (uint8_t)PHYMDIO_regadr Address of the PHY register. It should be PHYMDIO_BMCR or PHYMDIO_BMSR. + * @param (uint16_t)var Data to write to the PHY register. Please refer to the bit definitions of the BMCR and BMSR register. + */ +void wiz_mdio_write(uint8_t PHYMDIO_regadr, uint16_t var); + +/** + * @ingroup Special_function_W5100S + * @brief Read data from the PHY via MDC/MDIO interface. + * @details Read command or status data from the PHY via MDC/MDIO interface. + * @param (uint8_t)PHYMDIO_regadr Address of the PHY register. It should be PHYMDIO_BMCR or PHYMDIO_BMSR. + * @return The value of the PHY register + */ +uint16_t wiz_mdio_read(uint8_t PHYMDIO_regadr); + +/** + * @ingroup Special_function_W5100S + * @brief Delay function + * @details Delay function using internal 100us timer of the W5100S + * @param (uint32_t)ms Time to delay in milliseconds. + */ +void wiz_delay_ms(uint32_t ms); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif //_W5100S_H_ + + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.c new file mode 100755 index 00000000000..52bd5f50dfb --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.c @@ -0,0 +1,353 @@ +//***************************************************************************** +// +//! \file w5200.c +//! \brief W5200 HAL Interface. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "w5200.h" + +#if (_WIZCHIP_ == 5200) +/** +@brief This function writes the data into W5200 registers. +*/ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(_W5200_SPI_WRITE_); // Data write command and Write data length upper + WIZCHIP.IF.SPI._write_byte(0x01); // Write data length lower + WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data) + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + //add indirect bus + //M20150601 : Rename the function for integrating with W5300 + //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF)); + //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF)); + WIZCHIP.IF.BUS._write_data(IDM_DR,wb); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} +/** +@brief This function reads the value from W5200 registers. +*/ +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(_W5200_SPI_READ_); // Read data length upper + WIZCHIP.IF.SPI._write_byte(0x01); // Data length lower + ret = WIZCHIP.IF.SPI._read_byte(); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + //add indirect bus + //M20150601 : Rename the function for integrating with W5300 + //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF)); + //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF)); + ret = WIZCHIP.IF.BUS._read_data(IDM_DR); + +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + + +/** +@brief This function writes into W5200 memory(Buffer) +*/ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(_W5200_SPI_WRITE_ | ((len & 0x7F00) >> 8)); // Write data op code and length upper + WIZCHIP.IF.SPI._write_byte((len & 0x00FF) >> 0); // length lower + for(i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + //M20150601 : Rename the function for integrating with W5300 + /* + WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI); + WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF)); + for(i = 0 ; i < len; i++) + WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); + */ + setMR(getMR() | MR_AI); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF)); + for(i = 0 ; i < len; i++) + WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +/** +@brief This function reads into W5200 memory(Buffer) +*/ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte( _W5200_SPI_READ_ | ((len & 0x7F00) >> 8)); // Write data op code and length upper + WIZCHIP.IF.SPI._write_byte((len & 0x00FF) >> 0); // length lower + for(i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + //M20150601 : Rename the function for integrating with W5300 + /* + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI); + WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF)); + for(i = 0 ; i < len; i++) + pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR); + WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); + */ + setMR(getMR() | MR_AI); + WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF)); + for(i = 0 ; i < len; i++) + pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR); + setMR(getMR() & ~MR_AI); +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +/////////////////////////////////// +// Socket N regsiter IO function // +/////////////////////////////////// + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// + +uint16_t getSn_RxBASE(uint8_t sn) +{ + int8_t i; + uint16_t rxbase = _WIZCHIP_IO_RXBUF_; + for(i = 0; i < sn; i++) + rxbase += getSn_RxMAX(i); + return rxbase; +} + +uint16_t getSn_TxBASE(uint8_t sn) +{ + int8_t i; + uint16_t txbase = _WIZCHIP_IO_TXBUF_; + for(i = 0; i < sn; i++) + txbase += getSn_TxMAX(i); + return txbase; +} + +/** +@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip. + +This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer +register. User should read upper byte first and lower byte later to get proper value. +And this function is being used for copy the data form application buffer to Transmite +buffer of the chip. It calculate the actual physical address where one has to write +the data in transmite buffer. Here also take care of the condition while it exceed +the Tx memory uper-bound of socket. + +*/ + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + + uint16_t ptr; + uint16_t size; + uint16_t dst_mask; + uint8_t * dst_ptr; + + ptr = getSn_TX_WR(sn); + + + dst_mask = (uint32_t)ptr & getSn_TxMASK(sn); + dst_ptr = (uint8_t*)((uint32_t)getSn_TxBASE(sn) + dst_mask); + + if (dst_mask + len > getSn_TxMAX(sn)) + { + size = getSn_TxMAX(sn) - dst_mask; + WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, size); + wizdata += size; + size = len - size; + dst_ptr = (uint8_t*)((uint32_t)getSn_TxBASE(sn)); + WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, size); + } + else + { + WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, len); + } + + ptr += len; + + setSn_TX_WR(sn, ptr); +} + + +/** +@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer. + +This function read the Rx read pointer register +and after copy the data from receive buffer update the Rx write pointer register. +User should read upper byte first and lower byte later to get proper value. +It calculate the actual physical address where one has to read +the data from Receive buffer. Here also take care of the condition while it exceed +the Rx memory uper-bound of socket. +*/ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr; + uint16_t size; + uint16_t src_mask; + uint8_t * src_ptr; + + ptr = getSn_RX_RD(sn); + + src_mask = (uint32_t)ptr & getSn_RxMASK(sn); + src_ptr = (uint8_t *)((uint32_t)getSn_RxBASE(sn) + src_mask); + + if( (src_mask + len) > getSn_RxMAX(sn) ) + { + size = getSn_RxMAX(sn) - src_mask; + WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size); + wizdata += size; + size = len - size; + src_ptr = (uint8_t*)((uint32_t)getSn_RxBASE(sn)); + WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size); + } + else + { + WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, len); + } + + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr; + + ptr = getSn_RX_RD(sn); + + ptr += len; + setSn_RX_RD(sn,ptr); +} + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.h new file mode 100755 index 00000000000..0fcfe3eb58c --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5200/w5200.h @@ -0,0 +1,2110 @@ +//* **************************************************************************** +//! \file w5200.h +//! \brief W5200 HAL Header File. +//! \version 1.0.0 +//! \date 2015/03/23 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _W5200_H +#define _W5200_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "wizchip_conf.h" + +/// \cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5200) +/// \endcond + +#define _WIZCHIP_SN_BASE_ (0x4000) +#define _WIZCHIP_SN_SIZE_ (0x0100) +#define _WIZCHIP_IO_TXBUF_ (0x8000) /* Internal Tx buffer address of the iinchip */ +#define _WIZCHIP_IO_RXBUF_ (0xC000) /* Internal Rx buffer address of the iinchip */ + +#define _W5200_SPI_READ_ (0x00 << 7) ///< SPI interface Read operation in Control Phase +#define _W5200_SPI_WRITE_ (0x01 << 7) ///< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block +#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address + +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) + #define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0001)) + #define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0002)) + #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003)) + #define _W5200_IO_BASE_ 0x0000 +#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define _W5200_IO_BASE_ 0x0000 +#endif + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + + +//----------- defgroup -------------------------------- + +/** + * @defgroup W5200 W5200 + * @brief WHIZCHIP register defines and I/O functions of @b W5200. + * + * - @ref WIZCHIP_register_W5200 : @ref Common_register_group_W5200 and @ref Socket_register_group_W5200 + * - @ref WIZCHIP_IO_Functions_W5200 : @ref Basic_IO_function_W5200, @ref Common_register_access_function_W5200 and @ref Socket_register_group_W5200 + */ + + /** + * @defgroup WIZCHIP_register_W5200 WIZCHIP register + * @ingroup W5200 + * @brief WIZCHIP register defines register group of W5200 . + * + * - \ref Common_register_group_W5200 : Common register group w5200 + * - \ref Socket_register_group_W5200 : \c SOCKET n register group w5200 + */ + + +/** + * @defgroup WIZCHIP_IO_Functions_W5200 WIZCHIP I/O functions + * @ingroup W5200 + * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5200. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - \ref Common_register_group_W5200 access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getIR2(), setIR2(), getIMR2(), setIMR2(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC() + * -# @b etc. \n + * getPHYSTATUS(), getVERSIONR() \n\n + * + * - \ref Socket_register_group_W5200 access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group_W5200 Common register + * @ingroup WIZCHIP_register_W5200 + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, _IMR_, IR2, IMR2 : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC : PPPoE. + * @sa PHYSTATUS, VERSIONR : etc. + */ + + + /** + * @defgroup Socket_register_group_W5200 Socket register + * @ingroup WIZCHIP_register_W5200 + * @brief Socket register group\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAG : Internet protocol. + * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + /** + * @defgroup Basic_IO_function_W5200 Basic I/O function + * @ingroup WIZCHIP_IO_Functions_W5200 + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function_W5200 Common register access functions + * @ingroup WIZCHIP_IO_Functions_W5200 + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function_W5200 Socket register access functions + * @ingroup WIZCHIP_IO_Functions_W5200 + * @brief These are functions to access socket registers. + */ + + //----------------------------------------------------------------------------------- + +//----------------------------- W5200 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group_W5200 + * @brief Mode Register address(R/W)\n + * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of \ref MR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    RST Reserved WOL PB PPPoE Reserved AI IND
    + * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_AI : Address Auto-Increment in Indirect Bus Interface + * - \ref MR_IND : Indirect Bus Interface mode + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) + #define MR (_WIZCHIP_IO_BASE_ + (0x0000)) // Mode +#else + #define MR (_W5200_IO_BASE_ + (0x0000)) // Mode +#endif + +/** + * @ingroup Common_register_group_W5200 + * @brief Gateway IP Register address(R/W) + * @details \ref GAR configures the default gateway address. + */ +#define GAR (_W5200_IO_BASE_ + (0x0001)) // GW Address + +/** + * @ingroup Common_register_group_W5200 + * @brief Subnet mask Register address(R/W) + * @details \ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5200_IO_BASE_ + (0x0005)) // SN Mask Address + +/** + * @ingroup Common_register_group_W5200 + * @brief Source MAC Register address(R/W) + * @details \ref SHAR configures the source hardware address. + */ +#define SHAR (_W5200_IO_BASE_ + (0x0009)) // Source Hardware Address + +/** + * @ingroup Common_register_group_W5200 + * @brief Source IP Register address(R/W) + * @details \ref SIPR configures the source IP address. + */ +#define SIPR (_W5200_IO_BASE_ + (0x000F)) // Source IP Address + +// Reserved (_W5200_IO_BASE_ + (0x0013)) +// Reserved (_W5200_IO_BASE_ + (0x0014)) + +/** + * @ingroup Common_register_group_W5200 + * @brief Interrupt Register(R/W) + * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host. + * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of \ref IR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    CONFLICT Reserved PPPoE Reserved Reserved Reserved Reserved Reserved
    + * - \ref IR_CONFLICT : IP conflict + * - \ref IR_PPPoE : PPPoE connection close + */ +#define IR (_W5200_IO_BASE_ + (0x0015)) // Interrupt + +/** + * @ingroup Common_register_group_W5200 + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR2. + * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR2 is Interrupt will be issued. + * In other words, if a bit of \ref _IMR_, an interrupt will be not issued even if the corresponding bit of \ref IR2 is set + * @note This Register is same operated as SMIR of W5100, W5300 and W5550.\n + * So, \ref setSIMR() set a value to _IMR_ for integrating with ioLibrary + */ +#define _IMR_ (_W5200_IO_BASE_ + (0x0016)) // Socket Interrupt Mask + +/** + * @ingroup Common_register_group_W5200 + * @brief Timeout register address( 1 is 100us )(R/W) + * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0. + * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5200 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the \ref _RTR_ time, W5200 retransmits the packet or issues timeout. + */ +#define _RTR_ (_W5200_IO_BASE_ + (0x0017)) // Retry Time + +/** + * @ingroup Common_register_group_W5200 + * @brief Retry count register(R/W) + * @details \ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1'). + */ +#define _RCR_ (_W5200_IO_BASE_ + (0x0019)) // Retry Count + +// Reserved (_W5200_IO_BASE_ + (0x001A)) +// Reserved (_W5200_IO_BASE_ + (0x001B)) + +/** + * @ingroup Common_register_group_W5200 + * @brief PPP LCP Request Timer register in PPPoE mode(R) + * @details \ref PATR notifies authentication method that has been agreed at the connection with + * PPPoE Server. W5200 supports two types of Authentication method - PAP and CHAP. + */ +#define PATR (_W5200_IO_BASE_ + (0x001C)) + +/** + * @ingroup Common_register_group_W5200 + * @brief PPP LCP Request Timer register in PPPoE mode(R) + * @details \ref PPPALGO notifies authentication algorithm in PPPoE mode. For detailed information, + * please refer to PPPoE application note. + */ +#define PPPALGO (_W5200_IO_BASE_ + (0x001E)) // Authentication Algorithm in PPPoE + +/** + * @ingroup Common_register_group_W5200 + * @brief chip version register address(R) + * @details \ref VERSIONR always indicates the W5200 version as @b 0x03. + */ +#define VERSIONR (_W5200_IO_BASE_ + (0x001F)) // Chip version + +// Reserved (_W5200_IO_BASE_ + (0x0020)) +// Reserved (_W5200_IO_BASE_ + (0x0021)) +// Reserved (_W5200_IO_BASE_ + (0x0022)) +// Reserved (_W5200_IO_BASE_ + (0x0023)) +// Reserved (_W5200_IO_BASE_ + (0x0024)) +// Reserved (_W5200_IO_BASE_ + (0x0025)) +// Reserved (_W5200_IO_BASE_ + (0x0026)) +// Reserved (_W5200_IO_BASE_ + (0x0027)) + +/** + * @ingroup Common_register_group_W5200 + * @brief PPP LCP Request Timer register in PPPoE mode(R) + * @details \ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5200_IO_BASE_ + (0x0028)) // PPP LCP RequestTimer + +/** + * @ingroup Common_register_group_W5200 + * @brief PPP LCP Magic number register in PPPoE mode(R) + * @details \ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5200_IO_BASE_ + (0x0029)) // PPP LCP Magic number + +// Reserved (_W5200_IO_BASE_ + (0x002A)) +// Reserved (_W5200_IO_BASE_ + (0x002B)) +// Reserved (_W5200_IO_BASE_ + (0x002C)) +// Reserved (_W5200_IO_BASE_ + (0x002D)) +// Reserved (_W5200_IO_BASE_ + (0x002E)) +// Reserved (_W5200_IO_BASE_ + (0x002F)) + +/** + * @ingroup Common_register_group_W5200 + * @brief Set Interrupt low level timer register address(R/W) + * @details \ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5200_IO_BASE_ + (0x0030)) // Interrupt Low Level Timer + +// Reserved (_W5200_IO_BASE_ + (0x0032)) +// Reserved (_W5200_IO_BASE_ + (0x0033)) + +/** + * @ingroup Common_register_group_W5200 + * @brief Socket Interrupt Register(R/W) + * @details \ref IR2 indicates the interrupt status of Socket.\n + * Each bit of \ref IR2 be still until \ref Sn_IR is cleared by the host.\n + * If \ref Sn_IR is not equal to x00 the n-th bit of \ref IR2 is and INTn PIN is asserted until \ref IR2 is x00 */ +#define IR2 (_W5200_IO_BASE_ + (0x0034)) // Socket Interrupt + +/** + * @ingroup Common_register_group_W5200 + * @brief PHYSTATUS(R/W) + * @details \ref PHYSTATUS is the Register to indicate W5200 status of PHY. + * + * + * + *
    7 6 5 4 3 2 1 0
    Reserved Reserved LINK POWERSAVE POWERDOWN Reserved Reserved Reserved
    + * - \ref PHYSTATUS_LINK : Link Status Register[Read Only] + * - \ref PHYSTATUS_POWERSAVE : Power save mode of PHY[R/W] + * - \ref PHYSTATUS_POWERDOWN : Power down mode of PHY[R/W] + */ +#define PHYSTATUS (_W5200_IO_BASE_ + (0x0035)) // PHY Status + +/** + * @ingroup Common_register_group_W5200 + * @brief Interrupt mask register(R/W) + * @details \ref IMR2 is used to mask interrupts. Each bit of \ref _IMR_ corresponds to each bit of \ref IR. + * When a bit of \ref IMR2 is and the corresponding bit of \ref IR is an interrupt will be issued. In other words, + * if a bit of \ref IMR2 is an interrupt will not be issued even if the corresponding bit of \ref IR is \n\n + * Each bit of \ref IMR2 defined as the following. + * + * + * + *
    7 6 5 4 3 2 1 0
    IM_IR7 Reserved IM_IR5 Reserved Reserved Reserved Reserved Reserved
    + * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * @note This Register is same operated as _IMR_ of W5100, W5300 and W5550.\n + * So, \ref setIMR() set a value to IMR2 for integrating with ioLibrary + */ +#define IMR2 (_W5200_IO_BASE_ + (0x0036)) // Interrupt Mask + + +//----------------------------- W5200 Socket Registers ----------------------------- + +//--------------------------- For Backward Compatibility --------------------------- + +/** + * @ingroup Socket_register_group_W5200 + * @brief socket Mode register(R/W) + * @details \ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of \ref Sn_MR defined as the following. + * + * + * + *
    7 6 5 4 3 2 1 0
    MULTI MF ND/MC Reserved Protocol[3] Protocol[2] Protocol[1] Protocol[0]
    + * - \ref Sn_MR_MULTI : Support UDP Multicasting + * - \ref Sn_MR_MF : Support MACRAW + * - \ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - \ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - Protocol + * + * + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 0 0 0 Closed
    0 0 0 1 TCP
    0 0 1 0 UDP
    0 1 0 0 MACRAW
    + * - In case of Socket 0 + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 1 0 0 MACRAW
    0 1 0 1 PPPoE
    + * - \ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - \ref Sn_MR_UDP : UDP + * - \ref Sn_MR_TCP : TCP + * - \ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5200 accepts the command, the \ref Sn_CR register is automatically cleared to 0x00. + * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR. + * - \ref Sn_CR_OPEN : Initialize or open socket. + * - \ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - \ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - \ref Sn_CR_DISCON : Send closing request in TCP mode. + * - \ref Sn_CR_CLOSE : Close socket. + * - \ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - \ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - \ref Sn_CR_SEND_KEEP : Send keep alive message. + * - \ref Sn_CR_RECV : Update RX buffer pointer and receive data. + * - In case of S0_MR(P3:P0) = S0_MR_PPPoE + * + * + * + * + * + * + * + *
    Value Symbol Description
    0x23 PCON PPPoE connection begins by transmitting PPPoE discovery packet
    0x24 PDISCON Closes PPPoE connection
    0x25 PCR In each phase, it transmits REQ message.
    0x26 PCN In each phase, it transmits NAK message.
    0x27 PCJ In each phase, it transmits REJECT message.
    + */ +#define Sn_CR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Socket interrupt register(R) + * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of \ref Sn_IMR is the corresponding bit of \ref Sn_IR becomes \n + * In order to clear the \ref Sn_IR bit, the host should write the bit to \n + * + * + * + *
    7 6 5 4 3 2 1 0
    PRECV PFAIL PNEXT SEND_OK TIMEOUT RECV DISCON CON
    + * - \ref Sn_IR_PRECV : PPP Receive Interrupt + * - \ref Sn_IR_PFAIL : PPP Fail Interrupt + * - \ref Sn_IR_PNEXT : PPP Next Phase Interrupt + * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Socket status register(R) + * @details \ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - \ref SOCK_CLOSED : Closed + * - \ref SOCK_INIT : Initiate state + * - \ref SOCK_LISTEN : Listen state + * - \ref SOCK_ESTABLISHED : Success to connect + * - \ref SOCK_CLOSE_WAIT : Closing state + * - \ref SOCK_UDP : UDP socket + * - \ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - \ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - \ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - \ref SOCK_FIN_WAIT : Connection state + * - \ref SOCK_CLOSING : Closing state + * - \ref SOCK_TIME_WAIT : Closing state + * - \ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register + +/** + * @ingroup Socket_register_group_W5200 + * @brief source port register(R/W) + * @details \ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered. +*/ +#define Sn_PORT(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Peer MAC register address(R/W) + * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address + +/** + * @ingroup Socket_register_group_W5200 + * @brief Peer IP register address(R/W) + * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of TCP server before CONNECT command. + * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address + +/** + * @ingroup Socket_register_group_W5200 + * @brief Peer port register address(R/W) + * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command. + * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address + +/** + * @ingroup Socket_register_group_W5200 + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address + +/** + * @ingroup Socket_register_group_W5200 + * @brief IP Protocol(PROTO) Register(R/W) + * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is + * valid only in IPRAW mode, and ignored in other modes. + */ +#define Sn_PROTO(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode + +/** + * @ingroup Socket_register_group_W5200 + * @brief IP Type of Service(TOS) Register(R/W) + * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(sn) (WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register + +/** + * @ingroup Socket_register_group_W5200 + * @brief IP Time to live(TTL) Register(R/W) + * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register + +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017)) +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018)) +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019)) +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A)) +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B)) +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C)) +// Reserved (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D)) + +/** + * @ingroup Socket_register_group_W5200 + * @brief Receive memory size register(R/W) + * @details \ref Sn_RXMEM_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using \ref Sn_RXMEM_SIZE. The total sum of \ref Sn_RXMEM_SIZE can not be exceed 16Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXMEM_SIZE(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001E)) // Receive memory size reigster + +/** + * @ingroup Socket_register_group_W5200 + * @brief Transmit memory size register(R/W) + * @details \ref Sn_TXMEM_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can't be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using \ref Sn_TXMEM_SIZE. The total sum of \ref Sn_TXMEM_SIZE can not be exceed 16Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXMEM_SIZE(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001F)) // Transmit memory size reigster + +/** + * @ingroup Socket_register_group_W5200 + * @brief Transmit free memory size register(R) + * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE. + * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Transmit memory read pointer register address(R) + * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address + +/** + * @ingroup Socket_register_group_W5200 + * @brief Transmit memory write pointer register address(R/W) + * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address + +/** + * @ingroup Socket_register_group_W5200 + * @brief Received data size register(R) + * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between + * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD) + */ +#define Sn_RX_RSR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Read point of Receive memory(R/W) + * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5200. + */ +#define Sn_RX_RD(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory + +/** + * @ingroup Socket_register_group_W5200 + * @brief Write point of Receive memory(R) + * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory + +/** + * @ingroup Socket_register_group_W5200 + * @brief socket interrupt mask register(R) + * @details \ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of \ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of \ref Sn_IMR is + * the corresponding bit of \ref Sn_IR becomes When both the corresponding bit of \ref Sn_IMR and \ref Sn_IR are and the n-th bit of \ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +#define Sn_IMR(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002C)) // socket interrupt mask register + +/** + * @ingroup Socket_register_group_W5200 + * @brief Fragment field value in IP header register(R/W) + * @details \ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(sn) (_W5200_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002D)) // frag field value in IP header register + + +//----------------------------- W5200 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 ///< reset + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. + * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (\ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5200 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and + * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 ///< Wake on Lan + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 ///< ping block + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be '1'. + */ +#define MR_PPPOE 0x08 ///< enable pppoe + +/** + * @brief Address Auto-Increment in Indirect Bus Interface + * @details 0 : Disable auto-increment \n + * 1 : Enable auto-incremente \n + * At the Indirect Bus Interface mode, if this bit is set as ��1��, the address will + * be automatically increased by 1 whenever read and write are performed. + */ +#define MR_AI 0x02 ///< auto-increment in indirect mode + +/** + * @brief Indirect Bus Interface mode + * @details 0 : Disable Indirect bus Interface mode \n + * 1 : Enable Indirect bus Interface mode \n + * If this bit is set as ��1��, Indirect Bus Interface mode is set. + */ +#define MR_IND 0x01 ///< enable indirect mode + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 ///< check ip confict + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 ///< get the PPPoE close message + +/** + * @brief Link Status [Read Only] + * @details 0: Link down \n 1: Link up \n + */ +#define PHYSTATUS_LINK 0x20 + +/** + * @brief Power save mode of PHY + * @details 0: Disable Power save mode \n 1: Enable Power save mode \n + */ +#define PHYSTATUS_POWERSAVE 0x10 + +/** + * @brief Power down mode of PHY + * @details 0: Disable Power down mode \n 1: Enable Power down mode\n + */ +#define PHYSTATUS_POWERDOWN 0x08 + +// Sn_MR values +/* Sn_MR Default values */ +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 ///< unused socket + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 ///< TCP + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 ///< UDP +#define Sn_MR_IPRAW 0x03 ///< IP LAYER RAW SOCK + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 ///< MAC LAYER RAW SOCK + +/** + * @brief PPPoE + * @details This configures the protocol mode of Socket n. + * @note PPPoE mode should be only used in Socket 0. + */ +#define Sn_MR_PPPOE 0x05 ///< PPPoE + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001).\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_. + */ +#define Sn_MR_ND 0x20 ///< No Delayed Ack(TCP) flag + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010).\n + * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of \ref Sn_CR. + */ +#define Sn_MR_MC Sn_MR_ND ///< Select IGMP version 1(0) or 2(1) + +/** + * @brief Multicast Blocking in \ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1') + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MF 0x40 ///< Use MAC filter +#define Sn_MR_MFEN Sn_MR_MF + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010).\n + * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of \ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 ///< support multicating + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n + * + * + * + * + * + * + * + * + *
    \b Sn_MR (P[3:0]) \b Sn_SR
    Sn_MR_CLOSE (000) --
    Sn_MR_TCP (001) SOCK_INIT (0x13)
    Sn_MR_UDP (010) SOCK_UDP (0x22)
    S0_MR_IPRAW (011) SOCK_IPRAW (0x32)
    S0_MR_MACRAW (100) SOCK_MACRAW (0x42)
    S0_MR_PPPoE (101) SOCK_PPPoE (0x5F)
    + */ +#define Sn_CR_OPEN 0x01 ///< initialize or open socket + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).// + * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.// + * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.// + * When a 'TCP client' connection request is successfully established, + * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 ///< wait connection request in tcp mode(Server mode) + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by \ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as TCP client + */ +#define Sn_CR_CONNECT 0x04 ///< send connection request in tcp mode(Client mode) + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (Active closeor Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 ///< send closing reqeuset in tcp mode + +/** + * @brief Close socket + * @details Sn_SR is changed to \ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (\ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/** + * @brief PPPoE connection + * @details PPPoE connection begins by transmitting PPPoE discovery packet + */ +#define Sn_CR_PCON 0x23 + +/** + * @brief Closes PPPoE connection + * @details Closes PPPoE connection + */ +#define Sn_CR_PDISCON 0x24 + +/** + * @brief REQ message transmission + * @details In each phase, it transmits REQ message. + */ +#define Sn_CR_PCR 0x25 + +/** + * @brief NAK massage transmission + * @details In each phase, it transmits NAK message. + */ +#define Sn_CR_PCN 0x26 + +/** + * @brief REJECT message transmission + * @details In each phase, it transmits REJECT message. + */ +#define Sn_CR_PCJ 0x27 + +/* Sn_IR values */ +/** + * @brief PPP Receive Interrupt + * @details PPP Receive Interrupts when the option which is not supported is received. + */ +#define Sn_IR_PRECV 0x80 + +/** + * @brief PPP Fail Interrupt + * @details PPP Fail Interrupts when PAP Authentication is failed. + */ +#define Sn_IR_PFAIL 0x40 + +/** + * @brief PPP Next Phase Interrupt + * @details PPP Next Phase Interrupts when the phase is changed during ADSL connection process. + */ +#define Sn_IR_PNEXT 0x20 + +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 ///< complete sending + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 ///< assert timeout + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 ///< closed + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n + * After \ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 ///< init state + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer (TCP client).\n + * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1'). + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to \ref SOCK_ESTABLISHED. \n + * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1'). + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to \ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring \ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (\ref Sn_IR[TIMEOUT] = '1'). + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n + * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 ///< udp socket + +/** +* @brief IP raw mode socket + * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when Sn_MR (P3:P0) is + * Sn_MR_IPRAW and OPEN command is used.\n + * IP Packet can be transferred without a connection similar to the UDP mode. +*/ +#define SOCK_IPRAW 0x32 ///< ip raw mode socket + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100)and OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 ///< mac raw mode socket + +/** + * @brief PPPoE mode socket + * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR + * (P3:P0)=S0_MR_PPPoE.\n + * It is temporarily used at the PPPoE +connection. + */ +#define SOCK_PPPOE 0x5F ///< pppoe socket + +// IP PROTOCOL +#define IPPROTO_IP 0 ///< Dummy for IP +#define IPPROTO_ICMP 1 ///< Control message protocol +#define IPPROTO_IGMP 2 ///< Internet group management protocol +#define IPPROTO_GGP 3 ///< GW^2 (deprecated) +#define IPPROTO_TCP 6 ///< TCP +#define IPPROTO_PUP 12 ///< PUP +#define IPPROTO_UDP 17 ///< UDP +#define IPPROTO_IDP 22 ///< XNS idp +#define IPPROTO_ND 77 ///< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 ///< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// +/** + * @ingroup Basic_IO_function_W5200 + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function_W5200 + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function_W5200 + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5200 + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + + +///////////////////////////////// +// Common Register IO function // +///////////////////////////////// + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define setMR(mr) WIZCHIP_WRITE(MR,mr) +#else + #define setMR(mr) (*((uint8_t*)MR) = mr) +#endif + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get @ref MR. + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #define getMR() WIZCHIP_READ(MR) +#else + #define getMR() (*(uint8_t*)MR) +#endif + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set @ref GAR. + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get @ref GAR. + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set @ref SUBR. + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @note If subr is null pointer, set the backup subnet to SUBR. \n + * If subr is 0.0.0.0, back up SUBR and clear it. \n + * Otherwize, set subr to SUBR + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR, subr,4) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get @ref SUBR. + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set @ref SHAR. + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get @ref SHAR. + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set @ref SIPR. + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() +*/ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get @ref SIPR. + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref IR register + * @param (uint8_t)ir Value to set \ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xA0)) +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref IR register + * @return uint8_t. Value of \ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xA0) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref IMR2 register + * @param (uint8_t)imr Value to set @ref IMR2 register. + * @sa getIMR() + */ +//M20150410 : Replace _IMR_ with IMR2 for integrating with ioLibrary +/* +#define setIMR(imr) \ + WIZCHIP_WRITE(_IMR_, imr) +*/ +#define setIMR(imr) \ + WIZCHIP_WRITE(IMR2, imr & 0xA0) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref IMR2 register + * @return uint8_t. Value of @ref IMR2 register. + * @sa setIMR() + */ +//M20150410 : Replace _IMR_ with IMR2 for integrating with ioLibrary +/* +#define getIMR() \ + WIZCHIP_READ(_IMR_) +*/ +#define getIMR() \ + (WIZCHIP_READ(IMR2) & 0xA0) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(_RCR_) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref PATR register + * @return uint16_t. Value to set \ref PATR register + */ +#define getPATR() \ + (((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1))) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref PPPALGO register + * @return uint8_t. Value to set \ref PPPALGO register + */ +#define getPPPALGO() \ + WIZCHIP_READ(PPPALGO) + + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref VERSIONR register + * @return uint8_t. Value to set \ref VERSIONR register + */ +#define getVERSIONR() \ + WIZCHIP_READ(VERSIONR) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref PTIMER register + * @param (uint8_t)ptimer Value to set \ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set @ref INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) {\ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ + } +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get @ref INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref IR2 register + * @param (uint8_t)ir2 Value to set \ref IR2 register. + * @sa getIR2() + */ +#define setIR2(ir2) \ + WIZCHIP_WRITE(IR2, ir2) +#define setSIR(ir2) setIR2(ir2) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref IR2 register + * @return uint8_t. Value of \ref IR2 register. + * @sa setIR2() + */ +#define getIR2() \ + WIZCHIP_READ(IR2) +#define getSIR() getIR2() + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref PHYSTATUS register + * @return uint8_t. Value to set \ref PHYSTATUS register. + */ +#define getPHYSTATUS() \ + WIZCHIP_READ(PHYSTATUS) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Set \ref _IMR_ register + * @param (uint8_t)imr2 Value to set \ref IMR2 register. + * @sa getIMR2() + * @note If possible, Don't use this function. Instead, Use setSIMR() for compatible with ioLibrary. + */ + //M20150410 : Replace IMR2 with _IMR_ for integrating with ioLibrary +/* +#define setIMR2(imr2) \ + WIZCHIP_WRITE(IMR2, (imr2 & 0xA0)) +*/ +#define setIMR2(imr2) \ + WIZCHIP_WRITE(_IMR_, imr2) +#define setSIMR(imr2) setIMR2(imr2) + +/** + * @ingroup Common_register_access_function_W5200 + * @brief Get \ref _IMR_ register + * @return uint8_t. Value of \ref IMR2 register. + * @sa setIMR2() + */ + //M20150410 : Replace IMR2 with _IMR_ for integrating with ioLibrary +/* +#define getIMR2() \ + (WIZCHIP_READ(IMR2) & 0xA0) +*/ +#define getIMR2() \ + WIZCHIP_READ(_IMR_) +#define getSIMR() getIMR2() +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_MR register + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * @param mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_MR register + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ expect bit 4. + * @return Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), ir) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + WIZCHIP_READ(Sn_IR(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() +*/ +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), imr) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + WIZCHIP_READ(Sn_IMR(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_PROTO register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)proto Value to set \ref Sn_PROTO + * @sa getSn_PROTO() + */ +//M20150601 : Fixed Wrong Register address +/* +#define setSn_PROTO(sn, proto) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) +*/ +#define setSn_PROTO(sn, proto) \ + WIZCHIP_WRITE(Sn_PROTO(sn), proto) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_PROTO register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_PROTO. + * @sa setSn_PROTO() + */ +//M20150601 : Fixed Wrong Register address +/* +#define getSn_PROTO(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) +*/ +#define getSn_PROTO(sn) \ + WIZCHIP_READ(Sn_PROTO(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_RXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE + * @sa getSn_RXMEM_SIZE() + */ +#define setSn_RXMEM_SIZE(sn, rxmemsize) \ + WIZCHIP_WRITE(Sn_RXMEM_SIZE(sn),rxmemsize) + +#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_RXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_RXMEM. + * @sa setSn_RXMEM_SIZE() + */ +#define getSn_RXMEM_SIZE(sn) \ + WIZCHIP_READ(Sn_RXMEM_SIZE(sn)) + +#define getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_TXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE + * @sa getSn_TXMEM_SIZE() + */ +#define setSn_TXMEM_SIZE(sn, txmemsize) \ + WIZCHIP_WRITE(Sn_TXMEM_SIZE(sn), txmemsize) + +#define setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_TXMEM_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_TXMEM_SIZE. + * @sa setSn_TXMEM_SIZE() + */ +#define getSn_TXMEM_SIZE(sn) \ + WIZCHIP_READ(Sn_TXMEM_SIZE(sn)) + +#define getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR + * @sa getSn_RX_WR() + */ +#define setSn_RX_WR(sn, rxwr) { \ + WIZCHIP_WRITE(Sn_RX_WR(sn), (uint8_t)(rxwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \ + } + + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)imr Value to set \ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn ,imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), imr) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + WIZCHIP_READ(Sn_IMR(sn)) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint16_t)frag Value to set \ref Sn_FRAG + * @sa getSn_FRAG() + */ +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get the max RX buffer size of socket sn + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Max buffer size + */ +#define getSn_RxMAX(sn) \ + ((uint16_t)getSn_RXMEM_SIZE(sn) << 10) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get the max TX buffer size of socket sn + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Max buffer size + */ +#define getSn_TxMAX(sn) \ + ((uint16_t)getSn_TXMEM_SIZE(sn) << 10) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get the mask of socket sn RX buffer. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Mask value + */ +#define getSn_RxMASK(sn) \ + ((uint16_t)getSn_RxMAX(sn) - 1) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get the mask of socket sn TX buffer + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Mask value + */ +#define getSn_TxMASK(sn) \ + ((uint16_t)getSn_TxMAX(sn) - 1) + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get the base address of socket sn RX buffer. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n RX buffer base address. + */ +uint16_t getSn_RxBASE(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5200 + * @brief Get the base address of socket sn TX buffer. + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint16_t. Value of Socket n TX buffer base address. + */ +uint16_t getSn_TxBASE(uint8_t sn); + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @ingroup Basic_IO_function_W5200 + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5200 + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function_W5200 + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// \cond DOXY_APPLY_CODE +#endif +/// \endcond + +#ifdef __cplusplus +} +#endif + +#endif //_W5200_H_ + + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.c new file mode 100755 index 00000000000..4b5e60b68e5 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.c @@ -0,0 +1,225 @@ +//***************************************************************************** +// +//! \file w5300.h +//! \brief W5300 HAL implement File. +//! \version 1.0.0 +//! \date 2015/05/01 +//! \par Revision history +//! <2015/05/01> 1st Released for integrating with ioLibrary +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2015, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include +#include "wizchip_conf.h" + +#if _WIZCHIP_ == 5300 + + extern uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_]; + extern uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_]; + + +/*********************** + * Basic I/O Function * + ***********************/ + +void WIZCHIP_WRITE(uint32_t AddrSel, uint16_t wb ) +{ + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) ) + #if(_WIZCHIP_IO_BUS_WIDTH_ == 8) + WIZCHIP.IF.BUS._write_data(AddrSel, (uint8_t)(wb>>8)); + WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(AddrSel,1),(uint8_t)wb); + #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16) + WIZCHIP.IF.BUS._write_data(AddrSel, wb); + #else + #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16" + #endif +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + #if(_WIZCHIP_IO_BUS_WIDTH_ == 8) + WIZCHIP.IF.BUS._write_data(IDM_AR, (uint8_t)(AddrSel >> 8)); + WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_AR,1),(uint8_t)AddrSel); + WIZCHIP.IF.BUS._write_data(IDM_DR,(uint8_t)(wb>>8)); + WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_DR,1),(uint8_t)wb); + #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16) + WIZCHIP.IF.BUS._write_data(IDM_AR, (uint16_t)AddrSel); + WIZCHIP.IF.BUS._write_data(IDM_DR, wb); + #else + #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5300. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint16_t ret; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) ) + #if (_WIZCHIP_IO_BUS_WIDTH_ == 8) + ret = (((uint16_t)WIZCHIP.IF.BUS._read_data(AddrSel)) << 8) | + (((uint16_t)WIZCHIP.IF.BUS._read_data(WIZCHIP_OFFSET_INC(AddrSel,1))) & 0x00FF) ; + #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16) + ret = WIZCHIP.IF.BUS._read_data(AddrSel); + #else + #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16" + #endif +#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) ) + #if(_WIZCHIP_IO_BUS_WIDTH_ == 8) + WIZCHIP.IF.BUS._write_data(IDM_AR, (uint8_t)(AddrSel >> 8)); + WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_AR,1),(uint8_t)AddrSel); + ret = (((uint16_t)WIZCHIP.IF.BUS._read_data(IDM_DR)) << 8) | + (((uint16_t)WIZCHIP.IF.BUS._read_data(WIZCHIP_OFFSET_INC(IDM_DR,1))) & 0x00FF); + #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16) + WIZCHIP.IF.BUS._write_data(IDM_AR, (uint16_t)AddrSel); + ret = WIZCHIP.IF.BUS._read_data(IDM_DR); + #else + #error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5300. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + + +void setTMSR(uint8_t sn,uint8_t tmsr) +{ + uint16_t tmem; + tmem = WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))); + if(sn & 0x01) tmem = (tmem & 0xFF00) | (((uint16_t)tmsr ) & 0x00FF) ; + else tmem = (tmem & 0x00FF) | (((uint16_t)tmsr) << 8) ; + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE)),tmem); +} + +uint8_t getTMSR(uint8_t sn) +{ + if(sn & 0x01) + return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))) & 0x00FF); + return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))) >> 8); +} + +void setRMSR(uint8_t sn,uint8_t rmsr) +{ + uint16_t rmem; + rmem = WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))); + if(sn & 0x01) rmem = (rmem & 0xFF00) | (((uint16_t)rmsr ) & 0x00FF) ; + else rmem = (rmem & 0x00FF) | (((uint16_t)rmsr) << 8) ; + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE)),rmem); +} + +uint8_t getRMSR(uint8_t sn) +{ + if(sn & 0x01) + return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))) & 0x00FF); + return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))) >> 8); +} + +uint32_t getSn_TX_FSR(uint8_t sn) +{ + uint32_t free_tx_size=0; + uint32_t free_tx_size1=1; + while(1) + { + free_tx_size = (((uint32_t)WIZCHIP_READ(Sn_TX_FSR(sn))) << 16) | + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),2))) & 0x0000FFFF); // read + if(free_tx_size == free_tx_size1) break; // if first == sencond, Sn_TX_FSR value is valid. + free_tx_size1 = free_tx_size; // save second value into first + } + return free_tx_size; +} + +uint32_t getSn_RX_RSR(uint8_t sn) +{ + uint32_t received_rx_size=0; + uint32_t received_rx_size1=1; + while(1) + { + received_rx_size = (((uint32_t)WIZCHIP_READ(Sn_RX_RSR(sn))) << 16) | + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),2))) & 0x0000FFFF); + if(received_rx_size == received_rx_size1) break; + received_rx_size1 = received_rx_size; // if first == sencond, Sn_RX_RSR value is valid. + } // save second value into first + return received_rx_size + (uint32_t)((sock_pack_info[sn] & 0x02) ? 1 : 0); +} + + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint32_t len) +{ + uint32_t i = 0; + if(len == 0) return; + + for(i = 0; i < len ; i += 2) + setSn_TX_FIFOR(sn, (((uint16_t)wizdata[i]) << 8) | (((uint16_t)wizdata[i+1]) & 0x00FF)) +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint32_t len) +{ + uint16_t rd = 0; + uint32_t i = 0; + + if(len == 0) return; + + for(i = 0; i < len; i++) + { + if((i & 0x01)==0) + { + rd = getSn_RX_FIFOR(sn); + wizdata[i] = (uint8_t)(rd >> 8); + } + else wizdata[i] = (uint8_t)rd; // For checking the memory access violation + } + sock_remained_byte[sn] = (uint8_t)rd; // back up the remaind fifo byte. +} + +void wiz_recv_ignore(uint8_t sn, uint32_t len) +{ + uint32_t i = 0; + for(i = 0; i < len ; i += 2) getSn_RX_FIFOR(sn); +} + + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.h new file mode 100755 index 00000000000..a8bcd182fdc --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5300/w5300.h @@ -0,0 +1,2336 @@ +#ifndef _W5300_H_ +#define _W5300_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//***************************************************************************** +// +//! \file w5300.h +//! \brief W5300 HAL Header File. +//! \version 1.0.0 +//! \date 2015/05/01 +//! \par Revision history +//! <2015/05/01> 1st Released for integrating with ioLibrary +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2015, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include +#include "wizchip_conf.h" + +/// \cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5300) +/// \endcond + +#define _WIZCHIP_SN_BASE_ (0x0200) +#define _WIZCHIP_SN_SIZE_ (0x0040) + + +#define WIZCHIP_CREG_BLOCK 0x00 ///< Common register block +#define WIZCHIP_SREG_BLOCK(N) (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + N) ///< Increase offset address + +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + #define _W5300_IO_BASE_ _WIZCHIP_IO_BASE_ +#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + #define IDM_AR ((_WIZCHIP_IO_BASE_ + 0x0002)) ///< Indirect mode address register + #define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0004)) ///< Indirect mode data register + #define _W5300_IO_BASE_ 0x0000 +#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) + #error "Unkonw _WIZCHIP_IO_MODE_" +#endif + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +//#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +//#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5300 W5300 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5300. + * + * - @ref WIZCHIP_register_W5300 : @ref Common_register_group_W5300 and @ref Socket_register_group_W5300 + * - @ref WIZCHIP_IO_Functions_W5300 : @ref Basic_IO_function_W5300, @ref Common_register_access_function_W5300 and @ref Socket_register_access_function_W5300 + */ + + +/** + * @defgroup WIZCHIP_register_W5300 WIZCHIP register + * @ingroup W5300 + * + * @brief WHIZCHIP register defines register group of @b W5300. + * + * - @ref Common_register_group_W5300 : Common register group + * - @ref Socket_register_group_W5300 : \c SOCKET n register group + */ + + +/** + * @defgroup WIZCHIP_IO_Functions_W5300 WIZCHIP I/O functions + * @ingroup W5300 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register_W5300. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE() \n\n + * + * - @ref Common_register_group_W5300 access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b Socket Memory \n + * getMTYPER(), setMTYPER() \n + * getTMS01R(), getTMS23R(), getTMS45R(), getTMS67R(), setTMS01R(), setTMS23R(), setTMS45R(), setTMS67R() \n + * getRMS01R(), getRMS23R(), getRMS45R(), getRMS67R(), setRMS01R(), setRMS23R(), setRMS45R(), setRMS67R() \n + * -# @b etc. \n + * getPn_BRDYR(), setPn_BRDYR(), getPn_BDPTHR(), setPn_BDPTHR(), getIDR() \n\n + * + * - \ref Socket_register_group_W5300 access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + + +/** + * @defgroup Common_register_group_W5300 Common register + * @ingroup WIZCHIP_register_W5300 + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR : Network Configuration + * @sa IR, _IMR_ : Interrupt. + * @sa MTYPER, TMS01R,TMS23R, TMS45R, TMS67R,RMS01R,RMS23R, RMS45R, RMS67R : Socket TX/RX memory + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PSID, PDHAR : PPPoE. + * @sa UIPR, UPORTR, FMTUR : ICMP message. + * @sa Pn_BRDYR, Pn_BDPTHR, IDR : etc. + */ + + +/** + * @defgroup Socket_register_group_W5300 Socket register + * @ingroup WIZCHIP_register_W5300 + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_TX_WRSR, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR, Sn_TX_FIFOR, Sn_RX_FIFOR : Data communication + */ + + + /** + * @defgroup Basic_IO_function_W5300 Basic I/O function + * @ingroup WIZCHIP_IO_Functions_W5300 + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function_W5300 Common register access functions + * @ingroup WIZCHIP_IO_Functions_W5300 + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function_W5300 Socket register access functions + * @ingroup WIZCHIP_IO_Functions_W5300 + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end -------------------------------------------- + +//----------------------------- W5300 Common Registers ----------------------------- +/** + * @ingroup Common_register_group_W5300 + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + * + * + *
    15 14 13 12 11 10 9 8
    DBW MPF WDFRDF Reserved FS
    7 6 5 4 3 2 1 0
    RST Reserved WOL PB PPPoE Reserved FARP Reserved
    + * - \ref MR_DBW : Data bus width (0 : 8 Bit, 1 : 16 Bit), Read Only + * - \ref MR_MPF : Received a Pause Frame from MAC layer (0 : Normal Frame, 1 : Pause Frame), Read Only + * - \ref MR_WDF : Write Data Fetch time (When CS signal is low, W5300 Fetch a written data by Host after PLL_CLK * MR_WDF) + * - \ref MR_RDH : Read Data Hold time (0 : No use data hold time, 1 : Use data hold time, 2 PLL_CLK) + * - \ref MR_FS : FIFO Swap (0 : Disable Swap, 1 : Enable Swap) + * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_WIZCHIP_IO_BASE_) + +/** + * @ingroup Common_register_group_W5300 + * @brief Interrupt Register(R/W) + * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host. + * If \ref IR is not equal to 0x0000 INTn PIN is asserted to low until it is 0x0000\n\n + * Each bit of \ref IR defined as follows. + * + * + * + * + * + *
    15 14 13 12 11 10 9 8
    IPCF DPUR PPPT FMTU Reserved Reserved Reserved Reserved
    7 6 5 4 3 2 1 0
    S7_INT S6_INT S5_INT S4_INT S3_INT S2_INT S1_INT S0_INT
    + * - \ref IR_IPCF : IP conflict + * - \ref IR_DPUR : Destination Port Unreachable + * - \ref IR_PPPT : PPPoE Termination + * - \ref IR_FMTU : Fragmented MTU + * - \ref IR_SnINT(n) : Interrupted from SOCKETn + * + * @note : In W5300, IR is operated same as IR and SIR in other WIZCHIP(5100,5200,W5500) + */ +#define IR (_W5300_IO_BASE_ + 0x02) + +/** + * @ingroup Common_register_group_W5300 + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR. + * When a bit of _IMR_ is and the corresponding bit of \ref IR is Interrupt will be issued. + * In other words, if a bit of _IMR_, an interrupt will be not issued even if the corresponding bit of \ref IR is set + * @note : In W5300, _IMR_ is operated same as _IMR_ and SIMR in other WIZCHIP(5100,5200,W5500) + */ +#define _IMR_ (_W5300_IO_BASE_ + 0x04) + + +//#define ICFGR (_W5300_IO_BASE_ + 0x06) +//#define INTLEVEL ICFGR + +/** + * @ingroup Common_register_group_W5300 + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5300_IO_BASE_ + 0x08) + + +/** + * @ingroup Common_register_group_W5300 + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ + #define GAR (_W5300_IO_BASE_ + 0x10) + +/** + * @ingroup Common_register_group_W5300 + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5300_IO_BASE_ + 0x14) + +/** + * @ingroup Common_register_group_W5300 + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5300_IO_BASE_ + 0x18) + +/** + * @ingroup Common_register_group_W5300 + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref _RTR_ is x07D0. + * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref _RTR_, W5300 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the @ref _RTR_ time, W5300 retransmits the packet or issues timeout. + */ + #define _RTR_ (_W5300_IO_BASE_ + 0x1C) + +/** + * @ingroup Common_register_group_W5300 + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1'). + */ +#define _RCR_ (_W5300_IO_BASE_ + 0x1E) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 0 & 1 + * @details TMS01R configures the TX buffer block size of \c SOCKET 0 & 1. The default value is configured with 8KB and can be configure from 0 to 64KB with unit 1KB. + * But the sum of all SOCKET TX buffer size should be multiple of 8 and the sum of all SOCKET TX and RX memory size can't exceed 128KB. + * When exceeded nor multiple of 8, the data transmittion is invalid. + */ +#define TMS01R (_W5300_IO_BASE_ + 0x20) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 2 & 3 + * @details refer to \ref TMS01R + */ +#define TMS23R (TMS01R + 2) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 4 & 5 + * @details refer to \ref TMS01R + */ +#define TMS45R (TMS01R + 4) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 6 & 7 + * @details refer to \ref TMS01R + */ +#define TMS67R (TMS01R + 6) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 0. + * @details refer to \ref TMS01R + */ +#define TMSR0 TMS01R + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 1. + * @details refer to \ref TMS01R + */ +#define TMSR1 (TMSR0 + 1) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 2. + * @details refer to \ref TMS01R + */ +#define TMSR2 (TMSR0 + 2) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 3. + * @details refer to \ref TMS01R + */ +#define TMSR3 (TMSR0 + 3) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 4. + * @details refer to \ref TMS01R + */ +#define TMSR4 (TMSR0 + 4) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 5. + * @details refer to \ref TMS01R + */ +#define TMSR5 (TMSR0 + 5) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 6. + * @details refer to \ref TMS01R + */ +#define TMSR6 (TMSR0 + 6) + +/** + * @ingroup Common_register_group_W5300 + * @brief TX memory size of \c SOCKET 7. + * @details refer to \ref TMS01R + */ +#define TMSR7 (TMSR0 + 7) + + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 0 & 1 + * @details RMS01R configures the RX buffer block size of \c SOCKET 0 & 1. The default value is configured with 8KB and can be configure from 0 to 64KB with unit 1KB. + * But the sum of all SOCKET RX buffer size should be multiple of 8 and the sum of all SOCKET RX and TX memory size can't exceed 128KB. + * When exceeded nor multiple of 8, the data reception is invalid. + */ +#define RMS01R (_W5300_IO_BASE_ + 0x28) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 2 & 3 + * @details Refer to \ref RMS01R + */ +#define RMS23R (RMS01R + 2) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 4 & 5 + * @details Refer to \ref RMS01R + */ +#define RMS45R (RMS01R + 4) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 6 & 7 + * @details Refer to \ref RMS01R + */ +#define RMS67R (RMS01R + 6) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 0. + * @details refer to \ref RMS01R + */ +#define RMSR0 RMS01R + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 1. + * @details refer to \ref RMS01R + */ +#define RMSR1 (RMSR0 + 1) + +/** + * @ingroup Common_register_group_5300 + * @brief RX memory size of \c SOCKET 2. + * @details refer to \ref RMS01R + */ +#define RMSR2 (RMSR0 + 2) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 3. + * @details refer to \ref RMS01R + */ +#define RMSR3 (RMSR0 + 3) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 4. + * @details refer to \ref RMS01R + */ +#define RMSR4 (RMSR0 + 4) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 5. + * @details refer to \ref RMS01R + */ +#define RMSR5 (RMSR0 + 5) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 6. + * @details refer to \ref RMS01R + */ +#define RMSR6 (RMSR0 + 6) + +/** + * @ingroup Common_register_group_W5300 + * @brief RX memory size of \c SOCKET 7. + * @details refer to \ref RMS01R + */ +#define RMSR7 (RMSR0 + 7) + + + +/** + * @ingroup Common_register_group_W5300 + * @brief Memory Type Register + * @details W5300’s 128Kbytes data memory (Internal TX/RX memory) is composed of 16 memory blocks + * of 8Kbytes. MTYPER configures type of each 8KB memory block in order to select RX or TX memory. + * The type of 8KB memory block corresponds to each bit of MTYPER. When the bit is ‘1’, it is used as TX + * memory, and the bit is ‘0’, it is used as RX memory. MTYPER is configured as TX memory type + * from the lower bit. The rest of the bits not configured as TX memory, should be set as ‘0’. + */ +#define MTYPER (_W5300_IO_BASE_ + 0x30) + +/** + * @ingroup Common_register_group_W5300 + * @brief PPPoE Authentication Type register + * @details It notifies authentication method negotiated with PPPoE server. + * W5300 supports 2 types of authentication methods. + * - PAP : 0xC023 + * - CHAP : 0xC223 + */ +#define PATR (_W5300_IO_BASE_ + 0x32) + +//#define PPPALGOR (_W5300_IO_BASE_ + 0x34) + +/** + * @ingroup Common_register_group_W5300 + * @brief PPP Link Control Protocol Request Timer Register + * @details It configures transmitting timer of link control protocol (LCP) echo request. Value 1 is about 25ms. + */ +#define PTIMER (_W5300_IO_BASE_ + 0x36) + +/** + * @ingroup Common_register_group_W5300 + * @brief PPP LCP magic number register + * @details It configures byte value to be used for 4bytes “Magic Number” during LCP negotiation with PPPoE server. + */ +#define PMAGICR (_W5300_IO_BASE_ + 0x38) + +//#define PSTATER (_W5300_IO_BASE_ + 0x3A) + +/** + * @ingroup Common_register_group_W5300 + * @brief PPPoE session ID register + * @details It notifies PPP session ID to be used for communication with PPPoE server (acquired by PPPoE-process of W5300). + */ +#define PSIDR (_W5300_IO_BASE_ + 0x3C) + +/** + * @ingroup Common_register_group_W5300 + * @brief PPPoE destination hardware address register + * @details It notifies hardware address of PPPoE server (acquired by PPPoE-process of W5300). + */ +#define PDHAR (_W5300_IO_BASE_ + 0x40) + +/** + * @ingroup Common_register_group_W5300 + * @brief Unreachable IP address register + * @details When trying to transmit UDP data to destination port number which is not open, + * W5300 can receive ICMP (Destination port unreachable) packet. \n + * In this case, \ref IR_DPUR bit of \ref IR becomes '1'. + * And destination IP address and unreachable port number of ICMP packet can be acquired through UIPR and \ref UPORTR. + */ +#define UIPR (_W5300_IO_BASE_ + 0x48) + +/** + * @ingroup Common_register_group_W5300 + * @brief Unreachable port number register + * @details Refer to \ref UIPR. + */ +#define UPORTR (_W5300_IO_BASE_ + 0x4C) + +/** + * @ingroup Common_register_group_W5300 + * @brief Fragment MTU register + * @details When communicating with the peer having a different MTU, W5300 can receive an ICMP(Fragment MTU) packet. + * At this case, IR(FMTU) becomes ‘1’ and destination IP address and fragment MTU value of ICMP packet can be acquired through UIPR and FMTUR. + * In order to keep communicating with the peer having Fragment MTU, set the FMTUR first in Sn_MSSR of the SOCKETn, and try the next communication. + */ +#define FMTUR (_W5300_IO_BASE_ + 0x4E) + +//#define Sn_RTCR(n) (_W5300_IO_BASE_ + 0x50 + n*2) + +/** + * @ingroup Common_register_group_W5300 + * @brief PIN 'BRDYn' configure register + * @details It configures the PIN "BRDYn" which is monitoring TX/RX memory status of the specified SOCKET. + * If the free buffer size of TX memory is same or bigger than the buffer depth of \ref Pn_BDPTHR, + * or received buffer size of RX memory is same or bigger than the \ref Pn_BDPTHR, + * PIN "BRDYn" is signaled. + * + * + * + * + * + *
    15 14 13 12 11 10 9 8
    Reserved, Read as 0
    7 6 5 4 3 2 1 0
    PEN MT PPL Reserved SN
    + * + * - \ref Pn_PEN Enable PIN 'BRDYn' (0 : Disable, 1 : Enable) + * - \ref Pn_MT Monitoring Memory type (0 : RX memory, 1 : TX Memory) + * - \ref Pn_PPL PIN Polarity bit of Pn_BRDYR. (0 : Low sensitive, 1 : High sensitive) + * - \ref Pn_SN(n) Monitoring SOCKET number of Pn_BRDYR + */ +#define Pn_BRDYR(n) (_W5300_IO_BASE_ + 0x60 + n*4) + +/** + * @ingroup Common_register_group_W5300 + * @brief PIN 'BRDYn' buffer depth Register + * @details It configures buffer depth of PIN "BRDYn". + * When monitoring TX memory and \ref Sn_TX_FSR is same or bigger than Pn_BDPTHR, the PIN "BRDYn" is signaled. + * When monitoring RX memory and if \ref Sn_RX_RSR is same or bigger than Pn_BDPTHR, PIN "BRDYn" is signaled. + * The value for Pn_BDPTHR can't exceed TX/RX memory size allocated by TMSR or RMSR such like as \ref TMS01R or \ref RMS01R. + */ +#define Pn_BDPTHR(n) (_W5300_IO_BASE_ + 0x60 + n*4 + 2) + +/** + * @ingroup Common_register_group_W5300 + * @brief W5300 identification register. + * @details Read Only. 0x5300. + */ +#define IDR (_W5300_IO_BASE_ + 0xFE) +#define VERSIONR IDR + + +//----------------------------- W5300 SOCKET Registers ----------------------------- + +/** + * @ingroup Socket_register_group_W5300 + * @brief Socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + * + * + *
    15 14 13 12 11 10 9 8
    Reserved. Read as 0 ALIGN
    7 6 5 4 3 2 1 0
    MULTI MF ND/IGMPv Reserved PROTOCOL[3:0]
    + * - @ref Sn_MR_ALIGN : Alignment bit of Sn_MR, Only valid in \ref Sn_MR_TCP. (C0 : Include TCP PACK_INFO, 1 : Not include TCP PACK_INFO) + * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_MF : Enable MAC Filter (0 : Disable, 1 - Enable), When enabled, W5300 can receive only both own and broadcast packet. + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_IGMPv : IGMP version used in UDP mulitcasting. (0 : Version 2, 1 : Version 2) + * - PROTOCOL[3:0] + * + * + * + * + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 0 0 0 Closed
    0 0 0 1 TCP
    0 0 1 0 UDP
    0 0 1 1 IPCRAW
    0 1 0 0 MACRAW
    0 1 0 1 PPPoE
    + * + * - @ref Sn_MR_PPPoE : PPPoE + * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK + * - @ref Sn_MR_IPRAW : IP LAYER RAW SOCK + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x00) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. + * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + * - @ref Sn_CR_PCON : PPPoE connection begins by transmitting PPPoE discovery packet. + * - @ref Sn_CR_PDISCON : Closes PPPoE connection. + * - @ref Sn_CR_PCR : In each phase, it transmits REQ message. + * - @ref Sn_CR_PCN : In each phase, it transmits NAK message. + * - @ref Sn_CR_PCJ : In each phase, it transmits REJECT message. + */ +#define Sn_CR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x02) + +/** + * @ingroup Socket_register_group_W5300 + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is + * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +#define Sn_IMR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x04) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n + * In order to clear the @ref Sn_IR bit, the host should write the bit to \n + * + * + * + * + * + *
    15 14 13 12 11 10 9 8
    Reserved. Read as 0
    7 6 5 4 3 2 1 0
    PRECV PFAIL PNEXT SENDOK TIMEOUT RECV DISCON CON
    + * - \ref Sn_IR_PRECV : PPP receive + * - \ref Sn_IR_PFAIL : PPP fail + * - \ref Sn_IR_PNEXT : PPP next phase + * - \ref Sn_IR_SENDOK : SENDOK + * - \ref Sn_IR_TIMEOUT : TIMEOUT + * - \ref Sn_IR_RECV : RECV + * - \ref Sn_IR_DISCON : DISCON + * - \ref Sn_IR_CON : CON + */ +#define Sn_IR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x06) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Socket status register(R) + * @details @ref Sn_SSR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_IPRAW : IPRAW socket + * - @ref SOCK_MACRAW : MAC raw mode socket + * - @ref SOCK_PPPoE : PPPoE mode Socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + * - @ref SOCK_ARP : ARP request state + */ +#define Sn_SSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x08) +#define Sn_SR(n) Sn_SSR(n) ///< For Compatible ioLibrary. Refer to @ref Sn_SSR(n) + +/** + * @ingroup Socket_register_group_W5300 + * @brief source port register(R/W) + * @details @ref Sn_PORTR configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. + */ +#define Sn_PORTR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0A) +#define Sn_PORT(n) Sn_PORTR(n) ///< For compatible ioLibrary. Refer to @ref Sn_PORTR(n). + +/** + * @ingroup Socket_register_group_W5300 + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0C) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORTR configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP clientmode, it configures the listen port number of TCP serverbefore CONNECT command. + * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORTR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x12) +#define Sn_DPORT(n) Sn_DPORTR(n) ///< For compatible ioLibrary. Refer to \ref Sn_DPORTR. + + +/** + * @ingroup Socket_register_group_W5300 + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of TCP serverbefore CONNECT command. + * In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ + #define Sn_DIPR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x14) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x18) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, + * and ignored in other modes. The time unit is 5s. + * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. + * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). + * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, + * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x1A) + +/** + * @ingroup Socket_register_group_W5300 + * @brief IP Protocol(PROTO) Register(R/W) + * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is + * valid only in IPRAW mode, and ignored in other modes. + */ +#define Sn_PROTOR(n) Sn_KPALVTR(n) + + +/** + * @ingroup Socket_register_group_W5300 + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOSR configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x1C) +#define Sn_TOS(n) Sn_TOSR(n) ///< For compatible ioLibrary. Refer to Sn_TOSR + +/** + * @ingroup Socket_register_group_W5300 + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTLR configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTLR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x1E) +#define Sn_TTL(n) Sn_TTLR(n) ///< For compatible ioLibrary. Refer to Sn_TTLR + +/** + * @ingroup Socket_register_group_W5300 + * @brief SOCKETn TX write size register(R/W) + * @details It sets the byte size of the data written in internal TX memory through @ref Sn_TX_FIFOR. + * It is set before SEND or SEND_MAC command, and can't be bigger than internal TX memory + * size set by TMSR such as @ref TMS01R, TMS23R and etc. + */ +#define Sn_TX_WRSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x20) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Transmit free memory size register(R) + * @details Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by TMSR such as @ref TMS01SR. + * Data bigger than Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0024) + +/** + * @ingroup Socket_register_group_w5300 + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * @ref Sn_RX_RSR does not exceed the RMSR such as @ref RMS01SR and is calculated as the difference between + * ?Socket n RX Write Pointer (@ref Sn_RX_WR)and Socket n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x0028) + +/** + * @ingroup Socket_register_group_W5300 + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAGR configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAGR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x002C) +#define Sn_FRAG(n) Sn_FRAGR(n) + +/** + * @ingroup Socket_register_group_W5300 + * @brief SOCKET n TX FIFO regsiter + * @details It indirectly accesses internal TX memory of SOCKETn. + * The internal TX memory can't be accessed directly by the host, but can be accessed through Sn_TX_FIFOR. + * If @ref MR(MT) = '0', only the Host-Write of internal TX memory is allowed through Sn_TX_FIFOR. + * But if @ref MR(MT) is '1', both of Host-Read and Host-Write are allowed. + */ +#define Sn_TX_FIFOR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x2E) + +/** + * @ingroup Socket_register_group_W5300 + * @brief SOCKET n RX FIFO register + * @details It indirectly accesses to internal RX memory of SOCKETn. + * The internal RX memory can't be directly accessed by the host, but can be accessed through Sn_RX_FIFOR. + * If MR(MT) = '0', only the Host-Read of internal RX memory is allowed through Sn_RX_FIFOR. + * But if MR(MT) is '1', both of Host-Read and Host-Write are allowed. + */ +#define Sn_RX_FIFOR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x30) + +//#define Sn_TX_SADR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x32) + +//#define Sn_RX_SADR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x34) + +//#define Sn_TX_RD(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x36) + +//#define Sn_TX_WR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x38) + +//#define Sn_TX_ACK(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x3A) + +//#define Sn_RX_RD(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x3C) + +//#define Sn_RX_WR(n) (_W5300_IO_BASE_ + WIZCHIP_SREG_BLOCK(n) + 0x3E) + + +/************************************/ +/* The bit of MR regsiter defintion */ +/************************************/ +#define MR_DBW (1 << 15) /**< Data bus width bit of \ref MR. Read Only. (0 : 8Bit, 1 : 16Bit)*/ +#define MR_MPF (1 << 14) /**< Mac layer pause frame bit of \ref MR. (0 : Disable, 1 : Enable)*/ +#define MR_WDF(X) ((X & 0x07) << 11) /**< Write data fetch time bit of \ref MR. Fetch Data from DATA bus after PLL_CLK * MR_WDF[2:0]*/ +#define MR_RDH (1 << 10) /**< Read data hold time bit of \ref MR. Hold Data on DATA bus during 2 * PLL_CLK after CS high*/ +#define MR_FS (1 << 8) /**< FIFO swap bit of \ref MR. Swap MSB & LSB of \ref Sn_TX_FIFOR & Sn_RX_FIFOR (0 : No swap, 1 : Swap) */ +#define MR_RST (1 << 7) /**< S/W reset bit of \ref MR. (0 : Normal Operation, 1 : Reset (automatically clear after reset))*/ +#define MR_MT (1 << 5) /**< Memory test bit of \ref MR. (0 : Normal, 1 : Internal Socket memory write & read Test)*/ +#define MR_PB (1 << 4) /**< Ping block bit of \ref MR. (0 : Unblock, 1 : Block)*/ +#define MR_PPPoE (1 << 3) /**< PPPoE bit of \ref MR. (0 : No use PPPoE, 1: Use PPPoE)*/ +#define MR_DBS (1 << 2) /**< Data bus swap of \ref MR. Valid only 16bit mode (0 : No swap, 1 : Swap)*/ +#define MR_IND (1 << 0) /**< Indirect mode bit of \ref MR. (0 : Direct mode, 1 : Indirect mode) */ + + +/************************************/ +/* The bit of IR regsiter definition */ +/************************************/ +#define IR_IPCF (1 << 7) /**< IP conflict bit of \ref IR. To clear, Write the bit to '1'. */ +#define IR_DPUR (1 << 6) /**< Destination port unreachable bit of \ref IR. To clear, Write the bit to '1'. */ +#define IR_PPPT (1 << 5) /**< PPPoE terminate bit of \ref IR. To clear, Write the bit to '1'. */ +#define IR_FMTU (1 << 4) /**< Fragment MTU bit of IR. To clear, Write the bit to '1'. */ +#define IR_SnINT(n) (0x01 << n) /**< SOCKETn interrupt occurrence bit of \ref IR. To clear, Clear \ref Sn_IR*/ + +/*****************************************/ +/* The bit of Pn_BRDYR regsiter definition*/ +/*****************************************/ +#define Pn_PEN (1 << 7) /**< PIN 'BRDYn' enable bit of Pn_BRDYR. */ +#define Pn_MT (1 << 6) /**< PIN memory type bit of Pn_BRDYR. */ +#define Pn_PPL (1 << 5) /**< PIN Polarity bit of Pn_BRDYR. */ +#define Pn_SN(n) ((n & 0x07) << 0) /**< What socket to monitor. */ + + +/***************************************/ +/* The bit of Sn_MR regsiter definition */ +/***************************************/ +/** + * @brief Alignment bit of \ref Sn_MR. + * @details It is valid only in the TCP (\ref Sn_MR_TCP) with TCP communication, + * when every the received DATA packet size is of even number and set as '1', + * data receiving performance can be improved by removing PACKET-INFO(data size) that is attached to every the received DATA packet. + */ +#define Sn_MR_ALIGN (1 << 8) + +/** + * @brief Multicasting bit of \ref Sn_MR + * @details It is valid only in UDP (\ref Sn_MR_UDP). + * In order to implement multicasting, set the IP address and port number in @ref Sn_DIPR and @ref Sn_DPORTR respectively before "OPEN" command(@ref Sn_CR_OPEN).\n + * 0 : Disable, 1 : Enable + */ +#define Sn_MR_MULTI (1 << 7) + +/** + * @brief MAC filter bit of \ref Sn_MR + * @details It is valid in MACRAW(@ref Sn_MR_MACRAW). + * When this bit is set as ‘1’, W5300 can receive packet that is belong in itself or broadcasting. + * When this bit is set as ‘0’, W5300 can receive all packets on Ethernet. + * When using the hybrid TCP/IP stack, it is recommended to be set as ‘1’ for reducing the receiving overhead of host. \n + * 0 : Disable, 1 : Enable + */ +#define Sn_MR_MF (1 << 6) + +/** + * @brief IGMP version bit of \ref Sn_MR + * details It is valid in case of @ref Sn_MR_MULTI='1' and UDP(@ref Sn_MR_UDP). + * It configures IGMP version to send IGMP message such as Join/Leave/Report to multicast-group. \n + * 0 : IGMPv2, 1 : IGMPv1 + */ +#define Sn_MR_IGMPv (1 << 5) +#define Sn_MR_MC Sn_MR_IGMPv ///< For compatible ioLibrary + +/** + * @brief No delayed ack bit of \ref Sn_MR + * @details It is valid in TCP(@ref Sn_MR_TCP). + * In case that it is set as '1', ACK packet is transmitted right after receiving DATA packet from the peer. + * It is recommended to be set as '1' for TCP performance improvement. + * In case that it is set as '0', ACK packet is transmitted after the time set in @ref _RTR_ regardless of DATA packet receipt.\n + * 0 : No use, 1 : Use + */ +#define Sn_MR_ND (1 << 5) + +/** + * @brief No mode + * @details This configures the protocol mode of Socket n. + * @sa Sn_MR + */ +#define Sn_MR_CLOSE 0x00 + +/** + * @brief TCP mode + * @details This configures the protocol mode of Socket n. + * @sa Sn_MR + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief UDP mode + * @details This configures the protocol mode of Socket n. + * @sa Sn_MR + */ +#define Sn_MR_UDP 0x02 /**< Protocol bits of \ref Sn_MR. */ + +/** + * @brief IP LAYER RAW mode + * @details This configures the protocol mode of Socket n. + * @sa Sn_MR + */ +#define Sn_MR_IPRAW 0x03 /**< Protocol bits of \ref Sn_MR. */ + +/** + * @brief MAC LAYER RAW mode + * @details This configures the protocol mode of Socket 0. + * @sa Sn_MR + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +/** + * @brief PPPoE mode + * @details This configures the protocol mode of Socket 0. + * @sa Sn_MR + * @note PPPoE mode should be only used in Socket 0. + */ +#define Sn_MR_PPPoE 0x05 /**< Protocol bits of \ref Sn_MR. */ + +#define SOCK_STREAM Sn_MR_TCP /**< For Berkeley Socket API, Refer to @ref Sn_MR_TCP */ +#define SOCK_DGRAM Sn_MR_UDP /**< For Berkeley Socket API, Refer to @ref Sn_MR_UDP */ + + + +/******************************/ +/* The values of CR definition */ +/******************************/ +/** + * @brief Initialize or open a socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n + * + * + * + * + * + * + * + * + *
    \b Sn_MR (P[3:0]) \b Sn_SR
    Sn_MR_CLOSE (000)
    Sn_MR_TCP (001) SOCK_INIT (0x13)
    Sn_MR_UDP (010) SOCK_UDP (0x22)
    Sn_MR_IPRAW (010) SOCK_IPRAW (0x32)
    Sn_MR_MACRAW (100) SOCK_MACRAW (0x42)
    Sn_MR_PPPoE (101) SOCK_PPPoE (0x5F)
    + */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for connection-request (SYN packet) from any TCP client + * The @ref Sn_SR changes the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. + * When a TCP clientconnection request is successfully established, + * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes + * But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (b>Active close
    or Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, @b TCPTO occurs (\ref Sn_IR[3]='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details @ref Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND command transmits all the data in the Socket n TX buffer thru @ref Sn_TX_FIFOR.\n + * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR) and Socket TX Write Size register (@ref Sn_TX_WRSR). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND command transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC command transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer thru @ref Sn_RX_FIFOR).\n + * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR) & @ref Sn_RX_FIFOR. + */ +#define Sn_CR_RECV 0x40 /**< RECV command value of \ref Sn_CR */ + +#define Sn_CR_PCON 0x23 /**< PPPoE connection begins by transmitting PPPoE discovery packet. Refer to \ref Sn_CR */ +#define Sn_CR_PDISCON 0x24 /**< Closes PPPoE connection. Refer to \ref Sn_CR */ +#define Sn_CR_PCR 0x25 /**< In each phase, it transmits REQ message. Refer to \ref Sn_CR */ +#define Sn_CR_PCN 0x26 /**< In each phase, it transmits NAK message. Refer to \ref Sn_CR */ +#define Sn_CR_PCJ 0x27 /**< In each phase, it transmits REJECT message. Refer to \ref Sn_CR */ + + +/*********************************/ +/* The values of Sn_IR definition */ +/*********************************/ +#define Sn_IR_PRECV 0x80 /**< It is set in the case that option data which is not supported is received. Refer to \ref Sn_IR */ +#define Sn_IR_PFAIL 0x40 /**< It is set in the case that PAP authentication is failed. Refer to \ref Sn_IR */ +#define Sn_IR_PNEXT 0x20 /**< It is set in the case that the phase is changed during PPPoE connection process. \ref Sn_IR */ +#define Sn_IR_SENDOK 0x10 /**< It is set when SEND command is completed. Refer to \ref Sn_IR */ +#define Sn_IR_TIMEOUT 0x08 /**< It is set when ARPTO or TCPTO is occured. Refer to \ref Sn_IR */ +#define Sn_IR_RECV 0x04 /**< It is set whenever data is received from a peer. Refer to \ref Sn_IR */ +#define Sn_IR_DISCON 0x02 /**< It is set when FIN or FIN/ACK packet is received from a peer. Refer to \ref Sn_IR */ +#define Sn_IR_CON 0x01 /**< It is set one time when the connection is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. */ + +/**********************************/ +/* The values of Sn_SSR definition */ +/**********************************/ +/** + * @brief The state of SOCKET intialized or closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief The state of ARP process + * @details It is temporary state for getting a peer MAC address when TCP connect or UDP Data Send\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_ARP 0x01 /**< ARP-request is transmitted in order to acquire destination hardware address. */ + +/** + * @brief Initiate state in TCP. + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when \ref Sn_MR(P[3:0]) = '001' and OPEN command(\ref Sn_CR_OPEN) is ordered.\n + * After SOCK_INIT, user can use LISTEN(@ref Sn_CR_LISTEN)/CONNECT(@ref Sn_CR_CONNET) command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR_TIMEOUT = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by @ref Sn_CR_CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR_TIMEOUT = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n + * If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR_TIMEOUT = '1') is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or + * when the @ref Sn_CR_CONNECT command is successful.\n + * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using @ref Sn_CR_SEND or @ref Sn_CR_RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout(@ref Sn_CR_TIMTEOUT = '1') is occurred, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, @ref Sn_CR_DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout (@ref Sn_IR_TIMEOUT = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = '010').\n + * It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 + +/** + * @brief IP raw mode socket + * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is + * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n + * IP Packet can be transferred without a connection similar to the UDP mode. +*/ +#define SOCK_IPRAW 0x32 + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n = 0) and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0] = 100)and @ ref Sn_CR_OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 /**< SOCKET0 is open as MACRAW mode. */ + +/** + * @brief PPPoE mode socket + * @details It is the status that SOCKET0 is opened as PPPoE mode. + * It is changed to SOCK_PPPoE in case of @ref Sn_CR_OPEN command is ordered and @ref Sn_MR(P3:P0)= @ref Sn_MR_PPPoE\n + * It is temporarily used at the PPPoE connection. + */ +#define SOCK_PPPoE 0x5F /**< SOCKET0 is open as PPPoE mode. */ + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function_W5300 + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint16_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function_W5300 + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint16_t wb ); + +/*********************************** + * COMMON Register Access Function * + ***********************************/ + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set Mode Register + * @param (@ref iodata_t)mr The value to be set. + * @sa getMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) + #if (_WIZCHIP_IO_BUS_WIDTH_ == 8) + #define setMR(mr) \ + (*((uint8_t*)MR) = (uint8_t)((mr) >> 8)); (*((uint8_t*)WIZCHIP_OFFSET_INC(MR,1)) = (uint8_t)((mr) & 0xFF)) + #elif (_WIZCHIP_IO_BUS_WIDTH_ == 16) + #define setMR(mr) (*((uint16_t*)MR) = (uint16_t)((mr) & 0xFFFF)) + #else + #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. You should be define _WIZCHIP_IO_BUS_WIDTH as 8 or 16." + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_" +#endif + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref MR. + * @return @ref iodata_t. The value of Mode register. + * @sa setMR() + */ +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) + #if (_WIZCHIP_IO_BUS_WIDTH_ == 8) + #define getMR() (((uint16_t)(*((uint8_t*)MR)) << 8) + (((uint16_t)(*((uint8_t*)WIZCHIP_OFFSET_INC(MR,1)))) & 0x00FF)) + #elif(_WIZCHIP_IO_BUS_WIDTH_ == 16) + #define getMR() (*((uint16_t*)MR)) + #else + #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. You should be define _WIZCHIP_IO_BUS_WIDTH as 8 or 16." + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_" +#endif + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set \ref IR register + * @param (uint16_t)ir Value to set \ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, ir & 0xF0FF) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get \ref IR register + * @return uint8_t. Value of \ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xF0FF) + + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set \ref _IMR_ register + * @param (uint16_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(_IMR_, imr & 0xF0FF) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get \ref _IMR_ register + * @return uint16_t. Value of \ref IR register. + * @sa setIMR() + */ +#define getIMR() \ + (WIZCHIP_READ(_IMR_) & 0xF0FF) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) { \ + WIZCHIP_WRITE(SHAR, (((uint16_t)((shar)[0])) << 8) + (((uint16_t)((shar)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SHAR,2), (((uint16_t)((shar)[2])) << 8) + (((uint16_t)((shar)[3])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SHAR,4), (((uint16_t)((shar)[4])) << 8) + (((uint16_t)((shar)[5])) & 0x00FF)); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) { \ + (shar)[0] = (uint8_t)(WIZCHIP_READ(SHAR) >> 8); \ + (shar)[1] = (uint8_t)(WIZCHIP_READ(SHAR)); \ + (shar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,2)) >> 8); \ + (shar)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,2))); \ + (shar)[4] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,4)) >> 8); \ + (shar)[5] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SHAR,4))); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) { \ + WIZCHIP_WRITE(GAR, (((uint16_t)((gar)[0])) << 8) + (((uint16_t)((gar)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(GAR,2), (((uint16_t)((gar)[2])) << 8) + (((uint16_t)((gar)[3])) & 0x00FF)); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) { \ + (gar)[0] = (uint8_t)(WIZCHIP_READ(GAR) >> 8); \ + (gar)[1] = (uint8_t)(WIZCHIP_READ(GAR)); \ + (gar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(GAR,2)) >> 8); \ + (gar)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(GAR,2))); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) { \ + WIZCHIP_WRITE(SUBR, (((uint16_t)((subr)[0])) << 8) + (((uint16_t)((subr)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SUBR,2), (((uint16_t)((subr)[2])) << 8) + (((uint16_t)((subr)[3])) & 0x00FF)); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) { \ + (subr)[0] = (uint8_t)(WIZCHIP_READ(SUBR) >> 8); \ + (subr)[1] = (uint8_t)(WIZCHIP_READ(SUBR)); \ + (subr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SUBR,2)) >> 8); \ + (subr)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SUBR,2))); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) { \ + WIZCHIP_WRITE(SIPR, (((uint16_t)((sipr)[0])) << 8) + (((uint16_t)((sipr)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(SIPR,2), (((uint16_t)((sipr)[2])) << 8) + (((uint16_t)((sipr)[3])) & 0x00FF)); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) { \ + (sipr)[0] = (uint8_t)(WIZCHIP_READ(SIPR) >> 8); \ + (sipr)[1] = (uint8_t)(WIZCHIP_READ(SIPR)); \ + (sipr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SIPR,2)) >> 8); \ + (sipr)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(SIPR,2))); \ + } + + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) \ + WIZCHIP_WRITE(_RTR_, rtr) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +#define getRTR() \ + WIZCHIP_READ(_RTR_) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(_RCR_, ((uint16_t)rcr)&0x00FF) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() \ + ((uint8_t)(WIZCHIP_READ(_RCR_) & 0x00FF)) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref TMS01R register + * @param (uint16_t)tms01r Value to set @ref TMS01R register. The lower socket memory size is located at MSB of tms01r. + * @sa getTMS01R() + */ +#define setTMS01R(tms01r) \ + WIZCHIP_WRITE(TMS01R,tms01r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref TMS01R register + * @return uint16_t. Value of @ref TMS01R register. + * @sa setTMS01R() + */ +#define getTMS01R() \ + WIZCHIP_READ(TMS01R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref TMS23R register + * @param (uint16_t)tms23r Value to set @ref TMS23R register. The lower socket memory size is located at MSB of tms01r. + * @sa getTMS23R() + */ +#define setTMS23R(tms23r) \ + WIZCHIP_WRITE(TMS23R,tms23r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref TMS23R register + * @return uint16_t. Value of @ref TMS23R register. + * @sa setTMS23R() + */ +#define getTMS23R() \ + WIZCHIP_READ(TMS23R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref TMS45R register + * @param (uint16_t)tms45r Value to set @ref TMS45R register. The lower socket memory size is located at MSB of tms45r. + * @sa getTMS45R() + */ +#define setTMS45R(tms45r) \ + WIZCHIP_WRITE(TMS45R,tms45r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref TMS45R register + * @return uint16_t. Value of @ref TMS45R register. + * @sa setTMS45R() + */ +#define getTMS45R() \ + WIZCHIP_READ(TMS45R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref TMS67R register + * @param (uint16_t)tms67r Value to set @ref TMS67R register. The lower socket memory size is located at MSB of tms67r. + * @sa getTMS67R() + */ +#define setTMS67R(tms67r) \ + WIZCHIP_WRITE(TMS67R,tms67r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref TMS67R register + * @return uint16_t. Value of @ref TMS67R register. + * @sa setTMS67R() + */ +#define getTMS67R() \ + WIZCHIP_READ(TMS67R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref TMSR0 ~ @ref TMSR7 register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tmsr Value to set @ref TMSR0 ~@ref TMSR7 register. + * @sa getTMSR() + */ +void setTMSR(uint8_t sn,uint8_t tmsr); +#define setSn_TXBUF_SIZE(sn, tmsr) setTMSR(sn, tmsr) ///< For compatible ioLibrary + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref TMSR0 ~ @ref TMSR7 register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref TMSR0 ~ @ref TMSR7 + * @sa getTMSR() + */ +uint8_t getTMSR(uint8_t sn); +#define getSn_TXBUF_SIZE(sn) getTMSR(sn) ///< For compatible ioLibrary + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref RMS01R register + * @param (uint16_t)rms01r Value to set @ref RMS01R register. The lower socket memory size is located at MSB of rms01r. + * @sa getRMS01R() + */ +#define setRMS01R(rms01r) \ + WIZCHIP_WRITE(RMS01R,rms01r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref RMS01R register + * @return uint16_t. Value of @ref RMS01R register. + * @sa setRMS01R() + */ +#define getRMS01R() \ + WIZCHIP_READ(RMS01R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref RMS23R register + * @param (uint16_t)rms23r Value to set @ref RMS23R register. The lower socket memory size is located at MSB of rms01r. + * @sa getRMS23R() + */ +#define setRMS23R(rms23r) \ + WIZCHIP_WRITE(RMS23R,rms23r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref RMS23R register + * @return uint16_t. Value of @ref RMS23R register. + * @sa setRMS23R() + */ +#define getRMS23R() \ + WIZCHIP_READ(RMS23R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref RMS45R register + * @param (uint16_t)rms45r Value to set @ref RMS45R register. The lower socket memory size is located at MSB of rms45r. + * @sa getRMS45R() + */ +#define setRMS45R(rms45r) \ + WIZCHIP_WRITE(RMS45R,rms45r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref RMS45R register + * @return uint16_t. Value of @ref RMS45R register. + * @sa setRMS45R() + */ +#define getRMS45R() \ + WIZCHIP_READ(RMS45R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref RMS67R register + * @param (uint16_t)rms67r Value to set @ref RMS67R register. The lower socket memory size is located at MSB of rms67r. + * @sa getRMS67R() + */ +#define setRMS67R(rms67r) \ + WIZCHIP_WRITE(RMS67R,rms67r) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref RMS67R register + * @return uint16_t. Value of @ref RMS67R register. + * @sa setRMS67R() + */ +#define getRMS67R() \ + WIZCHIP_READ(RMS67R) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref RMS01R ~ @ref RMS67R register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rmsr Value to set @ref RMSR0 ~@ref RMSR7 register. + * @sa getTMSR() + */ +void setRMSR(uint8_t sn,uint8_t rmsr); +#define setSn_RXBUF_SIZE(sn,rmsr) setRMSR(sn, rmsr) ///< For compatible ioLibrary + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref RMS01R ~ @ref RMS67R register + * @param (uint8_t)sn Socket number. It shoudl be 0 ~ 7. + * @return uint8_t. Value of @ref RMSR0 ~ @ref RMSR7 register. + * @sa setRMSR() + */ +uint8_t getRMSR(uint8_t sn); +#define getSn_RXBUF_SIZE(sn) getRMSR(sn) ///< For compatible ioLibrary + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref MTYPER register + * @param (uint16_t)mtyper Value to set @ref MTYPER register. + * @sa getMTYPER() + */ +#define setMTYPER(mtype) \ + WIZCHIP_WRITE(MTYPER, mtype) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref MTYPER register + * @return uint16_t. Value of @ref MTYPER register. + * @sa setMTYPER() + */ +#define getMTYPER() \ + WIZCHIP_READ(MTYPER) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref RATR register + * @return uint16_t. Value of @ref PATR register. + */ +#define getPATR() \ + WIZCHIP_READ(PATR) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ((uint16_t)ptimer) & 0x00FF) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + ((uint8_t)(WIZCHIP_READ(PTIMER) & 0x00FF)) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, ((uint16_t)pmagic) & 0x00FF) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + ((uint8_t)(WIZCHIP_READ(PMAGIC) & 0x00FF)) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + */ +#define getPSIDR() \ + WIZCHIP_READ(PSIDR) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref PDHAR register + * @param (uint8_t*)pdhar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. + */ +#define getPDHAR(pdhar) { \ + (pdhar)[0] = (uint8_t)(WIZCHIP_READ(PDHAR) >> 8); \ + (pdhar)[1] = (uint8_t)(WIZCHIP_READ(PDHAR)); \ + (pdhar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,2)) >> 8); \ + (pdhar)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,2))); \ + (pdhar)[4] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,4)) >> 8); \ + (pdhar)[5] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(PDHAR,4))); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get unreachable IP address. @ref UIPR + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. + */ +#define getUIPR(uipr) { \ + (uipr)[0] = (uint8_t)(WIZCHIP_READ(UIPR) >> 8); \ + (uipr)[1] = (uint8_t)(WIZCHIP_READ(UIPR)); \ + (uipr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(UIPR,2)) >> 8); \ + (uipr)[3] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(UIPR,2))); \ + } + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +#define getUPORTR() \ + WIZCHIP_READ(UPORTR) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref FMTUR register + * @return uint16_t. Value of @ref FMTUR register. + */ +#define getFMTUR() \ + WIZCHIP_READ(FMTUR) + + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref Pn_BRDYR register + * @return uint8_t. Value of @ref Pn_BRDYR register. + */ +#define getPn_BRDYR(p) \ + ((uint8_t)(WIZCHIP_READ(Pn_BRDYR(p)) & 0x00FF)) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref Pn_BRDYR register + * @param p Pin number (p = 0,1,2,3) + * @param brdyr Set a value @ref Pn_BRDYR(p). + */ +#define setPn_BRDYR(p, brdyr) \ + WIZCHIP_WRITE(Pn_BRDYR(p), brdyr & 0x00E7) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref Pn_BDPTHR register + * @param p Pin number (p = 0,1,2,3) + * @return uint16_t. Value of @ref Pn_BDPTHR register. + */ +#define getPn_BDPTHR(p) \ + WIZCHIP_READ(Pn_BDPTHR(p)) + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Set @ref Pn_BDPTHR register + * @param p Pin number (p = 0,1,2,3) + * @param bdpthr Value of @ref Pn_BDPTHR + */ +#define setPn_BDPTHR(p, bdpthr) \ + WIZCHIP_WRITE(Pn_BDPTHR(p),bdpthr) + + +/** + * @ingroup Common_register_access_function_W5300 + * @brief Get @ref IDR register + * @return uint16_t. Always 0x5300. + */ +#define getIDR() \ + WIZCHIP_READ(IDR) + + +/*********************************** + * SOCKET Register Access Function * + ***********************************/ + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), ((uint16_t)cr) & 0x00FF) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_CR(sn))) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), ((uint16_t)imr) & 0x00FF) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_IMR(sn))) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), ((uint16_t)ir) & 0x00FF) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_IR(sn))) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SSR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_SR(sn))) +#define getSn_SR(sn) getSn_SSR(sn) ///< For compatible ioLibrary. Refer to getSn_SSR(). + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_PORTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Variable to set @ref Sn_PORTR. + * @sa getSn_PORTR() + */ +#define setSn_PORTR(sn, port) \ + WIZCHIP_WRITE(Sn_PORTR(sn), port) +#define setSn_PORT(sn, port) setSn_PORTR(sn, port) ///< For compatible ioLibrary + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_PORTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Variable of @ref Sn_PORTR. + * @sa setSn_PORTR() + */ +#define getSn_PORTR(sn) \ + WIZCHIP_READ(Sn_PORTR(sn)) +#define getSn_PORT(sn) getSn_PORTR(sn) ///< For compatible ioLibrary + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) { \ + WIZCHIP_WRITE(Sn_DHAR(sn), (((uint16_t)((dhar)[0])) << 8) + (((uint16_t)((dhar)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),2), (((uint16_t)((dhar)[0])) << 8) + (((uint16_t)((dhar)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),4), (((uint16_t)((dhar)[0])) << 8) + (((uint16_t)((dhar)[1])) & 0x00FF)); \ + } + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) { \ + (dhar)[0] = (uint8_t)(WIZCHIP_READ(Sn_DHAR(sn)) >> 8); \ + (dhar)[1] = (uint8_t) WIZCHIP_READ(Sn_DHAR(sn)); \ + (dhar)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),2)) >> 8); \ + (dhar)[3] = (uint8_t) WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),2)); \ + (dhar)[4] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),4)) >> 8); \ + (dhar)[5] = (uint8_t) WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DHAR(sn),4)); \ + } + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORTR(sn, dport) \ + WIZCHIP_WRITE(Sn_DPORTR(sn),dport) +#define setSn_DPORT(sn, dport) setSn_DPORTR(sn,dport) ///< For compatible ioLibrary. Refer to @ref Sn_DPORTR. + + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + * @note This function is not available because W5300 have a bug to read @ref Sn_DPORTR. \n + * Don't use this function. + */ +#define getSn_DPORTR(sn) \ + WIZCHIP_READ(Sn_DPORTR(sn)) +#define getSn_DPORT(sn) getSn_DPORTR(sn) ///< For compatible ioLibrary. Refer to @ref Sn_DPORTR. + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) { \ + WIZCHIP_WRITE(Sn_DIPR(sn), (((uint16_t)((dipr)[0])) << 8) + (((uint16_t)((dipr)[1])) & 0x00FF)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DIPR(sn),2), (((uint16_t)((dipr)[2])) << 8) + (((uint16_t)((dipr)[3])) & 0x00FF)); \ + } + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) { \ + (dipr)[0] = (uint8_t)(WIZCHIP_READ(Sn_DIPR(sn)) >> 8); \ + (dipr)[1] = (uint8_t) WIZCHIP_READ(Sn_DIPR(sn)); \ + (dipr)[2] = (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DIPR(sn),2)) >> 8); \ + (dipr)[3] = (uint8_t) WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DIPR(sn),2)); \ + } + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) \ + WIZCHIP_WRITE(Sn_MSSR(sn), mss) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + WIZCHIP_READ(Sn_MSSR(sn)) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), (WIZCHIP_READ(Sn_KPALVTR(sn)) & 0x00FF) | (((uint16_t)kpalvt)<<8)) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) \ + ((uint8_t)(WIZCHIP_READ(Sn_KPALVTR(sn)) >> 8)) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_PROTOR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)proto Value to set \ref Sn_PROTOR + * @sa getSn_PROTOR() + */ +#define setSn_PROTOR(sn, proto) \ + WIZCHIP_WRITE(Sn_PROTOR(sn),(WIZCHIP_READ(Sn_PROTOR(sn)) & 0xFF00) | (((uint16_t)proto) & 0x00FF)) +#define setSn_PROTO(sn,proto) setSn_PROTOR(sn,proto) ///< For compatible ioLibrary + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_PROTOR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return uint8_t. Value of @ref Sn_PROTOR. + * @sa setSn_PROTOR() + */ +#define getSn_PROTOR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_PROTOR(sn))) +#define getSn_PROTO(sn) getSn_PROTOR(sn) ///< For compatible ioLibrary + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_TX_WRSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint32_t)txwrs Value to set @ref Sn_KPALVTR (It should be <= 0x00010000) + * @sa getSn_TX_WRSR() + */ +#define setSn_TX_WRSR(sn, txwrs) { \ + WIZCHIP_WRITE(Sn_TX_WRSR(sn), (uint16_t)(((uint32_t)txwrs) >> 16)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WRSR(sn),2), (uint16_t)txwrs); \ + } + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_TX_WRSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint32_t. Value of Sn_TX_WRSR. + * @sa setSn_TX_WRSR() + */ +#define getSn_TX_WRSR(sn) \ + ( (((uint32_t)WIZCHIP_READ(Sn_TX_WRSR(sn))) << 16) + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WRSR(sn),1))) & 0x0000FFFF) ) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint32_t. Value of @ref Sn_TX_FSR. + */ +uint32_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint32_t. Value of @ref Sn_RX_RSR. + */ +uint32_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_TX_FIFOR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txfifo. Value to set @ref Sn_TX_FIFOR. + */ +#define setSn_TX_FIFOR(sn, txfifo) \ + WIZCHIP_WRITE(Sn_TX_FIFOR(sn), txfifo); + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_RX_FIFOR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_FIFOR. + */ +#define getSn_RX_FIFOR(sn) \ + WIZCHIP_READ(Sn_RX_FIFOR(sn)); + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_TOSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param (uint8_t)tos Value to set @ref Sn_TOSR + * @sa getSn_TOSR() + */ +#define setSn_TOSR(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), ((uint16_t)tos) & 0x00FF) +#define setSn_TOS(sn,tos) setSn_TOSR(sn,tos) ///< For compatible ioLibrar + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_TOSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_ . + * @return uint8_t. Value of Sn_TOSR. + * @sa setSn_TOSR() + */ +#define getSn_TOSR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_TOSR(sn))) +#define getSn_TOS(sn) getSn_TOSR(sn) ///< For compatible ioLibrar + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_TTLR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTLR + * @sa getSn_TTLR() + */ +#define setSn_TTLR(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTLR(sn), ((uint16_t)ttl) & 0x00FF) +#define setSn_TTL(sn,ttl) setSn_TTLR(sn,ttl) ///< For compatible ioLibrary + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_TTLR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTLR. + * @sa setSn_TTLR() + */ +#define getSn_TTLR(sn) \ + ((uint8_t)WIZCHIP_READ(Sn_TTL(sn))) +#define getSn_TTL(sn) getSn_TTLR(sn) ///< For compatible ioLibrary + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Set @ref Sn_FRAGR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAGR + * @sa getSn_FRAGR() + */ +#define setSn_FRAGR(sn, frag) \ + WIZCHIP_WRITE(Sn_FRAGR(sn), ((uint16_t)frag) & 0x00FF) +#define setSn_FRAG(sn,frag) setSn_FRAGR(sn,flag) + +/** + * @ingroup Socket_register_access_function_W5300 + * @brief Get @ref Sn_FRAGR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAGR. + * @sa setSn_FRAGR() + */ +#define getSn_FRAGR(sn) \ + (WIZCHIP_READ(Sn_FRAG(sn))) +#define getSn_FRAG(sn) getSn_FRAGR(sn) + + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// + +/** + * @brief Socket_register_access_function_W5300 + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint32_t. Value of Socket n RX max buffer size. + */ +#define getSn_RxMAX(sn) \ + (((uint32_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function_W5300 + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint32_t. Value of Socket n TX max buffer size. + */ +#define getSn_TxMAX(sn) \ + (((uint32_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function_W5300 + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint32_t len); + +/** + * @ingroup Basic_IO_function_W5300 + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint32_t len); + +/** + * @ingroup Basic_IO_function_W5300 + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint32_t len); + +/// \cond DOXY_APPLY_CODE +#endif +/// \endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5300_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.c new file mode 100755 index 00000000000..72ff9bef5ee --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.c @@ -0,0 +1,267 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +#if (_WIZCHIP_ == 5500) +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + } + else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + //if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation + if(!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + } + else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for(i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } + else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + if(!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for(i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } + else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if(len == 0) return; + ptr = getSn_TX_WR(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel,wizdata, len); + + ptr += len; + setSn_TX_WR(sn,ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if(len == 0) return; + ptr = getSn_RX_RD(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn,ptr); +} + + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn,ptr); +} + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.h new file mode 100755 index 00000000000..2dbd6ad9325 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/W5500/w5500.h @@ -0,0 +1,2165 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +// + +#ifndef _W5500_H_ +#define _W5500_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "wizchip_conf.h" + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5500) +/// @endcond + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address + + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function + */ + + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + + + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + + + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + + + /** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end -------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    RST Reserved WOL PB PPPoE Reserved FARP Reserved
    + * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. + * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of @ref IR defined as follows. + * + * + * + *
    7 6 5 4 3 2 1 0
    CONFLICT UNREACH PPPoE MP Reserved Reserved Reserved Reserved
    + * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ corresponds to each bit of @ref IR. + * When a bit of @ref _IMR_ is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref _IMR_ is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n + * Each bit of @ref _IMR_ defined as the following. + * + * + * + *
    7 6 5 4 3 2 1 0
    IM_IR7 IM_IR6 IM_IR5 IM_IR4 Reserved Reserved Reserved Reserved
    + * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +//M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. + * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref _RTR_ is x07D0. + * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref _RTR_, W5500 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the @ref _RTR_ time, W5500 retransmits the packet or issues timeout. + */ +//M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1'). + */ +//M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) +#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates + * the destination IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR + * indicates the destination IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + + +//----------------------------- W5500 Socket Registers IOMAP ----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + *
    7 6 5 4 3 2 1 0
    MULTI/MFEN BCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3] Protocol[2] Protocol[1] Protocol[0]
    + * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + *
    Protocol[3] Protocol[2] Protocol[1] Protocol[0] @b Meaning
    0 0 0 0 Closed
    0 0 0 1 TCP
    0 0 1 0 UDP
    0 1 0 0 MACRAW
    + * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. + * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n + * In order to clear the @ref Sn_IR bit, the host should write the bit to \n + * + * + * + *
    7 6 5 4 3 2 1 0
    Reserved Reserved Reserved SEND_OK TIMEOUT RECV DISCON CON
    + * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered. + */ +#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of TCP serverbefore CONNECT command. + * In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP clientmode, it configures the listen port number of TCP serverbefore CONNECT command. + * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +#define Sn_PROTO(N) (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. + * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between + * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is + * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, + * and ignored in other modes. The time unit is 5s. + * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. + * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). + * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, + * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + + +//----------------------------- W5500 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. + * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and + * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. + */ +#define IR_MP 0x10 + + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7<<3) +#define PHYCFGR_OPMDC_PDOWN (6<<3) +#define PHYCFGR_OPMDC_NA (5<<3) +#define PHYCFGR_OPMDC_100FA (4<<3) +#define PHYCFGR_OPMDC_100F (3<<3) +#define PHYCFGR_OPMDC_100H (2<<3) +#define PHYCFGR_OPMDC_10F (1<<3) +#define PHYCFGR_OPMDC_10H (0<<3) +#define PHYCFGR_DPX_FULL (1<<2) +#define PHYCFGR_DPX_HALF (0<<2) +#define PHYCFGR_SPD_100 (1<<1) +#define PHYCFGR_SPD_10 (0<<1) +#define PHYCFGR_LNK_ON (1<<0) +#define PHYCFGR_LNK_OFF (0<<0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m + * In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref _RTR_. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to itself. + * When this bit is W5500 can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n + * + * + * + * + * + * + *
    \b Sn_MR (P[3:0]) \b Sn_SR
    Sn_MR_CLOSE (000)
    Sn_MR_TCP (001) SOCK_INIT (0x13)
    Sn_MR_UDP (010) SOCK_UDP (0x22)
    S0_MR_MACRAW (100) SOCK_MACRAW (0x02)
    + */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for connection-request (SYN packet) from any TCP client + * The @ref Sn_SR changes the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. + * When a TCP clientconnection request is successfully established, + * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes + * But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON command processes the disconnect-process (b>Active close
    or Passive close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN command is ordered.\n + * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to @ref SOCK_CLOSED after TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n + * If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = '010').\n + * It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 + +#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) \ + WIZCHIP_WRITE(MR,mr) + + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() \ + WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR, subr,4) + + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) {\ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ + } + + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +//M20150401 : Type explict declaration +/* +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +*/ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) \ + WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() \ + WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) \ + WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() \ + WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +//M20150401 : Type explict declaration +/* +#define getRTR() \ + ((WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) +*/ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) + + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(_RCR_) + +//================================================== test done =========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHAR address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) {\ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +//uint16_t getPSID(void); +//M20150401 : Type explict declaration +/* +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) +*/ +#define getPSID() \ + (((uint16_t)WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +//M20150401 : Type explict declaration +/* +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) +*/ +#define getPMRU() \ + (((uint16_t)WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. + */ +//M20150401 : Size Error of UIPR (6 -> 4) +/* +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) +*/ +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,4) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +//M20150401 : Type explict declaration +/* +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) +*/ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) \ + WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() \ + WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() \ + WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +//M20150401 : Type explict declaration +/* +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) +*/ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +//M20150401 : Type explict declaration +/* +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) +*/ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +//M20150401 : Type explict declaration +/* +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) +*/ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +//M20150401 : Type explict declaration +/* +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) +*/ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +//M20150401 : Type explict declaration +/* +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) +*/ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +//M20150401 : Type explict declaration +/* +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) +*/ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +//M20150401 : Type explict declaration +/* +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) +*/ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +//M20150401 : Type explict declaration +/* +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) +*/ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +//M20150401 : Type explict declaration +/* +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) +*/ +#define getSn_RxMAX(sn) \ + (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +//M20150401 : Type explict declaration +/* +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) +*/ +#define getSn_TxMAX(sn) \ + (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of len(variable) bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) bytes. + * This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5500_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.c new file mode 100755 index 00000000000..412a65d6d1d --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.c @@ -0,0 +1,931 @@ +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address. +//! Copy 4 byte addr value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +//M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; + +//M20150601 : For extern decleation +//static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +// + +#if _WIZCHIP_ == 5200 + static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; +#endif + +//A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data() +#endif + + +#define CHECK_SOCKNUM() \ + do{ \ + if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + }while(0); \ + +#define CHECK_SOCKMODE(mode) \ + do{ \ + if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + }while(0); \ + +#define CHECK_SOCKINIT() \ + do{ \ + if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + }while(0); \ + +#define CHECK_SOCKDATA() \ + do{ \ + if(len == 0) return SOCKERR_DATALEN; \ + }while(0); \ + + + +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) +{ + CHECK_SOCKNUM(); + switch(protocol) + { + case Sn_MR_TCP : + { + //M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t*)&taddr); + if(taddr == 0) return SOCKERR_SOCKINIT; + break; + } + case Sn_MR_UDP : + case Sn_MR_MACRAW : + case Sn_MR_IPRAW : + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_PPPoE : + break; + #endif + default : + return SOCKERR_SOCKMODE; + } + //M20150601 : For SF_TCP_ALIGN & W5300 + //if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if(flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if(flag != 0) + { + switch(protocol) + { + case Sn_MR_TCP: + //M20150601 : For SF_TCP_ALIGN & W5300 + #if _WIZCHIP_ == 5300 + if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG; + #else + if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; + #endif + + break; + case Sn_MR_UDP: + if(flag & SF_IGMP_VER2) + { + if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; + } + #if _WIZCHIP_ == 5500 + if(flag & SF_UNI_BLOCK) + { + if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } + #endif + break; + default: + break; + } + } + close(sn); + //M20150601 + #if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) ); + #else + setSn_MR(sn, (protocol | (flag & 0xF0))); + #endif + if(!port) + { + port = sock_any_port++; + if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn,port); + setSn_CR(sn,Sn_CR_OPEN); + while(getSn_CR(sn)); + //A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 < sn + //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) ) + if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) ) + { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~ + //socket(s,Sn_MR_UDP,0x3000,0); + //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1). + setSn_MR(sn,Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn,Sn_CR_OPEN); + while(getSn_CR(sn) != 0); + while(getSn_SR(sn) != SOCK_UDP); + sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn,Sn_CR_CLOSE); + /* wait to process the command... */ + while( getSn_CR(sn) ); + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + //A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1< freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + } + wiz_send_data(sn, buf, len); + #if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; + #endif + + #if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn,len); + #endif + + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + sock_is_sending |= (1 << sn); + //M20150409 : Explicit Type Casting + //return len; + return (int32_t)len; +} + + +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) +{ + uint8_t tmp = 0; + uint16_t recvsize = 0; +//A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif +// + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if(recvsize < len) len = recvsize; + +//A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + //sock_pack_info[sn] = PACK_COMPLETED; // for clear + if(sock_remained_size[sn] == 0) + { +#endif +// + while(1) + { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) + { + if(tmp == SOCK_CLOSE_WAIT) + { + if(recvsize != 0) break; + else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } + else + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if((sock_io_mode & (1< sock_remained_size[sn]) len = sock_remained_size[sn]; + recvsize = len; + if(sock_pack_info[sn] & PACK_FIFOBYTE) + { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if(recvsize != 0) + { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + } + sock_remained_size[sn] -= recvsize; + if(sock_remained_size[sn] != 0) + { + sock_pack_info[sn] |= PACK_REMAINED; + if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; + } + else sock_pack_info[sn] = PACK_COMPLETED; + if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; + //len = recvsize; +#else + if(recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); +#endif + + //M20150409 : Explicit Type Casting + //return len; + return (int32_t)len; +} + +int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) +{ + uint8_t tmp = 0; + uint16_t freesize = 0; + uint32_t taddr; + + CHECK_SOCKNUM(); + switch(getSn_MR(sn) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_MACRAW: +// break; +// #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + break; +// #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + //M20140501 : For avoiding fatal error on memory align mismatched + //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + //uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_IPINVALID; + if((port == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); +//#if ( _WIZCHIP_ < 5200 ) + if((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) return SOCKERR_SOCKSTATUS; +//#else +// if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; +//#endif + + setSn_DIPR(sn,addr); + setSn_DPORT(sn,port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1< freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + + #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t*)&taddr); + if(taddr == 0) + { + getSUBR((uint8_t*)&taddr); + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + } + else taddr = 0; + #endif + +//A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif +// + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + while(1) + { + tmp = getSn_IR(sn); + if(tmp & Sn_IR_SENDOK) + { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + //M:20131104 + //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if(tmp & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + //M20150409 : Fixed the lost of sign bits by type casting. + //len = (uint16_t)SOCKERR_TIMEOUT; + //break; + #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if(taddr) setSUBR((uint8_t*)&taddr); + #endif + return SOCKERR_TIMEOUT; + } + //////////// + } + #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if(taddr) setSUBR((uint8_t*)&taddr); + #endif + //M20150409 : Explicit Type Casting + //return len; + return (int32_t)len; +} + + + +int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) +{ +//M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif +// + uint8_t head[8]; + uint16_t pack_len=0; + + CHECK_SOCKNUM(); + //CHECK_SOCKMODE(Sn_MR_UDP); +//A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch((mr=getSn_MR(sn)) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_MACRAW: + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_PPPoE: + break; + #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if(sock_remained_size[sn] == 0) + { + while(1) + { + pack_len = getSn_RX_RSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1< 1514) + { + close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn,buf,pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 6); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + //M20150401 : For Typing Error + //sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + //#endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn,Sn_CR_RECV); + /* wait to process the command... */ + while(getSn_CR(sn)) ; + sock_remained_size[sn] -= pack_len; + //M20150601 : + //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if(sock_remained_size[sn] != 0) + { + sock_pack_info[sn] |= PACK_REMAINED; + #if _WIZCHIP_ == 5300 + if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; + #endif + } + else sock_pack_info[sn] = PACK_COMPLETED; +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + //M20150409 : Explicit Type Casting + //return pack_len; + return (int32_t)pack_len; +} + + +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) +{ + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch(cstype) + { + case CS_SET_IOMODE: + tmp = *((uint8_t*)arg); + if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1< explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t*)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t*)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t*)arg) = getSn_IR(sn); + break; + #if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTMASK: + *((uint8_t*)arg) = getSn_IMR(sn); + break; + #endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg) +{ + // M20131220 : Remove warning + //uint8_t tmp; + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_TTL: + setSn_TTL(sn,*(uint8_t*)arg); + break; + case SO_TOS: + setSn_TOS(sn,*(uint8_t*)arg); + break; + case SO_MSS: + setSn_MSSR(sn,*(uint16_t*)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t*)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); + #if _WIZCHIP_ > 5200 + if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; + #endif + setSn_CR(sn,Sn_CR_SEND_KEEP); + while(getSn_CR(sn) != 0) + { + // M20131220 + //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; + #if !( (_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200) ) + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn,*(uint8_t*)arg); + break; + #endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg) +{ + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_FLAG: + *(uint8_t*)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t*) arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t*) arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t*) arg = getSn_MSSR(sn); + break; + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + *(uint16_t*) arg = getSn_DPORT(sn); + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t*) arg = getSn_KPALVTR(sn); + break; + #endif + case SO_SENDBUF: + *(uint16_t*) arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t*) arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t*) arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if(getSn_MR(sn) & Sn_MR_TCP) + *(uint16_t*)arg = getSn_RX_RSR(sn); + else + *(uint16_t*)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + //CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if((getSn_MR(sn) == Sn_MR_TCP)) + return SOCKERR_SOCKMODE; +#endif + *(uint8_t*)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.h new file mode 100755 index 00000000000..72469a77b7d --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/socket.h @@ -0,0 +1,489 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface. + * But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + *
    API WIZnet Berkeley
    socket() O O
    bind() X O
    listen() O O
    connect() O O
    accept() X O
    recv() O O
    send() O O
    recvfrom() O O
    sendto() O O
    closesocket() O
    close() & disconnect()
    O
    + * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, + * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n + * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. + * When the listen SOCKET accepts a connection request from a client, it keeps listening. + * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n + * Following figure shows network flow diagram by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n + * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, + * it is changed in order to communicate with the client. + * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n + * If there're many listen SOCKET with same listen port number and a client requests a connection, + * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus + extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet +#define SF_IGMP_VER2 (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 + #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 + #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 + #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 + #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 +#endif + +//A201505 : For W5300 +#if _WIZCHIP_ == 5300 + #define SF_TCP_ALIGN 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied) +#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied) +#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied) +//A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n + * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned immediately\n + */ +int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n + * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n + * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n + * In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer. \n + * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n + * Even if the connectionless socket has been previously connected to a specific address, + * the address and port number parameters override the destination address for that particular datagram only. + * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than len. + * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n + * This function is used to receive UDP and MAC_RAW mode, and handle the header as well. + * This function can divide to received the packet data. + * On the MACRAW SOCKET, the addr and port parameters are ignored. + * @note In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer + * In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet sized. + * When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * It is valid only when the first call recvfrom for receiving the packet. + * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the packet. +* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); + + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum +{ + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + //M20150410 : Remove the comma of last member + //SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +}sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum +{ + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind +#if _WIZCHIP_ > 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100 +#endif +}ctlsock_type; + + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum +{ + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100 + #if !( (_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200) ) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200 + #endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode. +}sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. + * Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. \n + * + * + * + * + * + *
    @b cstype @b data type@b value
    @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
    @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 ~ 16K
    @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind @ref SIK_CONNECTED, etc.
    + * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + * + * + * + * + *
    @b sotype @b data type@b value
    @ref SO_TTL uint8_t 0 ~ 255
    @ref SO_TOS uint8_t 0 ~ 255
    @ref SO_MSS uint16_t 0 ~ 65535
    @ref SO_DESTIP uint8_t[4]
    @ref SO_DESTPORT uint16_t 0 ~ 65535
    @ref SO_KEEPALIVESEND null null
    @ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
    + * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n + */ +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    @b sotype @b data type@b value
    @ref SO_FLAG uint8_t @ref SF_ETHER_OWN, etc...
    @ref SO_TOS uint8_t 0 ~ 255
    @ref SO_MSS uint16_t 0 ~ 65535
    @ref SO_DESTIP uint8_t[4]
    @ref SO_DESTPORT uint16_t
    @ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
    @ref SO_SENDBUF uint16_t 0 ~ 65535
    @ref SO_RECVBUF uint16_t 0 ~ 65535
    @ref SO_STATUS uint8_t @ref SOCK_ESTABLISHED, etc..
    @ref SO_REMAINSIZE uint16_t 0~ 65535
    @ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc...
    + * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n + * When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, + * This means the zero byte UDP data(UDP Header only) received. + */ +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +#ifdef __cplusplus + } +#endif + +#endif // _SOCKET_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.c new file mode 100755 index 00000000000..4b0e0ff756f --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.c @@ -0,0 +1,842 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* +//! For remove the warning when pointer type size is not 32bit. +//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +//A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +//M20150401 : Remove ; in the default callback function such as wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) { +} + +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) { +} + +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) { +} + +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) { +} + +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//M20150601 : Rename the function for integrating with W5300 +//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return *((volatile iodata_t*)((ptrdiff_t)AddrSel)); +} + +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//M20150601 : Rename the function for integrating with W5300 +//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t*)((ptrdiff_t)AddrSel)) = wb; +} + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//uint8_t wizchip_spi_readbyte(void) {return 0;}; +// uint8_t wizchip_spi_readbyte(void) { +// return 0; +// } + +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_spi_writebyte(uint8_t wb) {}; +//void wizchip_spi_writebyte(uint8_t wb) {} + +/** + * @brief Default function to burst read in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +// void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) { +// } + +/** + * @brief Default function to burst write in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +//void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +// void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) { +// } + +/** + * @\ref _WIZCHIP instance + */ +// +//M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of array +// +/* +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = { + _WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + {wizchip_cris_enter, wizchip_cris_exit}, + {wizchip_cs_select, wizchip_cs_deselect}, + { + {//M20150601 : Rename the function + //wizchip_bus_readbyte, + //wizchip_bus_writebyte + wizchip_bus_readdata, + wizchip_bus_writedata}, + + }}; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)) { + if(!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)) { + if(!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +//M20150515 : For integrating with W5300 +//void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc( + iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)) + ; + //M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if(!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)) { + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if(!spi_rb || !spi_wb) { + // WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + // WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc( + void (*spi_rb)(uint8_t* pBuf, uint16_t len), + void (*spi_wb)(uint8_t* pBuf, uint16_t len)) { + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if(!spi_rb || !spi_wb) { + // WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + // WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) { +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + uint8_t tmp = 0; +#endif + uint8_t* ptmp[2] = {0, 0}; + switch(cwtype) { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if(arg != 0) { + ptmp[0] = (uint8_t*)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind*)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind*)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind*)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind*)arg) = wizchip_getinterruptmask(); + break; +//M20150601 : This can be supported by W5200, W5500 +//#if _WIZCHIP_ > W5100 +#if(_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t*)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t*)arg = getINTLEVEL(); + break; +#endif + case CW_GET_ID: + ((uint8_t*)arg)[0] = WIZCHIP.id[0]; + ((uint8_t*)arg)[1] = WIZCHIP.id[1]; + ((uint8_t*)arg)[2] = WIZCHIP.id[2]; + ((uint8_t*)arg)[3] = WIZCHIP.id[3]; + ((uint8_t*)arg)[4] = WIZCHIP.id[4]; + ((uint8_t*)arg)[5] = WIZCHIP.id[5]; + ((uint8_t*)arg)[6] = 0; + break; +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t*)arg); +#endif +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) { + switch(cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo*)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo*)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type*)arg); + case CN_GET_NETMODE: + *(netmode_type*)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout*)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout*)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; +//A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); + getSUBR(sn); + getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay +//A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if(txsize) { + tmp = 0; +//M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if(txsize[i] >= 64) + return -1; //No use 64KB even if W5300 support max 64KB memory allocation + tmp += txsize[i]; + if(tmp > 128) return -1; + } + if(tmp % 8) return -1; +#else + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 //2016.10.28 peter add condition for w5100 and w5100s + if(tmp > 8) return -1; +#else + if(tmp > 16) return -1; +#endif + } + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 //2016.10.28 peter add condition for w5100 + j = 0; + while((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + +#endif + } + + if(rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if(rxsize[i] >= 64) + return -1; //No use 64KB even if W5300 support max 64KB memory allocation + tmp += rxsize[i]; + if(tmp > 128) return -1; + } + if(tmp % 8) return -1; +#else + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 //2016.10.28 peter add condition for w5100 and w5100s + if(tmp > 8) return -1; +#else + if(tmp > 16) return -1; +#endif + } + + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } +#endif + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); +//A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + //M20200227 : For clear + //setSIR(sir); + for(ir = 0; ir < 8; ir++) { + if(sir & (0x01 << ir)) setSn_IR(ir, 0xff); + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; +//A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + +//M20150601 : For Integrating with W5300 +//#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); +//A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; +//A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if(getPHYSR() & PHYSR_LNK) tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5200 + if(getPHYSTATUS() & PHYSTATUS_LINK) tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5500 + if(getPHYCFGR() & PHYCFGR_LNK_ON) tmp = PHY_LINK_ON; + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if(getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#elif _WIZCHIP_ == 5500 + if((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while(wiz_mdio_read(PHYMDIO_BMCR) & BMCR_RESET) { + } +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if(phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= BMCR_AUTONEGO; + else { + tmp &= ~BMCR_AUTONEGO; + if(phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if(phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if(tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if(tmp & BMCR_DUP) + phyconf->duplex = PHY_DUPLEX_FULL; + else + phyconf->duplex = PHY_DUPLEX_HALF; + if(tmp & BMCR_SPEED) + phyconf->speed = PHY_SPEED_100; + else + phyconf->speed = PHY_SPEED_10; + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if(pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if(pmode == PHY_POWER_DOWN) { + if(tmp & BMCR_PWDN) return 0; + } else { + if((tmp & BMCR_PWDN) != BMCR_PWDN) return 0; + } + return -1; +} + +#endif +#if _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) { + uint8_t tmp = 0; + if(phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if(phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else { + if(phyconf->duplex == PHY_DUPLEX_FULL) { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } else { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch(tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf* phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if((tmp & PHYCFGR_OPMD) == 0) return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if(pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if(pmode == PHY_POWER_DOWN) { + if(tmp & PHYCFGR_OPMDC_PDOWN) return 0; + } else { + if(tmp & PHYCFGR_OPMDC_ALLA) return 0; + } + return -1; +} +#endif + +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1; +#else + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { + return (netmode_type)getMR(); +} + +void wizchip_settimeout(wiz_NetTimeout* nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout* nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.h new file mode 100755 index 00000000000..a5d65f7e4fc --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/wizchip_conf.h @@ -0,0 +1,661 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b W5500 or etc. \n\n + * ex> #define \_WIZCHIP_ W5500 + */ + +#define W5100 5100 +#define W5100S 5100+5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 + +#ifndef _WIZCHIP_ +#define _WIZCHIP_ W5500 // W5100, W5100S, W5200, W5300, W5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ (_WIZCHIP_IO_MODE_SPI_ + 3) /**< SPI interface mode for fixed length data mode*/ + +#if (_WIZCHIP_ == W5100) + #define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +//A20150601 : Define the unit of IO DATA. + typedef uint8_t iodata_t; +//A20150401 : Indclude W5100.h file + #include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** +* @brief Define interface mode. +* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ +*/ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +//A20150601 : Define the unit of IO DATA. + typedef uint8_t iodata_t; +//A20150401 : Indclude W5100.h file + #include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) + #define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +//A20150601 : Define the unit of IO DATA. + typedef uint8_t iodata_t; + #include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) + #define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + */ +#ifndef _WIZCHIP_IO_MODE_ + //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#endif +//A20150601 : Define the unit of IO DATA. + typedef uint8_t iodata_t; + #include "W5500/w5500.h" +#elif ( _WIZCHIP_ == W5300) + #define _WIZCHIP_ID_ "W5300\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +//A20150601 : Define the unit and bus width of IO DATA. + /** + * @brief Select the data width 8 or 16 bits. + * @todo you should select the bus width. Select one of 8 or 16. + */ + #ifndef _WIZCHIP_IO_BUS_WIDTH_ + #define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 + #endif + #if _WIZCHIP_IO_BUS_WIDTH_ == 8 + typedef uint8_t iodata_t; + #elif _WIZCHIP_IO_BUS_WIDTH_ == 16 + typedef uint16_t iodata_t; + #else + #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." + #endif +// + #include "W5300/w5300.h" +#else + #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ + #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n + * ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +// #define _WIZCHIP_IO_BASE_ 0x60000000 // for 5100S IND + #define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ + #define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif + +//M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ + #ifndef _WIZCHIP_IO_BASE_ + #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." + #endif +#endif + +#if _WIZCHIP_ >= W5200 + #define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else + #define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + + +/******************************************************** +* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. +*********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP +{ + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS + { + void (*_enter) (void); ///< crtical section enter + void (*_exit) (void); ///< critial section exit + }CRIS; + /** + * The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS + { + void (*_select) (void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + }CS; + /** + * The set of interface IO callback func. + */ + union _IF + { + /** + * For BUS interface IO + */ + //M20156501 : Modify the function name for integrating with W5300 + //struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct + { + iodata_t (*_read_data) (uint32_t AddrSel); + void (*_write_data) (uint32_t AddrSel, iodata_t wb); + }BUS; + + /** + * For SPI interface IO + */ + struct + { + uint8_t (*_read_byte) (void); + void (*_write_byte) (uint8_t wb); + void (*_read_burst) (uint8_t* pBuf, uint16_t len); + void (*_write_burst) (uint8_t* pBuf, uint16_t len); + }SPI; + // To be added + // + }IF; +}_WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum +{ + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + +//D20150601 : For no modification your application code +//#if _WIZCHIP_ == W5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500 + CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only W5500 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500 +//#endif +//D20150601 : For no modification your application code +//#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only W5100, W5200 + CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200 +//#endif +}ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum +{ + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +}ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum +{ +#if _WIZCHIP_ == W5500 + IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +}intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500, + * and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n + * Valid only in W5500. + */ +typedef struct wiz_PhyConf_t +{ + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF + }wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum +{ + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +}dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t +{ + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +}wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum +{ +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500 +#endif + NM_WAKEONLAN = (1<<5), ///< Wake On Lan + NM_PINGBLOCK = (1<<4), ///< Block ping-request + NM_PPPOE = (1<<3), ///< PPPoE mode +}netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. + */ +typedef struct wiz_NetTimeout_t +{ + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +}wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such as + *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. + *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); + + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +//M20150601 : For integrating with W5300 +//void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte using SPI + *@param spi_wb : callback function to write byte using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to burst read using SPI + *@param spi_wb : callback function to burst write using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), + * controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n + * 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); + + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +//todo +#if _WIZCHIP_ > W5100 + int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100 + int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 +/** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_setphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphystat(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ + int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** +* @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout* nettime); +#ifdef __cplusplus + } +#endif + +#endif // _WIZCHIP_CONF_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.c new file mode 100755 index 00000000000..dee271032da --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.c @@ -0,0 +1,991 @@ +//***************************************************************************** +// +//! \file dhcp.c +//! \brief DHCP APIs implement file. +//! \details Processing DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.1 +//! \date 2019/10/08 +//! \par Revision history +//! <2019/10/08> compare DHCP server ip address +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Optimize code +//! 2. Add reg_dhcp_cbfunc() +//! 3. Add DHCP_stop() +//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() +//! 5. Don't care system endian +//! 6. Add comments +//! <2012/12/26> V1.1.1 +//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "socket.h" +#include "dhcp.h" + +/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ + +#ifdef _DHCP_DEBUG_ +#include +#endif + +#define _DHCP_DEBUG_ + +/* DHCP state machine. */ +#define STATE_DHCP_INIT 0 ///< Initialize +#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER +#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK +#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased +#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP +#define STATE_DHCP_RELEASE 5 ///< No use +#define STATE_DHCP_STOP 6 ///< Stop processing DHCP + +#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG +#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG + +/* DHCP message OP code */ +#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG +#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG + +/* DHCP message type */ +#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG +#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG +#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG +#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG +#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG +#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG +#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use +#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use + +#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG +#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG + +#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG +#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG +#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG + +#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time + +#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG +#define RIP_MSG_SIZE (236 + OPT_SIZE) /// Max size of @ref RIP_MSG + +/* + * @brief DHCP option and value (cf. RFC1533) + */ +enum { + padOption = 0, + subnetMask = 1, + timerOffset = 2, + routersOnSubnet = 3, + timeServer = 4, + nameServer = 5, + dns = 6, + logServer = 7, + cookieServer = 8, + lprServer = 9, + impressServer = 10, + resourceLocationServer = 11, + hostName = 12, + bootFileSize = 13, + meritDumpFile = 14, + domainName = 15, + swapServer = 16, + rootPath = 17, + extentionsPath = 18, + IPforwarding = 19, + nonLocalSourceRouting = 20, + policyFilter = 21, + maxDgramReasmSize = 22, + defaultIPTTL = 23, + pathMTUagingTimeout = 24, + pathMTUplateauTable = 25, + ifMTU = 26, + allSubnetsLocal = 27, + broadcastAddr = 28, + performMaskDiscovery = 29, + maskSupplier = 30, + performRouterDiscovery = 31, + routerSolicitationAddr = 32, + staticRoute = 33, + trailerEncapsulation = 34, + arpCacheTimeout = 35, + ethernetEncapsulation = 36, + tcpDefaultTTL = 37, + tcpKeepaliveInterval = 38, + tcpKeepaliveGarbage = 39, + nisDomainName = 40, + nisServers = 41, + ntpServers = 42, + vendorSpecificInfo = 43, + netBIOSnameServer = 44, + netBIOSdgramDistServer = 45, + netBIOSnodeType = 46, + netBIOSscope = 47, + xFontServer = 48, + xDisplayManager = 49, + dhcpRequestedIPaddr = 50, + dhcpIPaddrLeaseTime = 51, + dhcpOptionOverload = 52, + dhcpMessageType = 53, + dhcpServerIdentifier = 54, + dhcpParamRequest = 55, + dhcpMsg = 56, + dhcpMaxMsgSize = 57, + dhcpT1value = 58, + dhcpT2value = 59, + dhcpClassIdentifier = 60, + dhcpClientIdentifier = 61, + endOption = 255 +}; + +/* + * @brief DHCP message format + */ +typedef struct { + uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY + uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB + uint8_t hlen; ///< @ref DHCP_HLENETHERNET + uint8_t hops; ///< @ref DHCP_HOPS + uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. + uint16_t secs; ///< @ref DHCP_SECS + uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST + uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever + uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server + uint8_t siaddr[4]; ///< No use + uint8_t giaddr[4]; ///< No use + uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero + uint8_t sname[64]; ///< No use + uint8_t file[128]; ///< No use + uint8_t OPT[OPT_SIZE]; ///< Option +} RIP_MSG; + +uint8_t DHCP_SOCKET; // Socket number for DHCP + +uint8_t DHCP_SIP[4]; // DHCP Server IP address +uint8_t DHCP_REAL_SIP[4]; // For extract my DHCP server in a few DHCP server + +// Network information from DHCP Server +uint8_t OLD_allocated_ip[4] = { + 0, +}; // Previous IP address +uint8_t DHCP_allocated_ip[4] = { + 0, +}; // IP address from DHCP +uint8_t DHCP_allocated_gw[4] = { + 0, +}; // Gateway address from DHCP +uint8_t DHCP_allocated_sn[4] = { + 0, +}; // Subnet mask from DHCP +uint8_t DHCP_allocated_dns[4] = { + 0, +}; // DNS address from DHCP + +int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state +int8_t dhcp_retry_count = 0; + +uint32_t dhcp_lease_time = INFINITE_LEASETIME; +volatile uint32_t dhcp_tick_1s = 0; // unit 1 second +uint32_t dhcp_tick_next = DHCP_WAIT_TIME; + +uint32_t DHCP_XID; // Any number + +RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing + +uint8_t HOST_NAME[] = DCHP_HOST_NAME; + +uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. + +/* The default callback function */ +void default_ip_assign(void); +void default_ip_update(void); +void default_ip_conflict(void); + +/* Callback handler */ +void (*dhcp_ip_assign)(void) = + default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ +void (*dhcp_ip_update)(void) = + default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ +void (*dhcp_ip_conflict)(void) = + default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ + +char NibbleToHex(uint8_t nibble); + +/* send DISCOVER message to DHCP server */ +void send_DHCP_DISCOVER(void); + +/* send REQEUST message to DHCP server */ +void send_DHCP_REQUEST(void); + +/* send DECLINE message to DHCP server */ +void send_DHCP_DECLINE(void); + +/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ +int8_t check_DHCP_leasedIP(void); + +/* check the timeout in DHCP process */ +uint8_t check_DHCP_timeout(void); + +/* Initialize to timeout process. */ +void reset_DHCP_timeout(void); + +/* Parse message as OFFER and ACK and NACK from DHCP server.*/ +int8_t parseDHCPCMSG(void); + +/* The default handler of ip assign first */ +void default_ip_assign(void) { + setSIPR(DHCP_allocated_ip); + setSUBR(DHCP_allocated_sn); + setGAR(DHCP_allocated_gw); +} + +/* The default handler of ip changed */ +void default_ip_update(void) { + /* WIZchip Software Reset */ + setMR(MR_RST); + getMR(); // for delay + default_ip_assign(); + setSHAR(DHCP_CHADDR); +} + +/* The default handler of ip changed */ +void default_ip_conflict(void) { + // WIZchip Software Reset + setMR(MR_RST); + getMR(); // for delay + setSHAR(DHCP_CHADDR); +} + +/* register the call back func. */ +void reg_dhcp_cbfunc(void (*ip_assign)(void), void (*ip_update)(void), void (*ip_conflict)(void)) { + dhcp_ip_assign = default_ip_assign; + dhcp_ip_update = default_ip_update; + dhcp_ip_conflict = default_ip_conflict; + if(ip_assign) dhcp_ip_assign = ip_assign; + if(ip_update) dhcp_ip_update = ip_update; + if(ip_conflict) dhcp_ip_conflict = ip_conflict; +} + +/* make the common DHCP message */ +void makeDHCPMSG(void) { + uint8_t bk_mac[6]; + uint8_t* ptmp; + uint8_t i; + getSHAR(bk_mac); + pDHCPMSG->op = DHCP_BOOTREQUEST; + pDHCPMSG->htype = DHCP_HTYPE10MB; + pDHCPMSG->hlen = DHCP_HLENETHERNET; + pDHCPMSG->hops = DHCP_HOPS; + ptmp = (uint8_t*)(&pDHCPMSG->xid); + *(ptmp + 0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); + *(ptmp + 1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); + *(ptmp + 2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); + *(ptmp + 3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); + pDHCPMSG->secs = DHCP_SECS; + ptmp = (uint8_t*)(&pDHCPMSG->flags); + *(ptmp + 0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); + *(ptmp + 1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); + + pDHCPMSG->ciaddr[0] = 0; + pDHCPMSG->ciaddr[1] = 0; + pDHCPMSG->ciaddr[2] = 0; + pDHCPMSG->ciaddr[3] = 0; + + pDHCPMSG->yiaddr[0] = 0; + pDHCPMSG->yiaddr[1] = 0; + pDHCPMSG->yiaddr[2] = 0; + pDHCPMSG->yiaddr[3] = 0; + + pDHCPMSG->siaddr[0] = 0; + pDHCPMSG->siaddr[1] = 0; + pDHCPMSG->siaddr[2] = 0; + pDHCPMSG->siaddr[3] = 0; + + pDHCPMSG->giaddr[0] = 0; + pDHCPMSG->giaddr[1] = 0; + pDHCPMSG->giaddr[2] = 0; + pDHCPMSG->giaddr[3] = 0; + + pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; + pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; + pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; + pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; + pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; + pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; + + for(i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; + for(i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; + for(i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; + + // MAGIC_COOKIE + pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); + pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); + pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); + pDHCPMSG->OPT[3] = (uint8_t)(MAGIC_COOKIE & 0x000000FF) >> 0; +} + +/* SEND DHCP DISCOVER */ +void send_DHCP_DISCOVER(void) { + uint16_t i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + DHCP_SIP[0] = 0; + DHCP_SIP[1] = 0; + DHCP_SIP[2] = 0; + DHCP_SIP[3] = 0; + DHCP_REAL_SIP[0] = 0; + DHCP_REAL_SIP[1] = 0; + DHCP_REAL_SIP[2] = 0; + DHCP_REAL_SIP[3] = 0; + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DISCOVER; + + // Client identifier + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname + for(i = 0; HOST_NAME[i] != 0; i++) pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); + pDHCPMSG->OPT[k - (i + 6 + 1)] = i + 6; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x06; // length of request + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = endOption; + + for(i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + // send broadcasting packet + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + +#ifdef _DHCP_DEBUG_ + eth_printf("> Send DHCP_DISCOVER"); +#endif + sendto(DHCP_SOCKET, (uint8_t*)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* SEND DHCP REQUEST */ +void send_DHCP_REQUEST(void) { + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) { + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00) >> 8); + *((uint8_t*)(&pDHCPMSG->flags) + 1) = (DHCP_FLAGSUNICAST & 0x00FF); + pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; + pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; + pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; + pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; + ip[0] = DHCP_SIP[0]; + ip[1] = DHCP_SIP[1]; + ip[2] = DHCP_SIP[2]; + ip[3] = DHCP_SIP[3]; + } else { + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + } + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_REQUEST; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) + { + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + } + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // length of hostname + for(i = 0; HOST_NAME[i] != 0; i++) pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); + pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); + pDHCPMSG->OPT[k - (i + 6 + 1)] = i + 6; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x08; + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = performRouterDiscovery; + pDHCPMSG->OPT[k++] = staticRoute; + pDHCPMSG->OPT[k++] = endOption; + + for(i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + +#ifdef _DHCP_DEBUG_ + eth_printf("> Send DHCP_REQUEST"); +#endif + + sendto(DHCP_SOCKET, (uint8_t*)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* SEND DHCP DHCPDECLINE */ +void send_DHCP_DECLINE(void) { + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00) >> 8); + *((uint8_t*)(&pDHCPMSG->flags) + 1) = (DHCP_FLAGSUNICAST & 0x00FF); + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DECLINE; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + + pDHCPMSG->OPT[k++] = endOption; + + for(i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + //send broadcasting packet + ip[0] = 0xFF; + ip[1] = 0xFF; + ip[2] = 0xFF; + ip[3] = 0xFF; + +#ifdef _DHCP_DEBUG_ + eth_printf("\r\n> Send DHCP_DECLINE"); +#endif + + sendto(DHCP_SOCKET, (uint8_t*)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* PARSE REPLY pDHCPMSG */ +int8_t parseDHCPMSG(void) { + uint8_t svr_addr[6]; + uint16_t svr_port; + uint16_t len; + + uint8_t* p; + uint8_t* e; + uint8_t type = 0; + uint8_t opt_len; + + if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) { + len = recvfrom(DHCP_SOCKET, (uint8_t*)pDHCPMSG, len, svr_addr, &svr_port); +#ifdef _DHCP_DEBUG_ + eth_printf( + "DHCP message : %d.%d.%d.%d(%d) %d received.", + svr_addr[0], + svr_addr[1], + svr_addr[2], + svr_addr[3], + svr_port, + len); +#endif + } else + return 0; + + if(svr_port == DHCP_SERVER_PORT) { + // compare mac address + if((pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || + (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || + (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5])) { +#ifdef _DHCP_DEBUG_ + eth_printf("No My DHCP Message. This message is ignored."); +#endif + return 0; + } + //compare DHCP server ip address + if((DHCP_SIP[0] != 0) || (DHCP_SIP[1] != 0) || (DHCP_SIP[2] != 0) || (DHCP_SIP[3] != 0)) { + if(((svr_addr[0] != DHCP_SIP[0]) || (svr_addr[1] != DHCP_SIP[1]) || + (svr_addr[2] != DHCP_SIP[2]) || (svr_addr[3] != DHCP_SIP[3])) && + ((svr_addr[0] != DHCP_REAL_SIP[0]) || (svr_addr[1] != DHCP_REAL_SIP[1]) || + (svr_addr[2] != DHCP_REAL_SIP[2]) || (svr_addr[3] != DHCP_REAL_SIP[3]))) { +#ifdef _DHCP_DEBUG_ + eth_printf("Another DHCP sever send a response message. This is ignored."); +#endif + return 0; + } + } + p = (uint8_t*)(&pDHCPMSG->op); + p = p + + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) + e = p + (len - 240); + + while(p < e) { + switch(*p) { + case endOption: + p = e; // for break while(p < e) + break; + case padOption: + p++; + break; + case dhcpMessageType: + p++; + p++; + type = *p++; + break; + case subnetMask: + p++; + p++; + DHCP_allocated_sn[0] = *p++; + DHCP_allocated_sn[1] = *p++; + DHCP_allocated_sn[2] = *p++; + DHCP_allocated_sn[3] = *p++; + break; + case routersOnSubnet: + p++; + opt_len = *p++; + DHCP_allocated_gw[0] = *p++; + DHCP_allocated_gw[1] = *p++; + DHCP_allocated_gw[2] = *p++; + DHCP_allocated_gw[3] = *p++; + p = p + (opt_len - 4); + break; + case dns: + p++; + opt_len = *p++; + DHCP_allocated_dns[0] = *p++; + DHCP_allocated_dns[1] = *p++; + DHCP_allocated_dns[2] = *p++; + DHCP_allocated_dns[3] = *p++; + p = p + (opt_len - 4); + break; + case dhcpIPaddrLeaseTime: + p++; + opt_len = *p++; + dhcp_lease_time = *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; +#ifdef _DHCP_DEBUG_ + dhcp_lease_time = 10; +#endif + break; + case dhcpServerIdentifier: + p++; + opt_len = *p++; + DHCP_SIP[0] = *p++; + DHCP_SIP[1] = *p++; + DHCP_SIP[2] = *p++; + DHCP_SIP[3] = *p++; + DHCP_REAL_SIP[0] = svr_addr[0]; + DHCP_REAL_SIP[1] = svr_addr[1]; + DHCP_REAL_SIP[2] = svr_addr[2]; + DHCP_REAL_SIP[3] = svr_addr[3]; + break; + default: + p++; + opt_len = *p++; + p += opt_len; + break; + } // switch + } // while + } // if + return type; +} + +uint8_t DHCP_run(void) { + uint8_t type; + uint8_t ret; + + if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; + + if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + + ret = DHCP_RUNNING; + type = parseDHCPMSG(); + + switch(dhcp_state) { + case STATE_DHCP_INIT: + DHCP_allocated_ip[0] = 0; + DHCP_allocated_ip[1] = 0; + DHCP_allocated_ip[2] = 0; + DHCP_allocated_ip[3] = 0; + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + case STATE_DHCP_DISCOVER: + if(type == DHCP_OFFER) { +#ifdef _DHCP_DEBUG_ + eth_printf("> Receive DHCP_OFFER"); +#endif + DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; + DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; + DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; + DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; + + send_DHCP_REQUEST(); + dhcp_state = STATE_DHCP_REQUEST; + } else { + ret = check_DHCP_timeout(); + } + break; + case STATE_DHCP_REQUEST: + if(type == DHCP_ACK) { +#ifdef _DHCP_DEBUG_ + eth_printf("> Receive DHCP_ACK"); +#endif + if(check_DHCP_leasedIP()) { + // Network info assignment from DHCP + dhcp_ip_assign(); + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else { + // IP address conflict occurred + reset_DHCP_timeout(); + dhcp_ip_conflict(); + dhcp_state = STATE_DHCP_INIT; + } + } else if(type == DHCP_NAK) { +#ifdef _DHCP_DEBUG_ + eth_printf("> Receive DHCP_NACK"); +#endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_DISCOVER; + } else { + ret = check_DHCP_timeout(); + } + break; + case STATE_DHCP_LEASED: + ret = DHCP_IP_LEASED; + if((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time / 2) < dhcp_tick_1s)) { +#ifdef _DHCP_DEBUG_ + eth_printf("> Maintains the IP address "); +#endif + type = 0; + OLD_allocated_ip[0] = DHCP_allocated_ip[0]; + OLD_allocated_ip[1] = DHCP_allocated_ip[1]; + OLD_allocated_ip[2] = DHCP_allocated_ip[2]; + OLD_allocated_ip[3] = DHCP_allocated_ip[3]; + DHCP_XID++; + send_DHCP_REQUEST(); + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_REREQUEST; + } + break; + case STATE_DHCP_REREQUEST: + ret = DHCP_IP_LEASED; + if(type == DHCP_ACK) { + dhcp_retry_count = 0; + if(OLD_allocated_ip[0] != DHCP_allocated_ip[0] || + OLD_allocated_ip[1] != DHCP_allocated_ip[1] || + OLD_allocated_ip[2] != DHCP_allocated_ip[2] || + OLD_allocated_ip[3] != DHCP_allocated_ip[3]) { + ret = DHCP_IP_CHANGED; + dhcp_ip_update(); +#ifdef _DHCP_DEBUG_ + eth_printf(">IP changed."); +#endif + } +#ifdef _DHCP_DEBUG_ + else + eth_printf(">IP is continued."); +#endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else if(type == DHCP_NAK) { +#ifdef _DHCP_DEBUG_ + eth_printf("> Receive DHCP_NACK, Failed to maintain ip"); +#endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_DISCOVER; + } else + ret = check_DHCP_timeout(); + break; + default: + break; + } + return ret; +} + +void DHCP_stop(void) { + close(DHCP_SOCKET); + dhcp_state = STATE_DHCP_STOP; +} + +uint8_t check_DHCP_timeout(void) { + uint8_t ret = DHCP_RUNNING; + + if(dhcp_retry_count < MAX_DHCP_RETRY) { + if(dhcp_tick_next < dhcp_tick_1s) { + switch(dhcp_state) { + case STATE_DHCP_DISCOVER: + // eth_printf("<> state : STATE_DHCP_DISCOVER"); + send_DHCP_DISCOVER(); + break; + + case STATE_DHCP_REQUEST: + // eth_printf("<> state : STATE_DHCP_REQUEST"); + + send_DHCP_REQUEST(); + break; + + case STATE_DHCP_REREQUEST: + // eth_printf("<> state : STATE_DHCP_REREQUEST"); + + send_DHCP_REQUEST(); + break; + + default: + break; + } + + dhcp_tick_1s = 0; + dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; + dhcp_retry_count++; + } + } else { // timeout occurred + + switch(dhcp_state) { + case STATE_DHCP_DISCOVER: + dhcp_state = STATE_DHCP_INIT; + ret = DHCP_FAILED; + break; + case STATE_DHCP_REQUEST: + case STATE_DHCP_REREQUEST: + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + default: + break; + } + reset_DHCP_timeout(); + } + return ret; +} + +int8_t check_DHCP_leasedIP(void) { + uint8_t tmp; + int32_t ret; + + //WIZchip RCR value changed for ARP Timeout count control + tmp = getRCR(); + setRCR(0x03); + + // IP conflict detection : ARP request - ARP reply + // Broadcasting ARP Request for check the IP conflict using UDP sendto() function + ret = sendto(DHCP_SOCKET, (uint8_t*)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + + // RCR value restore + setRCR(tmp); + + if(ret == SOCKERR_TIMEOUT) { + // UDP send Timeout occurred : allocated IP address is unique, DHCP Success + +#ifdef _DHCP_DEBUG_ + eth_printf("\r\n> Check leased IP - OK"); +#endif + + return 1; + } else { + // Received ARP reply or etc : IP address conflict occur, DHCP Failed + send_DHCP_DECLINE(); + + ret = dhcp_tick_1s; + while((dhcp_tick_1s - ret) < 2) + ; // wait for 1s over; wait to complete to send DECLINE message; + + return 0; + } +} + +void DHCP_init(uint8_t s, uint8_t* buf) { + uint8_t zeroip[4] = {0, 0, 0, 0}; + getSHAR(DHCP_CHADDR); + if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | + DHCP_CHADDR[5]) == 0x00) { + // assigning temporary mac address, you should be set SHAR before call this function. + DHCP_CHADDR[0] = 0x00; + DHCP_CHADDR[1] = 0x08; + DHCP_CHADDR[2] = 0xdc; + DHCP_CHADDR[3] = 0x00; + DHCP_CHADDR[4] = 0x00; + DHCP_CHADDR[5] = 0x00; + setSHAR(DHCP_CHADDR); + } + + DHCP_SOCKET = s; // SOCK_DHCP + pDHCPMSG = (RIP_MSG*)buf; + DHCP_XID = 0x12345678; + { + DHCP_XID += DHCP_CHADDR[3]; + DHCP_XID += DHCP_CHADDR[4]; + DHCP_XID += DHCP_CHADDR[5]; + DHCP_XID += (DHCP_CHADDR[3] ^ DHCP_CHADDR[4] ^ DHCP_CHADDR[5]); + } + // WIZchip Netinfo Clear + setSIPR(zeroip); + setGAR(zeroip); + + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_INIT; +} + +/* Reset the DHCP timeout count and retry count. */ +void reset_DHCP_timeout(void) { + dhcp_tick_1s = 0; + dhcp_tick_next = DHCP_WAIT_TIME; + dhcp_retry_count = 0; +} + +void DHCP_time_handler(void) { + dhcp_tick_1s++; +} + +void getIPfromDHCP(uint8_t* ip) { + ip[0] = DHCP_allocated_ip[0]; + ip[1] = DHCP_allocated_ip[1]; + ip[2] = DHCP_allocated_ip[2]; + ip[3] = DHCP_allocated_ip[3]; +} + +void getGWfromDHCP(uint8_t* ip) { + ip[0] = DHCP_allocated_gw[0]; + ip[1] = DHCP_allocated_gw[1]; + ip[2] = DHCP_allocated_gw[2]; + ip[3] = DHCP_allocated_gw[3]; +} + +void getSNfromDHCP(uint8_t* ip) { + ip[0] = DHCP_allocated_sn[0]; + ip[1] = DHCP_allocated_sn[1]; + ip[2] = DHCP_allocated_sn[2]; + ip[3] = DHCP_allocated_sn[3]; +} + +void getDNSfromDHCP(uint8_t* ip) { + ip[0] = DHCP_allocated_dns[0]; + ip[1] = DHCP_allocated_dns[1]; + ip[2] = DHCP_allocated_dns[2]; + ip[3] = DHCP_allocated_dns[3]; +} + +uint32_t getDHCPLeasetime(void) { + return dhcp_lease_time; +} + +char NibbleToHex(uint8_t nibble) { + nibble &= 0x0F; + if(nibble <= 9) + return nibble + '0'; + else + return nibble + ('A' - 0x0A); +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.h new file mode 100755 index 00000000000..7d57dbfd9ef --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DHCP/dhcp.h @@ -0,0 +1,159 @@ +//***************************************************************************** +// +//! \file dhcp.h +//! \brief DHCP APIs Header file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.1 +//! \date 2019/10/08 +//! \par Revision history +//! <2019/10/08> compare DHCP server ip address +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Move unreferenced DEFINE to dhcp.c +//! <2012/12/26> V1.1.1 +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#ifndef _DHCP_H_ +#define _DHCP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @brief + * @details If you want to display debug & processing message, Define _DHCP_DEBUG_ + * @note If defined, it depends on + */ +#define _DHCP_DEBUG_ + +/* Retry to processing DHCP */ +#define MAX_DHCP_RETRY 3 ///< Maximum retry count +#define DHCP_WAIT_TIME 7 ///< Wait Time 10s + +/* UDP port numbers for DHCP */ +#define DHCP_SERVER_PORT 67 ///< DHCP server port number +#define DHCP_CLIENT_PORT 68 ///< DHCP client port number + +#define MAGIC_COOKIE 0x63825363 ///< You should not modify it number. + +#define DCHP_HOST_NAME "WIZnet\0" + +/* + * @brief return value of @ref DHCP_run() + */ +enum { + DHCP_FAILED = 0, ///< Processing Fail + DHCP_RUNNING, ///< Processing DHCP protocol + DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) + DHCP_IP_CHANGED, ///< Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update) + DHCP_IP_LEASED, ///< Stand by + DHCP_STOPPED ///< Stop processing DHCP protocol +}; + +/* + * @brief DHCP client initialization (outside of the main loop) + * @param s - socket number + * @param buf - buffer for processing DHCP message + */ +void DHCP_init(uint8_t s, uint8_t* buf); + +/* + * @brief DHCP 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DHCP_time_handler(void); + +/* + * @brief Register call back function + * @param ip_assign - callback func when IP is assigned from DHCP server first + * @param ip_update - callback func when IP is changed + * @param ip_conflict - callback func when the assigned IP is conflict with others. + */ +void reg_dhcp_cbfunc(void (*ip_assign)(void), void (*ip_update)(void), void (*ip_conflict)(void)); + +/* + * @brief DHCP client in the main loop + * @return The value is as the follow \n + * @ref DHCP_FAILED \n + * @ref DHCP_RUNNING \n + * @ref DHCP_IP_ASSIGN \n + * @ref DHCP_IP_CHANGED \n + * @ref DHCP_IP_LEASED \n + * @ref DHCP_STOPPED \n + * + * @note This function is always called by you main task. + */ +uint8_t DHCP_run(void); + +/* + * @brief Stop DHCP processing + * @note If you want to restart. call DHCP_init() and DHCP_run() + */ +void DHCP_stop(void); + +/* Get Network information assigned from DHCP server */ +/* + * @brief Get IP address + * @param ip - IP address to be returned + */ +void getIPfromDHCP(uint8_t* ip); +/* + * @brief Get Gateway address + * @param ip - Gateway address to be returned + */ +void getGWfromDHCP(uint8_t* ip); +/* + * @brief Get Subnet mask value + * @param ip - Subnet mask to be returned + */ +void getSNfromDHCP(uint8_t* ip); +/* + * @brief Get DNS address + * @param ip - DNS address to be returned + */ +void getDNSfromDHCP(uint8_t* ip); + +/* + * @brief Get the leased time by DHCP sever + * @return unit 1s + */ +uint32_t getDHCPLeasetime(void); + +void eth_printf(const char* format, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* _DHCP_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.c new file mode 100755 index 00000000000..ce7b8dda291 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.c @@ -0,0 +1,564 @@ +//***************************************************************************** +// +//! \file dns.c +//! \brief DNS APIs Implement file. +//! \details Send DNS query & Receive DNS reponse. \n +//! It depends on stdlib.h & string.h in ansi-c library +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Remove the unused define +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include +#include + +#include "socket.h" +#include "dns.h" + +#ifdef _DNS_DEBUG_ + #include +#endif + +#define INITRTT 2000L /* Initial smoothed response time */ +#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */ + +#define TYPE_A 1 /* Host address */ +#define TYPE_NS 2 /* Name server */ +#define TYPE_MD 3 /* Mail destination (obsolete) */ +#define TYPE_MF 4 /* Mail forwarder (obsolete) */ +#define TYPE_CNAME 5 /* Canonical name */ +#define TYPE_SOA 6 /* Start of Authority */ +#define TYPE_MB 7 /* Mailbox name (experimental) */ +#define TYPE_MG 8 /* Mail group member (experimental) */ +#define TYPE_MR 9 /* Mail rename name (experimental) */ +#define TYPE_NULL 10 /* Null (experimental) */ +#define TYPE_WKS 11 /* Well-known sockets */ +#define TYPE_PTR 12 /* Pointer record */ +#define TYPE_HINFO 13 /* Host information */ +#define TYPE_MINFO 14 /* Mailbox information (experimental)*/ +#define TYPE_MX 15 /* Mail exchanger */ +#define TYPE_TXT 16 /* Text strings */ +#define TYPE_ANY 255 /* Matches any type */ + +#define CLASS_IN 1 /* The ARPA Internet */ + +/* Round trip timing parameters */ +#define AGAIN 8 /* Average RTT gain = 1/8 */ +#define LAGAIN 3 /* Log2(AGAIN) */ +#define DGAIN 4 /* Mean deviation gain = 1/4 */ +#define LDGAIN 2 /* log2(DGAIN) */ + +/* Header for all domain messages */ +struct dhdr +{ + uint16_t id; /* Identification */ + uint8_t qr; /* Query/Response */ +#define QUERY 0 +#define RESPONSE 1 + uint8_t opcode; +#define IQUERY 1 + uint8_t aa; /* Authoratative answer */ + uint8_t tc; /* Truncation */ + uint8_t rd; /* Recursion desired */ + uint8_t ra; /* Recursion available */ + uint8_t rcode; /* Response code */ +#define NO_ERROR 0 +#define FORMAT_ERROR 1 +#define SERVER_FAIL 2 +#define NAME_ERROR 3 +#define NOT_IMPL 4 +#define REFUSED 5 + uint16_t qdcount; /* Question count */ + uint16_t ancount; /* Answer count */ + uint16_t nscount; /* Authority (name server) count */ + uint16_t arcount; /* Additional record count */ +}; + + +uint8_t* pDNSMSG; // DNS message buffer +uint8_t DNS_SOCKET; // SOCKET number for DNS +uint16_t DNS_MSGID; // DNS message ID + +uint32_t dns_1s_tick; // for timout of DNS processing +static uint8_t retry_count; + +/* converts uint16_t from network buffer to a host byte order integer. */ +uint16_t get16(uint8_t * s) +{ + uint16_t i; + i = *s++ << 8; + i = i + *s; + return i; +} + +/* copies uint16_t to the network buffer with network byte order. */ +uint8_t * put16(uint8_t * s, uint16_t i) +{ + *s++ = i >> 8; + *s++ = i; + return s; +} + + +/* + * CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM + * + * Description : This function converts a compressed domain name to the human-readable form + * Arguments : msg - is a pointer to the reply message + * compressed - is a pointer to the domain name in reply message. + * buf - is a pointer to the buffer for the human-readable form name. + * len - is the MAX. size of buffer. + * Returns : the length of compressed message + */ +int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len) +{ + uint16_t slen; /* Length of current segment */ + uint8_t * cp; + int clen = 0; /* Total length of compressed name */ + int indirect = 0; /* Set if indirection encountered */ + int nseg = 0; /* Total number of segments in name */ + + cp = compressed; + + for (;;) + { + slen = *cp++; /* Length of this segment */ + + if (!indirect) clen++; + + if ((slen & 0xc0) == 0xc0) + { + if (!indirect) + clen++; + indirect = 1; + /* Follow indirection */ + cp = &msg[((slen & 0x3f)<<8) + *cp]; + slen = *cp++; + } + + if (slen == 0) /* zero length == all done */ + break; + + len -= slen + 1; + + if (len < 0) return -1; + + if (!indirect) clen += slen; + + while (slen-- != 0) *buf++ = (char)*cp++; + *buf++ = '.'; + nseg++; + } + + if (nseg == 0) + { + /* Root name; represent as single dot */ + *buf++ = '.'; + len--; + } + + *buf++ = '\0'; + len--; + + return clen; /* Length of compressed message */ +} + +/* + * PARSE QUESTION SECTION + * + * Description : This function parses the qeustion record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the qeustion record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_question(uint8_t * msg, uint8_t * cp) +{ + int len; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + + if (len == -1) return 0; + + cp += len; + cp += 2; /* type */ + cp += 2; /* class */ + + return cp; +} + + +/* + * PARSE ANSER SECTION + * + * Description : This function parses the answer record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the answer record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns) +{ + int len, type; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + if (len == -1) return 0; + + cp += len; + type = get16(cp); + cp += 2; /* type */ + cp += 2; /* class */ + cp += 4; /* ttl */ + cp += 2; /* len */ + + + switch (type) + { + case TYPE_A: + /* Just read the address directly into the structure */ + ip_from_dns[0] = *cp++; + ip_from_dns[1] = *cp++; + ip_from_dns[2] = *cp++; + ip_from_dns[3] = *cp++; + break; + case TYPE_CNAME: + case TYPE_MB: + case TYPE_MG: + case TYPE_MR: + case TYPE_NS: + case TYPE_PTR: + /* These types all consist of a single domain name */ + /* convert it to ascii format */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_HINFO: + len = *cp++; + cp += len; + + len = *cp++; + cp += len; + break; + case TYPE_MX: + cp += 2; + /* Get domain name of exchanger */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_SOA: + /* Get domain name of name server */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + /* Get domain name of responsible person */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + cp += 4; + cp += 4; + cp += 4; + cp += 4; + cp += 4; + break; + case TYPE_TXT: + /* Just stash */ + break; + default: + /* Ignore */ + break; + } + + return cp; +} + +/* + * PARSE THE DNS REPLY + * + * Description : This function parses the reply message from DNS server. + * Arguments : dhdr - is a pointer to the header for DNS message + * buf - is a pointer to the reply message. + * len - is the size of reply message. + * Returns : -1 - Domain name lenght is too big + * 0 - Fail (Timout or parse error) + * 1 - Success, + */ +int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns) +{ + uint16_t tmp; + uint16_t i; + uint8_t * msg; + uint8_t * cp; + + msg = pbuf; + memset(pdhdr, 0, sizeof(*pdhdr)); + + pdhdr->id = get16(&msg[0]); + tmp = get16(&msg[2]); + if (tmp & 0x8000) pdhdr->qr = 1; + + pdhdr->opcode = (tmp >> 11) & 0xf; + + if (tmp & 0x0400) pdhdr->aa = 1; + if (tmp & 0x0200) pdhdr->tc = 1; + if (tmp & 0x0100) pdhdr->rd = 1; + if (tmp & 0x0080) pdhdr->ra = 1; + + pdhdr->rcode = tmp & 0xf; + pdhdr->qdcount = get16(&msg[4]); + pdhdr->ancount = get16(&msg[6]); + pdhdr->nscount = get16(&msg[8]); + pdhdr->arcount = get16(&msg[10]); + + + /* Now parse the variable length sections */ + cp = &msg[12]; + + /* Question section */ + for (i = 0; i < pdhdr->qdcount; i++) + { + cp = dns_question(msg, cp); + #ifdef _DNS_DEUBG_ + printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h"); + #endif + if(!cp) return -1; + } + + /* Answer section */ + for (i = 0; i < pdhdr->ancount; i++) + { + cp = dns_answer(msg, cp, ip_from_dns); + #ifdef _DNS_DEUBG_ + printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h"); + #endif + if(!cp) return -1; + } + + /* Name server (authority) section */ + for (i = 0; i < pdhdr->nscount; i++) + { + ; + } + + /* Additional section */ + for (i = 0; i < pdhdr->arcount; i++) + { + ; + } + + if(pdhdr->rcode == 0) return 1; // No error + else return 0; +} + + +/* + * MAKE DNS QUERY MESSAGE + * + * Description : This function makes DNS query message. + * Arguments : op - Recursion desired + * name - is a pointer to the domain name. + * buf - is a pointer to the buffer for DNS message. + * len - is the MAX. size of buffer. + * Returns : the pointer to the DNS message. + */ +int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len) +{ + uint8_t *cp; + char *cp1; + char sname[MAXCNAME]; + char *dname; + uint16_t p; + uint16_t dlen; + + cp = buf; + + DNS_MSGID++; + cp = put16(cp, DNS_MSGID); + p = (op << 11) | 0x0100; /* Recursion desired */ + cp = put16(cp, p); + cp = put16(cp, 1); + cp = put16(cp, 0); + cp = put16(cp, 0); + cp = put16(cp, 0); + + strcpy(sname, name); + dname = sname; + dlen = strlen(dname); + for (;;) + { + /* Look for next dot */ + cp1 = strchr(dname, '.'); + + if (cp1 != NULL) len = cp1 - dname; /* More to come */ + else len = dlen; /* Last component */ + + *cp++ = len; /* Write length of component */ + if (len == 0) break; + + /* Copy component up to (but not including) dot */ + strncpy((char *)cp, dname, len); + cp += len; + if (cp1 == NULL) + { + *cp++ = 0; /* Last one; write null and finish */ + break; + } + dname += len+1; + dlen -= len+1; + } + + cp = put16(cp, 0x0001); /* type */ + cp = put16(cp, 0x0001); /* class */ + + return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf))); +} + +/* + * CHECK DNS TIMEOUT + * + * Description : This function check the DNS timeout + * Arguments : None. + * Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur + * Note : timeout : retry count and timer both over. + */ + +int8_t check_DNS_timeout(void) +{ + + if(dns_1s_tick >= DNS_WAIT_TIME) + { + dns_1s_tick = 0; + if(retry_count >= MAX_DNS_RETRY) { + retry_count = 0; + return -1; // timeout occurred + } + retry_count++; + return 0; // timer over, but no timeout + } + + return 1; // no timer over, no timeout occur +} + + + +/* DNS CLIENT INIT */ +void DNS_init(uint8_t s, uint8_t * buf) +{ + DNS_SOCKET = s; // SOCK_DNS + pDNSMSG = buf; // User's shared buffer + DNS_MSGID = DNS_MSG_ID; +} + +/* DNS CLIENT RUN */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns) +{ + int8_t ret; + struct dhdr dhp; + uint8_t ip[4]; + uint16_t len, port; + int8_t ret_check_timeout; + + retry_count = 0; + dns_1s_tick = 0; + + // Socket open + socket(DNS_SOCKET, Sn_MR_UDP, 0, 0); + +#ifdef _DNS_DEBUG_ + printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + + len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE); + sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + + while (1) + { + if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0) + { + if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE; + len = recvfrom(DNS_SOCKET, pDNSMSG, len, ip, &port); + #ifdef _DNS_DEBUG_ + printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len); + #endif + ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns); + break; + } + // Check Timeout + ret_check_timeout = check_DNS_timeout(); + if (ret_check_timeout < 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + close(DNS_SOCKET); + return 0; // timeout occurred + } + else if (ret_check_timeout == 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Timeout\r\n"); +#endif + sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + } + } + close(DNS_SOCKET); + // Return value + // 0 > : failed / 1 - success + return ret; +} + + +/* DNS TIMER HANDLER */ +void DNS_time_handler(void) +{ + dns_1s_tick++; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.h new file mode 100755 index 00000000000..1eab1f91b2b --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/DNS/dns.h @@ -0,0 +1,109 @@ +//***************************************************************************** +// +//! \file dns.h +//! \brief DNS APIs Header file. +//! \details Send DNS query & Receive DNS reponse. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Move the no reference define to dns.c +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _DNS_H_ +#define _DNS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/* + * @brief Define it for Debug & Monitor DNS processing. + * @note If defined, it dependens on + */ +//#define _DNS_DEBUG_ + +#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */ +/* + * @brief Maxium length of your queried Domain name + * @todo SHOULD BE defined it equal as or greater than your Domain name lenght + null character(1) + * @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack. + */ +#define MAX_DOMAIN_NAME 128 // for example "www.google.com" + +#define MAX_DNS_RETRY 2 ///< Requery Count +#define DNS_WAIT_TIME 3 ///< Wait response time. unit 1s. + +#define IPPORT_DOMAIN 53 ///< DNS server port number + +#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modifyed it any number +/* + * @brief DNS process initialize + * @param s : Socket number for DNS + * @param buf : Buffer for DNS message + */ +void DNS_init(uint8_t s, uint8_t * buf); + +/* + * @brief DNS process + * @details Send DNS query and receive DNS response + * @param dns_ip : DNS server ip + * @param name : Domain name to be queryed + * @param ip_from_dns : IP address from DNS server + * @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n + * 0 : failed (Timeout or Parse error)\n + * 1 : success + * @note This funtion blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME + */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns); + +/* + * @brief DNS 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DNS_time_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _DNS_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.c new file mode 100755 index 00000000000..6c3592093c8 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.c @@ -0,0 +1,584 @@ +#include "ftpc.h" + +un_l2cval remote_ip; +uint16_t remote_port; +un_l2cval local_ip; +uint16_t local_port; +uint8_t connect_state_control_ftpc = 0; +uint8_t connect_state_data_ftpc = 0; +uint8_t gModeActivePassiveflag = 0; +uint8_t FTP_destip[4] = {192, 168, 10, 230}; // For FTP client examples; destination network info +uint16_t FTP_destport = 21; // For FTP client examples; destination network info +uint8_t gMenuStart = 0; +uint8_t gDataSockReady = 0; +uint8_t gDataPutGetStart = 0; +static uint8_t gMsgBuf[20]={0,}; + +struct ftpc ftpc; +struct Command Command; + +void ftpc_init(uint8_t * src_ip) +{ + ftpc.dsock_mode = ACTIVE_MODE; + + local_ip.cVal[0] = src_ip[0]; + local_ip.cVal[1] = src_ip[1]; + local_ip.cVal[2] = src_ip[2]; + local_ip.cVal[3] = src_ip[3]; + local_port = 35000; + strcpy(ftpc.workingdir, "/"); + socket(CTRL_SOCK, Sn_MR_TCP, FTP_destport, 0x0); +} +uint8_t ftpc_run(uint8_t * dbuf) +{ +#ifndef Need_UARTGetCharBlocking_func + uint16_t size = 0; + long ret = 0; + uint32_t send_byte, recv_byte; + uint32_t blocklen; + uint32_t remain_filesize; + uint32_t remain_datasize; + uint8_t msg_c; + uint8_t dat[50]={0,}; + uint32_t totalSize = 0, availableSize = 0; + + switch(getSn_SR(CTRL_SOCK)) + { + case SOCK_ESTABLISHED : + if(!connect_state_control_ftpc){ + printf("%d:FTP Connected\r\n", CTRL_SOCK); + strcpy(ftpc.workingdir, "/"); + connect_state_control_ftpc = 1; + } + if(gMenuStart){ + gMenuStart = 0; + printf("\r\n----------------------------------------\r\n"); + printf("Press menu key\r\n"); + printf("----------------------------------------\r\n"); + printf("1> View FTP Server Directory\r\n"); + printf("2> View My Directory\r\n"); + printf("3> Sets the type of file to be transferred. Current state : %s\r\n", (ftpc.type==ASCII_TYPE)?"Ascii":"Binary"); + printf("4> Sets Data Connection. Current state : %s\r\n", (ftpc.dsock_mode==ACTIVE_MODE)?"Active":"Passive"); + printf("5> Put File to Server\r\n"); + printf("6> Get File from Server\r\n"); +#if defined(F_FILESYSTEM) + printf("7> Delete My File\r\n"); +#endif + printf("----------------------------------------\r\n"); + while(1){ + msg_c=ftp_getc(); + if(msg_c=='1'){ + if(ftpc.dsock_mode==PASSIVE_MODE){ + sprintf(dat,"PASV\r\n"); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + Command.First = f_dir; + break; + } + else{ + wiz_NetInfo gWIZNETINFO; + ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO); + sprintf(dat,"PORT %d,%d,%d,%d,%d,%d\r\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], (uint8_t)(local_port>>8), (uint8_t)(local_port&0x00ff)); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + Command.First = f_dir; + + gModeActivePassiveflag = 1; + break; + } + break; + } + else if(msg_c=='5'){ + if(ftpc.dsock_mode==PASSIVE_MODE){ + sprintf(dat,"PASV\r\n"); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + Command.First = f_put; + break; + } + else{ + wiz_NetInfo gWIZNETINFO; + ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO); + sprintf(dat,"PORT %d,%d,%d,%d,%d,%d\r\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], (uint8_t)(local_port>>8), (uint8_t)(local_port&0x00ff)); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + Command.First = f_put; + + gModeActivePassiveflag = 1; + break; + } + } + else if(msg_c=='6'){ + if(ftpc.dsock_mode==PASSIVE_MODE){ + sprintf(dat,"PASV\r\n"); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + Command.First = f_get; + break; + } + else{ + wiz_NetInfo gWIZNETINFO; + ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO); + sprintf(dat,"PORT %d,%d,%d,%d,%d,%d\r\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], (uint8_t)(local_port>>8), (uint8_t)(local_port&0x00ff)); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + Command.First = f_get; + + gModeActivePassiveflag = 1; + break; + } + } + else if(msg_c=='2'){ +#if defined(F_FILESYSTEM) + scan_files(ftpc.workingdir, dbuf, (int *)&size); + printf("\r\n%s\r\n", dbuf); +#else + if (strncmp(ftpc.workingdir, "/$Recycle.Bin", sizeof("/$Recycle.Bin")) != 0) + size = sprintf(dbuf, "drwxr-xr-x 1 ftp ftp 0 Dec 31 2014 $Recycle.Bin\r\n-rwxr-xr-x 1 ftp ftp 512 Dec 31 2014 test.txt\r\n"); + printf("\r\n%s\r\n", dbuf); +#endif + gMenuStart = 1; + break; + } + else if(msg_c=='3'){ + printf("1> ASCII\r\n"); + printf("2> BINARY\r\n"); + while(1){ + msg_c=ftp_getc(); + if(msg_c=='1'){ + sprintf(dat,"TYPE %c\r\n", TransferAscii); + ftpc.type = ASCII_TYPE; + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + } + else if(msg_c=='2'){ + sprintf(dat,"TYPE %c\r\n", TransferBinary); + ftpc.type = IMAGE_TYPE; + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + } + else{ + printf("\r\nRetry...\r\n"); + } + } + break; + } + else if(msg_c=='4'){ + printf("1> ACTIVE\r\n"); + printf("2> PASSIVE\r\n"); + while(1){ + msg_c=ftp_getc(); + if(msg_c=='1'){ + ftpc.dsock_mode=ACTIVE_MODE; + break; + } + else if(msg_c=='2'){ + ftpc.dsock_mode=PASSIVE_MODE; + break; + } + else{ + printf("\r\nRetry...\r\n"); + } + } + gMenuStart = 1; + break; + } +#if defined(F_FILESYSTEM) + else if(msg_c=='7'){ + printf(">del filename?"); + sprintf(ftpc.filename, "/%s\r\n", User_Keyboard_MSG()); + if (f_unlink((const char *)ftpc.filename) != 0){ + printf("\r\nCould not delete.\r\n"); + } + else{ + printf("\r\nDeleted.\r\n"); + } + gMenuStart = 1; + break; + } +#endif + else{ + printf("\r\nRetry...\r\n"); + } + } + } + if(gDataSockReady){ + gDataSockReady = 0; + switch(Command.First){ + case f_dir: + sprintf(dat,"LIST\r\n"); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + case f_put: + printf(">put file name?"); + sprintf(dat,"STOR %s\r\n", User_Keyboard_MSG()); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + case f_get: + printf(">get file name?"); + sprintf(dat,"RETR %s\r\n", User_Keyboard_MSG()); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + default: + printf("Command.First = default\r\n"); + break; + } + } + if((size = getSn_RX_RSR(CTRL_SOCK)) > 0){ // Don't need to check SOCKERR_BUSY because it doesn't not occur. + memset(dbuf, 0, _MAX_SS); + if(size > _MAX_SS) size = _MAX_SS - 1; + ret = recv(CTRL_SOCK,dbuf,size); + dbuf[ret] = '\0'; + if(ret != size) + { + if(ret==SOCK_BUSY) return 0; + if(ret < 0){ + printf("%d:recv() error:%ld\r\n",CTRL_SOCK,ret); + close(CTRL_SOCK); + return ret; + } + } + printf("Rcvd Command: %s\r\n", dbuf); + proc_ftpc((char *)dbuf); + } + break; + case SOCK_CLOSE_WAIT : + printf("%d:CloseWait\r\n",CTRL_SOCK); + if((ret=disconnect(CTRL_SOCK)) != SOCK_OK) return ret; + printf("%d:Closed\r\n",CTRL_SOCK); + break; + case SOCK_CLOSED : + printf("%d:FTPStart\r\n",CTRL_SOCK); + if((ret=socket(CTRL_SOCK, Sn_MR_TCP, FTP_destport, 0x0)) != CTRL_SOCK){ + printf("%d:socket() error:%ld\r\n", CTRL_SOCK, ret); + close(CTRL_SOCK); + return ret; + } + break; + case SOCK_INIT : + printf("%d:Opened\r\n",CTRL_SOCK); + if((ret = connect(CTRL_SOCK, FTP_destip, FTP_destport)) != SOCK_OK){ + printf("%d:Connect error\r\n",CTRL_SOCK); + return ret; + } + connect_state_control_ftpc = 0; + printf("%d:Connectting...\r\n",CTRL_SOCK); + break; + default : + break; + } + + switch(getSn_SR(DATA_SOCK)){ + case SOCK_ESTABLISHED : + if(!connect_state_data_ftpc){ + printf("%d:FTP Data socket Connected\r\n", DATA_SOCK); + connect_state_data_ftpc = 1; + } + if(gDataPutGetStart){ + switch(Command.Second){ + case s_dir: + printf("dir waiting...\r\n"); + if((size = getSn_RX_RSR(DATA_SOCK)) > 0){ // Don't need to check SOCKERR_BUSY because it doesn't not occur. + printf("ok\r\n"); + memset(dbuf, 0, _MAX_SS); + if(size > _MAX_SS) size = _MAX_SS - 1; + ret = recv(DATA_SOCK,dbuf,size); + dbuf[ret] = '\0'; + if(ret != size){ + if(ret==SOCK_BUSY) return 0; + if(ret < 0){ + printf("%d:recv() error:%ld\r\n",CTRL_SOCK,ret); + close(DATA_SOCK); + return ret; + } + } + printf("Rcvd Data:\n\r%s\n\r", dbuf); + gDataPutGetStart = 0; + Command.Second = s_nocmd; + } + break; + case s_put: + printf("put waiting...\r\n"); + if(strlen(ftpc.workingdir) == 1) + sprintf(ftpc.filename, "/%s", (uint8_t *)gMsgBuf); + else + sprintf(ftpc.filename, "%s/%s", ftpc.workingdir, (uint8_t *)gMsgBuf); +#if defined(F_FILESYSTEM) + ftpc.fr = f_open(&(ftpc.fil), (const char *)ftpc.filename, FA_READ); + if(ftpc.fr == FR_OK){ + remain_filesize = ftpc.fil.fsize; + printf("f_open return FR_OK\r\n"); + do{ + memset(dbuf, 0, _MAX_SS); + if(remain_filesize > _MAX_SS) + send_byte = _MAX_SS; + else + send_byte = remain_filesize; + ftpc.fr = f_read(&(ftpc.fil), (void *)dbuf, send_byte , (UINT *)&blocklen); + if(ftpc.fr != FR_OK){ + break; + } + printf("#"); + send(DATA_SOCK, dbuf, blocklen); + remain_filesize -= blocklen; + }while(remain_filesize != 0); + printf("\r\nFile read finished\r\n"); + ftpc.fr = f_close(&(ftpc.fil)); + } + else{ + printf("File Open Error: %d\r\n", ftpc.fr); + ftpc.fr = f_close(&(ftpc.fil)); + } +#else + remain_filesize = strlen(ftpc.filename); + do{ + memset(dbuf, 0, _MAX_SS); + blocklen = sprintf(dbuf, "%s", ftpc.filename); + printf("########## dbuf:%s\r\n", dbuf); + send(DATA_SOCK, dbuf, blocklen); + remain_filesize -= blocklen; + }while(remain_filesize != 0); +#endif + gDataPutGetStart = 0; + Command.Second = s_nocmd; + disconnect(DATA_SOCK); + break; + case s_get: + printf("get waiting...\r\n"); + if(strlen(ftpc.workingdir) == 1) + sprintf(ftpc.filename, "/%s", (uint8_t *)gMsgBuf); + else + sprintf(ftpc.filename, "%s/%s", ftpc.workingdir, (uint8_t *)gMsgBuf); +#if defined(F_FILESYSTEM) + ftpc.fr = f_open(&(ftpc.fil), (const char *)ftpc.filename, FA_CREATE_ALWAYS | FA_WRITE); + if(ftpc.fr == FR_OK){ + printf("f_open return FR_OK\r\n"); + while(1){ + if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ + while(1){ + memset(dbuf, 0, _MAX_SS); + if(remain_datasize > _MAX_SS) recv_byte = _MAX_SS; + else recv_byte = remain_datasize; + ret = recv(DATA_SOCK, dbuf, recv_byte); + ftpc.fr = f_write(&(ftpc.fil), (const void *)dbuf, (UINT)ret, (UINT *)&blocklen); + remain_datasize -= blocklen; + if(ftpc.fr != FR_OK){ + printf("f_write failed\r\n"); + break; + } + if(remain_datasize <= 0) break; + } + if(ftpc.fr != FR_OK){ + printf("f_write failed\r\n"); + break; + } + printf("#"); + } + else{ + if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) break; + } + } + printf("\r\nFile write finished\r\n"); + ftpc.fr = f_close(&(ftpc.fil)); + gDataPutGetStart = 0; + }else{ + printf("File Open Error: %d\r\n", ftpc.fr); + } +#else + while(1){ + if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ + while(1){ + memset(dbuf, 0, _MAX_SS); + if(remain_datasize > _MAX_SS) + recv_byte = _MAX_SS; + else + recv_byte = remain_datasize; + ret = recv(DATA_SOCK, dbuf, recv_byte); + printf("########## dbuf:%s\r\n", dbuf); + remain_datasize -= ret; + if(remain_datasize <= 0) + break; + } + }else{ + if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) + break; + } + } + gDataPutGetStart = 0; + Command.Second = s_nocmd; +#endif + break; + default: + printf("Command.Second = default\r\n"); + break; + } + } + break; + case SOCK_CLOSE_WAIT : + printf("%d:CloseWait\r\n",DATA_SOCK); + if((ret=disconnect(DATA_SOCK)) != SOCK_OK) return ret; + printf("%d:Closed\r\n",DATA_SOCK); + break; + case SOCK_CLOSED : + if(ftpc.dsock_state == DATASOCK_READY){ + if(ftpc.dsock_mode == PASSIVE_MODE){ + printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port); + if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK){ + printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); + close(DATA_SOCK); + return ret; + } + local_port++; + if(local_port > 50000) + local_port = 35000; + }else{ + printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port); + if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK){ + printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); + close(DATA_SOCK); + return ret; + } + local_port++; + if(local_port > 50000) + local_port = 35000; + } + ftpc.dsock_state = DATASOCK_START; + } + break; + + case SOCK_INIT : + printf("%d:Opened\r\n",DATA_SOCK); + if(ftpc.dsock_mode == ACTIVE_MODE){ + if( (ret = listen(DATA_SOCK)) != SOCK_OK){ + printf("%d:Listen error\r\n",DATA_SOCK); + return ret; + } + gDataSockReady = 1; + printf("%d:Listen ok\r\n",DATA_SOCK); + }else{ + if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){ + printf("%d:Connect error\r\n", DATA_SOCK); + return ret; + } + gDataSockReady = 1; + } + connect_state_data_ftpc = 0; + break; + default : + break; + } +#endif + return 0; +} + +char proc_ftpc(char * buf) +{ + uint16_t Responses; + uint8_t dat[30]={0,}; + + Responses =(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0'); + + switch(Responses){ + case R_220: /* Service ready for new user. */ + printf("\r\nInput your User ID > "); + sprintf(dat,"USER %s\r\n", User_Keyboard_MSG()); + printf("\r\n"); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + + case R_331: /* User name okay, need password. */ + printf("\r\nInput your Password > "); + sprintf(dat,"PASS %s\r\n", User_Keyboard_MSG()); + printf("\r\n"); + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + case R_230: /* User logged in, proceed */ + printf("\r\nUser logged in, proceed\r\n"); + + sprintf(dat,"TYPE %c\r\n", TransferAscii); + ftpc.type = ASCII_TYPE; + send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); + break; + case R_200: + if((ftpc.dsock_mode==ACTIVE_MODE)&&gModeActivePassiveflag){ + ftpc.dsock_state = DATASOCK_READY; + gModeActivePassiveflag = 0; + } + else{ + gMenuStart = 1; + } + break; + case R_150: + switch(Command.First){ + case f_dir: + Command.First = f_nocmd; + Command.Second = s_dir; + gDataPutGetStart = 1; + break; + case f_get: + Command.First = f_nocmd; + Command.Second = s_get; + gDataPutGetStart = 1; + break; + case f_put: + Command.First = f_nocmd; + Command.Second = s_put; + gDataPutGetStart = 1; + break; + default : + printf("Command.First = default\r\n"); + break; + } + break; + case R_226: + gMenuStart = 1; + break; + case R_227: + if (pportc(buf) == -1){ + printf("Bad port syntax\r\n"); + } + else{ + printf("Go Open Data Sock...\r\n "); + ftpc.dsock_mode = PASSIVE_MODE; + ftpc.dsock_state = DATASOCK_READY; + } + break; + default: + printf("\r\nDefault Status = %d\r\n",(uint16_t)Responses); + gDataSockReady = 1; + break; + } + return 1; +} +int pportc(char * arg) +{ + int i; + char* tok=0; + strtok(arg,"("); + for (i = 0; i < 4; i++) + { + if(i==0) tok = strtok(NULL,",\r\n"); + else tok = strtok(NULL,","); + remote_ip.cVal[i] = (uint8_t)atoi(tok); + if (!tok){ + printf("bad pport : %s\r\n", arg); + return -1; + } + } + remote_port = 0; + for (i = 0; i < 2; i++){ + tok = strtok(NULL,",\r\n"); + remote_port <<= 8; + remote_port += atoi(tok); + if (!tok){ + printf("bad pport : %s\r\n", arg); + return -1; + } + } + printf("ip : %d.%d.%d.%d, port : %d\r\n", remote_ip.cVal[0], remote_ip.cVal[1], remote_ip.cVal[2], remote_ip.cVal[3], remote_port); + return 0; +} +uint8_t* User_Keyboard_MSG() +{ + uint8_t i=0; + do{ + gMsgBuf[i] = ftp_getc(); + i++; + }while(gMsgBuf[i-1]!=0x0d); + gMsgBuf[i-1]=0; + return gMsgBuf; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.h new file mode 100755 index 00000000000..ef2be525abf --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/ftpc.h @@ -0,0 +1,130 @@ +#ifndef _FTPC_H_ +#define _FTPC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "socket.h" + +/* If you need this header, use it. */ +//#include "stdio_private.h" + +#define F_APP_FTPC + +/* If your target support a file system, you have to activate this feature and implement. */ +//#define F_FILESYSTEM + +/* Change to your Chipset Uart function, you have to activate this feature and implement. + * Change!! -> Board_UARTGetCharBlocking() + * Below is an example of a function of lpc_chip library. */ +//#define ftp_getc() Board_UARTGetCharBlocking() + +#ifdef F_FILESYSTEM +#include "ff.h" +#endif + +#ifndef ftp_getc() +#define Need_UARTGetCharBlocking_func +#else +/* Change library + * Change!! -> board_api.h, + * Below is an example of a function of lpc_chip library. */ +#include "board_api.h" +#endif + + +#define LINELEN 100 +#ifndef F_FILESYSTEM +#define _MAX_SS 512 +#endif + +#define CTRL_SOCK 2 +#define DATA_SOCK 3 + +/* FTP Responses */ +#define R_150 150 /* File status ok; opening data conn */ +#define R_200 200 /* 'Generic' command ok */ +#define R_220 220 /* Service ready for new user. */ +#define R_226 226 /* Closing data connection. File transfer/abort successful */ +#define R_227 227 /* Entering passive mode (h1,h2,h3,h4,p1,p2) */ +#define R_230 230 /* User logged in, proceed */ +#define R_331 331 /* User name okay, need password. */ + +#define TransferAscii 'A' +#define TransferBinary 'I' + +enum ftpc_type { + ASCII_TYPE, + IMAGE_TYPE, +}; + +enum ftpc_datasock_state{ + DATASOCK_IDLE, + DATASOCK_READY, + DATASOCK_START +}; + +enum ftpc_datasock_mode{ + PASSIVE_MODE, + ACTIVE_MODE +}; +enum CommandFirst { + f_nocmd, + f_dir, + f_put, + f_get, +}; +enum CommandSecond { + s_nocmd, + s_dir, + s_put, + s_get, +}; +struct Command { + enum CommandFirst First; + enum CommandSecond Second; +}; +struct ftpc { + uint8_t control; /* Control stream */ + uint8_t data; /* Data stream */ + + enum ftpc_type type; /* Transfer type */ + + enum ftpc_datasock_state dsock_state; + enum ftpc_datasock_mode dsock_mode; + + char workingdir[LINELEN]; + char filename[LINELEN]; + +#ifdef F_FILESYSTEM + FIL fil; // FatFs File objects + FRESULT fr; // FatFs function common result code +#endif +}; + +#ifndef un_I2cval +typedef union _un_l2cval { + uint32_t lVal; + uint8_t cVal[4]; +}un_l2cval; +#endif + +void ftpc_init(uint8_t * src_ip); +uint8_t ftpc_run(uint8_t * dbuf); +char proc_ftpc(char * buf); +int pportc(char * arg); +uint8_t* User_Keyboard_MSG(); + +#ifdef __cplusplus +} +#endif + +#endif // _FTPC_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/stdio_private.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/stdio_private.h new file mode 100755 index 00000000000..a81d94c0f73 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPClient/stdio_private.h @@ -0,0 +1,75 @@ +/* Copyright (c) 2002, Joerg Wunsch + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* $Id: stdio_private.h,v 1.6 2003/01/07 22:17:24 joerg_wunsch Exp $ */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct __file { + char *buf; /* buffer pointer */ + unsigned char unget; /* ungetc() buffer */ + uint8_t flags; /* flags, see below */ +#define __SRD 0x0001 /* OK to read */ +#define __SWR 0x0002 /* OK to write */ +#define __SSTR 0x0004 /* this is an sprintf/snprintf string */ +#define __SPGM 0x0008 /* fmt string is in progmem */ +#define __SERR 0x0010 /* found error */ +#define __SEOF 0x0020 /* found EOF */ +#define __SUNGET 0x040 /* ungetc() happened */ +#if 0 +/* possible future extensions, will require uint16_t flags */ +#define __SRW 0x0080 /* open for reading & writing */ +#define __SLBF 0x0100 /* line buffered */ +#define __SNBF 0x0200 /* unbuffered */ +#define __SMBF 0x0400 /* buf is from malloc */ +#endif + int size; /* size of buffer */ + int len; /* characters read or written so far */ + int (*put)(char); /* function to write one char to device */ + int (*get)(void); /* function to read one char from device */ +}; + +/* values for PRINTF_LEVEL */ +#define PRINTF_MIN 1 +#define PRINTF_STD 2 +#define PRINTF_FLT 3 + +/* values for SCANF_LEVEL */ +#define SCANF_MIN 1 +#define SCANF_STD 2 +#define SCANF_FLT 3 + +#ifdef __cplusplus +} +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.c new file mode 100755 index 00000000000..5e27041ed15 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.c @@ -0,0 +1,983 @@ +/* +* Wiznet. +* (c) Copyright 2002, Wiznet. +* +* Filename : ftpd.c +* Version : 1.0 +* Programmer(s) : +* Created : 2003/01/28 +* Description : FTP daemon. (AVR-GCC Compiler) +*/ + + +#include +#include +#include +#include +#include +#include +#include "socket.h" +#include "ftpd.h" + +/* If you need this header, use it. */ +//#include "stdio_private.h" + +/* Command table */ +static char *commands[] = { + "user", + "acct", + "pass", + "type", + "list", + "cwd", + "dele", + "name", + "quit", + "retr", + "stor", + "port", + "nlst", + "pwd", + "xpwd", + "mkd", + "xmkd", + "xrmd", + "rmd ", + "stru", + "mode", + "syst", + "xmd5", + "xcwd", + "feat", + "pasv", + "size", + "mlsd", + "appe", + NULL +}; + +#if 0 +/* Response messages */ +char banner[] = "220 %s FTP version %s ready.\r\n"; +char badcmd[] = "500 Unknown command '%s'\r\n"; +char binwarn[] = "100 Warning: type is ASCII and %s appears to be binary\r\n"; +char unsupp[] = "500 Unsupported command or option\r\n"; +char givepass[] = "331 Enter PASS command\r\n"; +char logged[] = "230 Logged in\r\n"; +char typeok[] = "200 Type %s OK\r\n"; +char only8[] = "501 Only logical bytesize 8 supported\r\n"; +char deleok[] = "250 File deleted\r\n"; +char mkdok[] = "200 MKD ok\r\n"; +char delefail[] = "550 Delete failed: %s\r\n"; +char pwdmsg[] = "257 \"%s\" is current directory\r\n"; +char badtype[] = "501 Unknown type \"%s\"\r\n"; +char badport[] = "501 Bad port syntax\r\n"; +char unimp[] = "502 Command does not implemented yet.\r\n"; +char bye[] = "221 Goodbye!\r\n"; +char nodir[] = "553 Can't read directory \"%s\": %s\r\n"; +char cantopen[] = "550 Can't read file \"%s\": %s\r\n"; +char sending[] = "150 Opening data connection for %s (%d.%d.%d.%d,%d)\r\n"; +char cantmake[] = "553 Can't create \"%s\": %s\r\n"; +char writerr[] = "552 Write error: %s\r\n"; +char portok[] = "200 PORT command successful.\r\n"; +char rxok[] = "226 Transfer complete.\r\n"; +char txok[] = "226 Transfer complete.\r\n"; +char noperm[] = "550 Permission denied\r\n"; +char noconn[] = "425 Data connection reset\r\n"; +char lowmem[] = "421 System overloaded, try again later\r\n"; +char notlog[] = "530 Please log in with USER and PASS\r\n"; +char userfirst[] = "503 Login with USER first.\r\n"; +char okay[] = "200 Ok\r\n"; +char syst[] = "215 %s Type: L%d Version: %s\r\n"; +char sizefail[] = "550 File not found\r\n"; +#endif + +un_l2cval remote_ip; +uint16_t remote_port; +un_l2cval local_ip; +uint16_t local_port; +uint8_t connect_state_control = 0; +uint8_t connect_state_data = 0; + +struct ftpd ftp; + +int current_year = 2014; +int current_month = 12; +int current_day = 31; +int current_hour = 10; +int current_min = 10; +int current_sec = 30; + +int fsprintf(uint8_t s, const char *format, ...) +{ + int i; +/* + char buf[LINELEN]; + FILE f; + va_list ap; + + f.flags = __SWR | __SSTR; + f.buf = buf; + f.size = INT_MAX; + va_start(ap, format); + i = vfprintf(&f, format, ap); + va_end(ap); + buf[f.len] = 0; + + send(s, (uint8_t *)buf, strlen(buf)); +*/ + return i; +} + +void ftpd_init(uint8_t * src_ip) +{ + ftp.state = FTPS_NOT_LOGIN; + ftp.current_cmd = NO_CMD; + ftp.dsock_mode = ACTIVE_MODE; + + local_ip.cVal[0] = src_ip[0]; + local_ip.cVal[1] = src_ip[1]; + local_ip.cVal[2] = src_ip[2]; + local_ip.cVal[3] = src_ip[3]; + local_port = 35000; + + strcpy(ftp.workingdir, "/"); + + socket(CTRL_SOCK, Sn_MR_TCP, IPPORT_FTP, 0x0); +} + +uint8_t ftpd_run(uint8_t * dbuf) +{ + uint16_t size = 0, i; + long ret = 0; + uint32_t blocklen, send_byte, recv_byte; + uint32_t remain_filesize; + uint32_t remain_datasize; +#if defined(F_FILESYSTEM) + //FILINFO fno; +#endif + + //memset(dbuf, 0, sizeof(_MAX_SS)); + + switch(getSn_SR(CTRL_SOCK)) + { + case SOCK_ESTABLISHED : + if(!connect_state_control) + { +#if defined(_FTP_DEBUG_) + printf("%d:FTP Connected\r\n", CTRL_SOCK); +#endif + //fsprintf(CTRL_SOCK, banner, HOSTNAME, VERSION); + strcpy(ftp.workingdir, "/"); + sprintf((char *)dbuf, "220 %s FTP version %s ready.\r\n", HOSTNAME, VERSION); + ret = send(CTRL_SOCK, (uint8_t *)dbuf, strlen((const char *)dbuf)); + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",CTRL_SOCK,ret); +#endif + close(CTRL_SOCK); + return ret; + } + connect_state_control = 1; + } + +#if defined(_FTP_DEBUG_) + //printf("ftp socket %d\r\n", CTRL_SOCK); +#endif + + if((size = getSn_RX_RSR(CTRL_SOCK)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. + { +#if defined(_FTP_DEBUG_) + printf("size: %d\r\n", size); +#endif + + memset(dbuf, 0, _MAX_SS); + + if(size > _MAX_SS) size = _MAX_SS - 1; + + ret = recv(CTRL_SOCK,dbuf,size); + dbuf[ret] = '\0'; + if(ret != size) + { + if(ret==SOCK_BUSY) return 0; + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:recv() error:%ld\r\n",CTRL_SOCK,ret); +#endif + close(CTRL_SOCK); + return ret; + } + } +#if defined(_FTP_DEBUG_) + printf("Rcvd Command: %s", dbuf); +#endif + proc_ftpd((char *)dbuf); + } + break; + + case SOCK_CLOSE_WAIT : +#if defined(_FTP_DEBUG_) + printf("%d:CloseWait\r\n",CTRL_SOCK); +#endif + if((ret=disconnect(CTRL_SOCK)) != SOCK_OK) return ret; +#if defined(_FTP_DEBUG_) + printf("%d:Closed\r\n",CTRL_SOCK); +#endif + break; + + case SOCK_CLOSED : +#if defined(_FTP_DEBUG_) + printf("%d:FTPStart\r\n",CTRL_SOCK); +#endif + if((ret=socket(CTRL_SOCK, Sn_MR_TCP, IPPORT_FTP, 0x0)) != CTRL_SOCK) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", CTRL_SOCK, ret); +#endif + close(CTRL_SOCK); + return ret; + } + break; + + case SOCK_INIT : +#if defined(_FTP_DEBUG_) + printf("%d:Opened\r\n",CTRL_SOCK); +#endif + //strcpy(ftp.workingdir, "/"); + if( (ret = listen(CTRL_SOCK)) != SOCK_OK) + { +#if defined(_FTP_DEBUG_) + printf("%d:Listen error\r\n",CTRL_SOCK); +#endif + return ret; + } + connect_state_control = 0; + +#if defined(_FTP_DEBUG_) + printf("%d:Listen ok\r\n",CTRL_SOCK); +#endif + break; + + default : + break; + } + +#if 1 + switch(getSn_SR(DATA_SOCK)) + { + case SOCK_ESTABLISHED : + if(!connect_state_data) + { +#if defined(_FTP_DEBUG_) + printf("%d:FTP Data socket Connected\r\n", DATA_SOCK); +#endif + connect_state_data = 1; + } + + switch(ftp.current_cmd) + { + case LIST_CMD: + case MLSD_CMD: +#if defined(_FTP_DEBUG_) + printf("previous size: %d\r\n", size); +#endif +#if defined(F_FILESYSTEM) + scan_files(ftp.workingdir, dbuf, (int *)&size); +#endif +#if defined(_FTP_DEBUG_) + printf("returned size: %d\r\n", size); + printf("%s\r\n", dbuf); +#endif +#if !defined(F_FILESYSTEM) + if (strncmp(ftp.workingdir, "/$Recycle.Bin", sizeof("/$Recycle.Bin")) != 0) + size = sprintf(dbuf, "drwxr-xr-x 1 ftp ftp 0 Dec 31 2014 $Recycle.Bin\r\n-rwxr-xr-x 1 ftp ftp 512 Dec 31 2014 test.txt\r\n"); +#endif + size = strlen(dbuf); + send(DATA_SOCK, dbuf, size); + ftp.current_cmd = NO_CMD; + disconnect(DATA_SOCK); + size = sprintf(dbuf, "226 Successfully transferred \"%s\"\r\n", ftp.workingdir); + send(CTRL_SOCK, dbuf, size); + break; + + case RETR_CMD: +#if defined(_FTP_DEBUG_) + printf("filename to retrieve : %s %d\r\n", ftp.filename, strlen(ftp.filename)); +#endif +#if defined(F_FILESYSTEM) + ftp.fr = f_open(&(ftp.fil), (const char *)ftp.filename, FA_READ); + //print_filedsc(&(ftp.fil)); + if(ftp.fr == FR_OK){ + remain_filesize = ftp.fil.fsize; +#if defined(_FTP_DEBUG_) + printf("f_open return FR_OK\r\n"); +#endif + do{ +#if defined(_FTP_DEBUG_) + //printf("remained file size: %d\r\n", ftp.fil.fsize); +#endif + memset(dbuf, 0, _MAX_SS); + + if(remain_filesize > _MAX_SS) + send_byte = _MAX_SS; + else + send_byte = remain_filesize; + + ftp.fr = f_read(&(ftp.fil), dbuf, send_byte , &blocklen); + if(ftp.fr != FR_OK) + break; +#if defined(_FTP_DEBUG_) + printf("#"); + //printf("----->fsize:%d recv:%d len:%d \r\n", remain_filesize, send_byte, blocklen); + //printf("----->fn:%s data:%s \r\n", ftp.filename, dbuf); +#endif + send(DATA_SOCK, dbuf, blocklen); + remain_filesize -= blocklen; + }while(remain_filesize != 0); +#if defined(_FTP_DEBUG_) + printf("\r\nFile read finished\r\n"); +#endif + ftp.fr = f_close(&(ftp.fil)); + }else{ +#if defined(_FTP_DEBUG_) + printf("File Open Error: %d\r\n", ftp.fr); +#endif + } +#else + remain_filesize = strlen(ftp.filename); + + do{ + memset(dbuf, 0, _MAX_SS); + + blocklen = sprintf(dbuf, "%s", ftp.filename); + + printf("########## dbuf:%s\r\n", dbuf); + + send(DATA_SOCK, dbuf, blocklen); + remain_filesize -= blocklen; + }while(remain_filesize != 0); + +#endif + ftp.current_cmd = NO_CMD; + disconnect(DATA_SOCK); + size = sprintf(dbuf, "226 Successfully transferred \"%s\"\r\n", ftp.filename); + send(CTRL_SOCK, dbuf, size); + break; + + case STOR_CMD: +#if defined(_FTP_DEBUG_) + printf("filename to store : %s %d\r\n", ftp.filename, strlen(ftp.filename)); +#endif +#if defined(F_FILESYSTEM) + ftp.fr = f_open(&(ftp.fil), (const char *)ftp.filename, FA_CREATE_ALWAYS | FA_WRITE); + //print_filedsc(&(ftp.fil)); + if(ftp.fr == FR_OK){ +#if defined(_FTP_DEBUG_) + printf("f_open return FR_OK\r\n"); +#endif + while(1){ + if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ + while(1){ + memset(dbuf, 0, _MAX_SS); + + if(remain_datasize > _MAX_SS) + recv_byte = _MAX_SS; + else + recv_byte = remain_datasize; + + ret = recv(DATA_SOCK, dbuf, recv_byte); +#if defined(_FTP_DEBUG_) + //printf("----->fn:%s data:%s \r\n", ftp.filename, dbuf); +#endif + + ftp.fr = f_write(&(ftp.fil), dbuf, (UINT)ret, &blocklen); +#if defined(_FTP_DEBUG_) + //printf("----->dsize:%d recv:%d len:%d \r\n", remain_datasize, ret, blocklen); +#endif + remain_datasize -= blocklen; + + if(ftp.fr != FR_OK){ +#if defined(_FTP_DEBUG_) + printf("f_write failed\r\n"); +#endif + break; + } + + if(remain_datasize <= 0) + break; + } + + if(ftp.fr != FR_OK){ +#if defined(_FTP_DEBUG_) + printf("f_write failed\r\n"); +#endif + break; + } + +#if defined(_FTP_DEBUG_) + printf("#"); +#endif + }else{ + if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) + break; + } + } +#if defined(_FTP_DEBUG_) + printf("\r\nFile write finished\r\n"); +#endif + ftp.fr = f_close(&(ftp.fil)); + }else{ +#if defined(_FTP_DEBUG_) + printf("File Open Error: %d\r\n", ftp.fr); +#endif + } + + //fno.fdate = (WORD)(((current_year - 1980) << 9) | (current_month << 5) | current_day); + //fno.ftime = (WORD)((current_hour << 11) | (current_min << 5) | (current_sec >> 1)); + //f_utime((const char *)ftp.filename, &fno); +#else + while(1){ + if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ + while(1){ + memset(dbuf, 0, _MAX_SS); + + if(remain_datasize > _MAX_SS) + recv_byte = _MAX_SS; + else + recv_byte = remain_datasize; + + ret = recv(DATA_SOCK, dbuf, recv_byte); + + printf("########## dbuf:%s\r\n", dbuf); + + remain_datasize -= ret; + + if(remain_datasize <= 0) + break; + } + }else{ + if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) + break; + } + } +#endif + ftp.current_cmd = NO_CMD; + disconnect(DATA_SOCK); + size = sprintf(dbuf, "226 Successfully transferred \"%s\"\r\n", ftp.filename); + send(CTRL_SOCK, dbuf, size); + break; + + case NO_CMD: + default: + break; + } + break; + + case SOCK_CLOSE_WAIT : +#if defined(_FTP_DEBUG_) + printf("%d:CloseWait\r\n",DATA_SOCK); +#endif + if((ret=disconnect(DATA_SOCK)) != SOCK_OK) return ret; +#if defined(_FTP_DEBUG_) + printf("%d:Closed\r\n",DATA_SOCK); +#endif + break; + + case SOCK_CLOSED : + if(ftp.dsock_state == DATASOCK_READY) + { + if(ftp.dsock_mode == PASSIVE_MODE){ +#if defined(_FTP_DEBUG_) + printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port); +#endif + if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); +#endif + close(DATA_SOCK); + return ret; + } + + local_port++; + if(local_port > 50000) + local_port = 35000; + }else{ +#if defined(_FTP_DEBUG_) + printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, IPPORT_FTPD); +#endif + if((ret=socket(DATA_SOCK, Sn_MR_TCP, IPPORT_FTPD, 0x0)) != DATA_SOCK) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); +#endif + close(DATA_SOCK); + return ret; + } + } + + ftp.dsock_state = DATASOCK_START; + } + break; + + case SOCK_INIT : +#if defined(_FTP_DEBUG_) + printf("%d:Opened\r\n",DATA_SOCK); +#endif + if(ftp.dsock_mode == PASSIVE_MODE){ + if( (ret = listen(DATA_SOCK)) != SOCK_OK) + { +#if defined(_FTP_DEBUG_) + printf("%d:Listen error\r\n",DATA_SOCK); +#endif + return ret; + } + +#if defined(_FTP_DEBUG_) + printf("%d:Listen ok\r\n",DATA_SOCK); +#endif + }else{ + if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){ +#if defined(_FTP_DEBUG_) + printf("%d:Connect error\r\n", DATA_SOCK); +#endif + return ret; + } + } + connect_state_data = 0; + break; + + default : + break; + } +#endif + + return 0; +} + +char proc_ftpd(char * buf) +{ + char **cmdp, *cp, *arg, *tmpstr; + char sendbuf[200]; + int slen; + long ret; + + + /* Translate first word to lower case */ + for (cp = buf; *cp != ' ' && *cp != '\0'; cp++) + *cp = tolower(*cp); + + /* Find command in table; if not present, return syntax error */ + for (cmdp = commands; *cmdp != NULL; cmdp++) + if (strncmp(*cmdp, buf, strlen(*cmdp)) == 0) + break; + + if (*cmdp == NULL) + { + //fsprintf(CTRL_SOCK, badcmd, buf); + slen = sprintf(sendbuf, "500 Unknown command '%s'\r\n", buf); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + return 0; + } + /* Allow only USER, PASS and QUIT before logging in */ + if (ftp.state == FTPS_NOT_LOGIN) + { + switch(cmdp - commands) + { + case USER_CMD: + case PASS_CMD: + case QUIT_CMD: + break; + default: + //fsprintf(CTRL_SOCK, notlog); + slen = sprintf(sendbuf, "530 Please log in with USER and PASS\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + return 0; + } + } + + arg = &buf[strlen(*cmdp)]; + while(*arg == ' ') arg++; + + /* Execute specific command */ + switch (cmdp - commands) + { + case USER_CMD : +#if defined(_FTP_DEBUG_) + printf("USER_CMD : %s", arg); +#endif + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + strcpy(ftp.username, arg); + //fsprintf(CTRL_SOCK, givepass); + slen = sprintf(sendbuf, "331 Enter PASS command\r\n"); + ret = send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",CTRL_SOCK,ret); +#endif + close(CTRL_SOCK); + return ret; + } + break; + + case PASS_CMD : +#if defined(_FTP_DEBUG_) + printf("PASS_CMD : %s", arg); +#endif + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + ftplogin(arg); + break; + + case TYPE_CMD : + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + switch(arg[0]) + { + case 'A': + case 'a': /* Ascii */ + ftp.type = ASCII_TYPE; + //fsprintf(CTRL_SOCK, typeok, arg); + slen = sprintf(sendbuf, "200 Type set to %s\r\n", arg); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case 'B': + case 'b': /* Binary */ + case 'I': + case 'i': /* Image */ + ftp.type = IMAGE_TYPE; + //fsprintf(CTRL_SOCK, typeok, arg); + slen = sprintf(sendbuf, "200 Type set to %s\r\n", arg); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + default: /* Invalid */ + //fsprintf(CTRL_SOCK, badtype, arg); + slen = sprintf(sendbuf, "501 Unknown type \"%s\"\r\n", arg); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + } + break; + + case FEAT_CMD : + slen = sprintf(sendbuf, "211-Features:\r\n MDTM\r\n REST STREAM\r\n SIZE\r\n MLST size*;type*;create*;modify*;\r\n MLSD\r\n UTF8\r\n CLNT\r\n MFMT\r\n211 END\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case QUIT_CMD : +#if defined(_FTP_DEBUG_) + printf("QUIT_CMD\r\n"); +#endif + //fsprintf(CTRL_SOCK, bye); + slen = sprintf(sendbuf, "221 Goodbye!\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + disconnect(CTRL_SOCK); + break; + + case RETR_CMD : + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(_FTP_DEBUG_) + printf("RETR_CMD\r\n"); +#endif + if(strlen(ftp.workingdir) == 1) + sprintf(ftp.filename, "/%s", arg); + else + sprintf(ftp.filename, "%s/%s", ftp.workingdir, arg); + slen = sprintf(sendbuf, "150 Opening data channel for file downloand from server of \"%s\"\r\n", ftp.filename); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + ftp.current_cmd = RETR_CMD; + break; + + case APPE_CMD : + case STOR_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(_FTP_DEBUG_) + printf("STOR_CMD\r\n"); +#endif + if(strlen(ftp.workingdir) == 1) + sprintf(ftp.filename, "/%s", arg); + else + sprintf(ftp.filename, "%s/%s", ftp.workingdir, arg); + slen = sprintf(sendbuf, "150 Opening data channel for file upload to server of \"%s\"\r\n", ftp.filename); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + ftp.current_cmd = STOR_CMD; + if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){ +#if defined(_FTP_DEBUG_) + printf("%d:Connect error\r\n", DATA_SOCK); +#endif + return ret; + } + connect_state_data = 0; + break; + + case PORT_CMD: +#if defined(_FTP_DEBUG_) + printf("PORT_CMD\r\n"); +#endif + if (pport(arg) == -1){ + //fsprintf(CTRL_SOCK, badport); + slen = sprintf(sendbuf, "501 Bad port syntax\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + } else{ + //fsprintf(CTRL_SOCK, portok); + ftp.dsock_mode = ACTIVE_MODE; + ftp.dsock_state = DATASOCK_READY; + slen = sprintf(sendbuf, "200 PORT command successful.\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + } + break; + + case MLSD_CMD: +#if defined(_FTP_DEBUG_) + printf("MLSD_CMD\r\n"); +#endif + slen = sprintf(sendbuf, "150 Opening data channel for directory listing of \"%s\"\r\n", ftp.workingdir); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + ftp.current_cmd = MLSD_CMD; + break; + + case LIST_CMD: +#if defined(_FTP_DEBUG_) + printf("LIST_CMD\r\n"); +#endif + slen = sprintf(sendbuf, "150 Opening data channel for directory listing of \"%s\"\r\n", ftp.workingdir); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + ftp.current_cmd = LIST_CMD; + break; + + case NLST_CMD: +#if defined(_FTP_DEBUG_) + printf("NLST_CMD\r\n"); +#endif + break; + + case SYST_CMD: + slen = sprintf(sendbuf, "215 UNIX emulated by WIZnet\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case PWD_CMD: + case XPWD_CMD: + slen = sprintf(sendbuf, "257 \"%s\" is current directory.\r\n", ftp.workingdir); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case PASV_CMD: + slen = sprintf(sendbuf, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n", local_ip.cVal[0], local_ip.cVal[1], local_ip.cVal[2], local_ip.cVal[3], local_port >> 8, local_port & 0x00ff); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + disconnect(DATA_SOCK); + ftp.dsock_mode = PASSIVE_MODE; + ftp.dsock_state = DATASOCK_READY; +#if defined(_FTP_DEBUG_) + printf("PASV port: %d\r\n", local_port); +#endif + break; + + case SIZE_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + if(slen > 3) + { + tmpstr = strrchr(arg, '/'); + *tmpstr = 0; +#if defined(F_FILESYSTEM) + slen = get_filesize(arg, tmpstr + 1); +#else + slen = _MAX_SS; +#endif + if(slen > 0) + slen = sprintf(sendbuf, "213 %d\r\n", slen); + else + slen = sprintf(sendbuf, "550 File not Found\r\n"); + } + else + { + slen = sprintf(sendbuf, "550 File not Found\r\n"); + } + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case CWD_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + if(slen > 3) + { + arg[slen - 3] = 0x00; + tmpstr = strrchr(arg, '/'); + *tmpstr = 0; +#if defined(F_FILESYSTEM) + slen = get_filesize(arg, tmpstr + 1); +#else + slen = 0; +#endif + *tmpstr = '/'; + if(slen == 0){ + slen = sprintf(sendbuf, "213 %d\r\n", slen); + strcpy(ftp.workingdir, arg); + slen = sprintf(sendbuf, "250 CWD successful. \"%s\" is current directory.\r\n", ftp.workingdir); + } + else + { + slen = sprintf(sendbuf, "550 CWD failed. \"%s\"\r\n", arg); + } + } + else + { + strcpy(ftp.workingdir, arg); + slen = sprintf(sendbuf, "250 CWD successful. \"%s\" is current directory.\r\n", ftp.workingdir); + } + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case MKD_CMD: + case XMKD_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(F_FILESYSTEM) + if (f_mkdir(arg) != 0) + { + slen = sprintf(sendbuf, "550 Can't create directory. \"%s\"\r\n", arg); + } + else + { + slen = sprintf(sendbuf, "257 MKD command successful. \"%s\"\r\n", arg); + //strcpy(ftp.workingdir, arg); + } +#else + slen = sprintf(sendbuf, "550 Can't create directory. Permission denied\r\n"); +#endif + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case DELE_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(F_FILESYSTEM) + if (f_unlink(arg) != 0) + { + slen = sprintf(sendbuf, "550 Could not delete. \"%s\"\r\n", arg); + } + else + { + slen = sprintf(sendbuf, "250 Deleted. \"%s\"\r\n", arg); + } +#else + slen = sprintf(sendbuf, "550 Could not delete. Permission denied\r\n"); +#endif + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + case XCWD_CMD: + case ACCT_CMD: + case XRMD_CMD: + case RMD_CMD: + case STRU_CMD: + case MODE_CMD: + case XMD5_CMD: + //fsprintf(CTRL_SOCK, unimp); + slen = sprintf(sendbuf, "502 Command does not implemented yet.\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + + default: /* Invalid */ + //fsprintf(CTRL_SOCK, badcmd, arg); + slen = sprintf(sendbuf, "500 Unknown command \'%s\'\r\n", arg); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + break; + } + + return 1; +} + + +char ftplogin(char * pass) +{ + char sendbuf[100]; + int slen = 0; + + //memset(sendbuf, 0, DATA_BUF_SIZE); + +#if defined(_FTP_DEBUG_) + printf("%s logged in\r\n", ftp.username); +#endif + //fsprintf(CTRL_SOCK, logged); + slen = sprintf(sendbuf, "230 Logged on\r\n"); + send(CTRL_SOCK, (uint8_t *)sendbuf, slen); + ftp.state = FTPS_LOGIN; + + return 1; +} + +int pport(char * arg) +{ + int i; + char* tok=0; + + for (i = 0; i < 4; i++) + { + if(i==0) tok = strtok(arg,",\r\n"); + else tok = strtok(NULL,","); + remote_ip.cVal[i] = (uint8_t)atoi(tok); + if (!tok) + { +#if defined(_FTP_DEBUG_) + printf("bad pport : %s\r\n", arg); +#endif + return -1; + } + } + remote_port = 0; + for (i = 0; i < 2; i++) + { + tok = strtok(NULL,",\r\n"); + remote_port <<= 8; + remote_port += atoi(tok); + if (!tok) + { +#if defined(_FTP_DEBUG_) + printf("bad pport : %s\r\n", arg); +#endif + return -1; + } + } +#if defined(_FTP_DEBUG_) + printf("ip : %d.%d.%d.%d, port : %d\r\n", remote_ip.cVal[0], remote_ip.cVal[1], remote_ip.cVal[2], remote_ip.cVal[3], remote_port); +#endif + + return 0; +} + +#if defined(F_FILESYSTEM) +void print_filedsc(FIL *fil) +{ +#if defined(_FTP_DEBUG_) + printf("File System pointer : %08X\r\n", fil->fs); + printf("File System mount ID : %d\r\n", fil->id); + printf("File status flag : %08X\r\n", fil->flag); + printf("File System pads : %08X\r\n", fil->err); + printf("File read write pointer : %08X\r\n", fil->fptr); + printf("File size : %08X\r\n", fil->fsize); + printf("File start cluster : %08X\r\n", fil->sclust); + printf("current cluster : %08X\r\n", fil->clust); + printf("current data sector : %08X\r\n", fil->dsect); + printf("dir entry sector : %08X\r\n", fil->dir_sect); + printf("dir entry pointer : %08X\r\n", fil->dir_ptr); +#endif +} +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.h new file mode 100755 index 00000000000..6a5e2bf4284 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/ftpd.h @@ -0,0 +1,154 @@ +#ifndef _FTPD_H_ +#define _FTPD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +* Wiznet. +* (c) Copyright 2002, Wiznet. +* +* Filename : ftpd.h +* Version : 1.0 +* Programmer(s) : +* Created : 2003/01/28 +* Description : Header file of FTP daemon. (AVR-GCC Compiler) +*/ + +#include + +//#define F_FILESYSTEM // If your target support a file system, you have to activate this feature and implement. + +#if defined(F_FILESYSTEM) +#include "ff.h" +#endif + +#define F_APP_FTP +#define _FTP_DEBUG_ + + +#define LINELEN 100 +//#define DATA_BUF_SIZE 100 +#if !defined(F_FILESYSTEM) +#define _MAX_SS 512 +#endif + +#define CTRL_SOCK 2 +#define DATA_SOCK 3 + +#define IPPORT_FTPD 20 /* FTP Data port */ +#define IPPORT_FTP 21 /* FTP Control port */ + +#define HOSTNAME "iinChip" +#define VERSION "1.0" + +#define FILENAME "a.txt" + +/* FTP commands */ +enum ftp_cmd { + USER_CMD, + ACCT_CMD, + PASS_CMD, + TYPE_CMD, + LIST_CMD, + CWD_CMD, + DELE_CMD, + NAME_CMD, + QUIT_CMD, + RETR_CMD, + STOR_CMD, + PORT_CMD, + NLST_CMD, + PWD_CMD, + XPWD_CMD, + MKD_CMD, + XMKD_CMD, + XRMD_CMD, + RMD_CMD, + STRU_CMD, + MODE_CMD, + SYST_CMD, + XMD5_CMD, + XCWD_CMD, + FEAT_CMD, + PASV_CMD, + SIZE_CMD, + MLSD_CMD, + APPE_CMD, + NO_CMD, +}; + +enum ftp_type { + ASCII_TYPE, + IMAGE_TYPE, + LOGICAL_TYPE +}; + +enum ftp_state { + FTPS_NOT_LOGIN, + FTPS_LOGIN +}; + +enum datasock_state{ + DATASOCK_IDLE, + DATASOCK_READY, + DATASOCK_START +}; + +enum datasock_mode{ + PASSIVE_MODE, + ACTIVE_MODE +}; + +struct ftpd { + uint8_t control; /* Control stream */ + uint8_t data; /* Data stream */ + + enum ftp_type type; /* Transfer type */ + enum ftp_state state; + + enum ftp_cmd current_cmd; + + enum datasock_state dsock_state; + enum datasock_mode dsock_mode; + + char username[LINELEN]; /* Arg to USER command */ + char workingdir[LINELEN]; + char filename[LINELEN]; + +#if defined(F_FILESYSTEM) + FIL fil; // FatFs File objects + FRESULT fr; // FatFs function common result code +#endif + +}; + +#ifndef un_I2cval +typedef union _un_l2cval { + uint32_t lVal; + uint8_t cVal[4]; +}un_l2cval; +#endif + +void ftpd_init(uint8_t * src_ip); +uint8_t ftpd_run(uint8_t * dbuf); +char proc_ftpd(char * buf); +char ftplogin(char * pass); +int pport(char * arg); + +int sendit(char * command); +int recvit(char * command); + +long sendfile(uint8_t s, char * command); +long recvfile(uint8_t s); + +#if defined(F_FILESYSTEM) +void print_filedsc(FIL *fil); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _FTPD_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/stdio_private.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/stdio_private.h new file mode 100755 index 00000000000..f92a32f788d --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/FTPServer/stdio_private.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2002, Joerg Wunsch + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* $Id: stdio_private.h,v 1.6 2003/01/07 22:17:24 joerg_wunsch Exp $ */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct __file { + char *buf; /* buffer pointer */ + unsigned char unget; /* ungetc() buffer */ + uint8_t flags; /* flags, see below */ +#define __SRD 0x0001 /* OK to read */ +#define __SWR 0x0002 /* OK to write */ +#define __SSTR 0x0004 /* this is an sprintf/snprintf string */ +#define __SPGM 0x0008 /* fmt string is in progmem */ +#define __SERR 0x0010 /* found error */ +#define __SEOF 0x0020 /* found EOF */ +#define __SUNGET 0x040 /* ungetc() happened */ +#if 0 +/* possible future extensions, will require uint16_t flags */ +#define __SRW 0x0080 /* open for reading & writing */ +#define __SLBF 0x0100 /* line buffered */ +#define __SNBF 0x0200 /* unbuffered */ +#define __SMBF 0x0400 /* buf is from malloc */ +#endif + int size; /* size of buffer */ + int len; /* characters read or written so far */ + int (*put)(char); /* function to write one char to device */ + int (*get)(void); /* function to read one char from device */ +}; + +/* values for PRINTF_LEVEL */ +#define PRINTF_MIN 1 +#define PRINTF_STD 2 +#define PRINTF_FLT 3 + +/* values for SCANF_LEVEL */ +#define SCANF_MIN 1 +#define SCANF_STD 2 +#define SCANF_FLT 3 + +#ifdef __cplusplus +} +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.c new file mode 100755 index 00000000000..b468435541b --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.c @@ -0,0 +1,298 @@ +#include "ping.h" +#include "socket.h" +#include "w5500.h" + +PINGMSGR PingRequest; // Variable for Ping Request +PINGMSGR PingReply; // Variable for Ping Reply +static uint16_t RandomID = 0x1234; +static uint16_t RandomSeqNum = 0x4321; +uint8_t ping_reply_received = 0; +uint8_t req = 0; +uint8_t rep = 0; + +extern void ping_wait_ms(int ms); + +uint8_t ping_auto(uint8_t s, uint8_t* addr) { + uint8_t i; + int32_t len = 0; + uint8_t cnt = 0; + int ret = 0; + rep = req = 0; + for(i = 0; i <= 3; i++) { + uint8_t sr = getSn_SR(s); + eth_printf("SR: %02X", sr); + switch(sr) { + case SOCK_CLOSED: + close(s); + IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol + if((ret = socket(s, Sn_MR_IPRAW, 3000, 0)) != + s) { // open the SOCKET with IPRAW mode, if fail then Error + eth_printf(" socket %d fail %d", s, ret); +#ifdef PING_DEBUG + return SOCKET_ERROR; +#endif + } + /* Check socket register */ + while(getSn_SR(s) != SOCK_IPRAW) + ; + ping_wait_ms(1000); // wait 1000ms + ping_wait_ms(1000); // wait 1000ms + break; + case SOCK_IPRAW: + ping_request(s, addr); + req++; + while(1) { + if((len = getSn_RX_RSR(s)) > 0) { + ping_reply(s, addr, len); + rep++; + break; + } else if(cnt > 100) { + eth_printf("Request Time out."); + cnt = 0; + break; + } else { + cnt++; + ping_wait_ms(50); // wait 50ms + } + // wait_time for 2 seconds, Break on fail + } + break; + default: + break; + } +#ifdef PING_DEBUG + if(req >= 3) { + eth_printf("Ping Request = %d, PING_Reply = %d", req, rep); + + if(rep == req) + return PING_SUCCESS; + else + return REPLY_ERROR; + } +#endif + } + return FUNCTION_ERROR; +} + +uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t* addr) { + uint16_t rlen, cnt, i; + cnt = 0; + + for(i = 0; i < pCount + 1; i++) { + if(i != 0) { + /* Output count number */ + eth_printf("No.%d", (i - 1)); + } + + uint8_t sr = getSn_SR(s); + eth_printf("SR: %d", sr); + switch(sr) { + case SOCK_CLOSED: + close(s); + // close the SOCKET + /* Create Socket */ + IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol + if(socket(s, Sn_MR_IPRAW, 3000, 0) != + s) { // open the SOCKET with IPRAW mode, if fail then Error + eth_printf(" socket %d fail ", (s)); +#ifdef PING_DEBUG + return SOCKET_ERROR; +#endif + } + /* Check socket register */ + while(getSn_SR(s) != SOCK_IPRAW) + ; + ping_wait_ms(1000); + break; + case SOCK_IPRAW: + ping_request(s, addr); + req++; + while(1) { + if((rlen = getSn_RX_RSR(s)) > 0) { + ping_reply(s, addr, rlen); + rep++; + if(ping_reply_received) break; + } + /* wait_time for 2 seconds, Break on fail*/ + if((cnt > 100)) { + eth_printf("Request Time out."); + cnt = 0; + break; + } else { + cnt++; + ping_wait_ms(20); + } + } + break; + default: + break; + } +#ifdef PING_DEBUG + if(req >= pCount) { + eth_printf("Ping Request = %d, PING_Reply = %d", req, rep); + if(rep == req) + return PING_SUCCESS; + else + return REPLY_ERROR; + } +#endif + } + return FUNCTION_ERROR; +} + +uint8_t ping_request(uint8_t s, uint8_t* addr) { + uint16_t i; + + //Initailize flag for ping reply + ping_reply_received = 0; + /* make header of the ping-request */ + PingRequest.Type = PING_REQUEST; // Ping-Request + PingRequest.Code = CODE_ZERO; // Always '0' + PingRequest.ID = htons(RandomID++); // set ping-request's ID to random integer value + PingRequest.SeqNum = + htons(RandomSeqNum++); // set ping-request's sequence number to ramdom integer value + //size = 32; // set Data size + + /* Fill in Data[] as size of BIF_LEN (Default = 32)*/ + for(i = 0; i < BUF_LEN; i++) { + PingRequest.Data[i] = (i) % 8; //'0'~'8' number into ping-request's data + } + /* Do checksum of Ping Request */ + PingRequest.CheckSum = + 0; // value of checksum before calucating checksum of ping-request packet + PingRequest.CheckSum = + htons(checksum((uint8_t*)&PingRequest, sizeof(PingRequest))); // Calculate checksum + + /* sendto ping_request to destination */ + if(sendto(s, (uint8_t*)&PingRequest, sizeof(PingRequest), addr, 3000) == + 0) { // Send Ping-Request to the specified peer. + eth_printf(" Fail to send ping-reply packet "); + } else { + eth_printf( + "Send Ping Request to Destination (%d.%d.%d.%d )", + (addr[0]), + (addr[1]), + (addr[2]), + (addr[3])); + eth_printf( + " ID:%x SeqNum:%x CheckSum:%x", + htons(PingRequest.ID), + htons(PingRequest.SeqNum), + htons(PingRequest.CheckSum)); + } + return 0; +} // ping request + +uint8_t ping_reply(uint8_t s, uint8_t* addr, uint16_t rlen) { + uint16_t tmp_checksum; + uint16_t len; + uint16_t i; + uint8_t data_buf[128]; + uint16_t port = 3000; + PINGMSGR PingReply; + /* receive data from a destination */ + len = recvfrom(s, (uint8_t*)data_buf, rlen, addr, &port); + if(data_buf[0] == PING_REPLY) { + PingReply.Type = data_buf[0]; + PingReply.Code = data_buf[1]; + PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2]; + PingReply.ID = (data_buf[5] << 8) + data_buf[4]; + PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6]; + + for(i = 0; i < len - 8; ++i) { + PingReply.Data[i] = data_buf[8 + i]; + } + /* check Checksum of Ping Reply */ + tmp_checksum = ~checksum(data_buf, len); + if(tmp_checksum != 0xffff) { + eth_printf("tmp_checksum = %x", tmp_checksum); + } else { + /* Output the Destination IP and the size of the Ping Reply Message*/ + eth_printf( + "Reply from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes", + (addr[0]), + (addr[1]), + (addr[2]), + (addr[3]), + htons(PingReply.ID), + htons(PingReply.SeqNum), + (rlen + 6)); + /* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/ + ping_reply_received = 1; + } + } else if(data_buf[0] == PING_REQUEST) { + PingReply.Code = data_buf[1]; + PingReply.Type = data_buf[2]; + PingReply.CheckSum = (data_buf[3] << 8) + data_buf[2]; + PingReply.ID = (data_buf[5] << 8) + data_buf[4]; + PingReply.SeqNum = (data_buf[7] << 8) + data_buf[6]; + + for(i = 0; i < len - 8; ++i) { + PingReply.Data[i] = data_buf[8 + i]; + } + /* check Checksum of Ping Reply */ + tmp_checksum = PingReply.CheckSum; + PingReply.CheckSum = 0; + PingReply.CheckSum = htons(checksum((uint8_t*)&PingReply, len)); + + if(tmp_checksum != PingReply.CheckSum) { + eth_printf( + "CheckSum is in correct %x shold be %x", + (tmp_checksum), + htons(PingReply.CheckSum)); + } else { + eth_printf("Checksum is correct"); + } + + /* Output the Destination IP and the size of the Ping Reply Message*/ + eth_printf( + "Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes", + (addr[0]), + (addr[1]), + (addr[2]), + (addr[3]), + (PingReply.ID), + (PingReply.SeqNum), + (rlen + 6)); + /* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/ + ping_reply_received = 1; + } else { + eth_printf(" Unkonwn msg."); + } + + return 0; +} // ping_reply + +uint16_t checksum(uint8_t* data_buf, uint16_t len) { + uint16_t sum, tsum, i, j; + uint32_t lsum; + + j = len >> 1; + lsum = 0; + tsum = 0; + for(i = 0; i < j; ++i) { + tsum = data_buf[i * 2]; + tsum = tsum << 8; + tsum += data_buf[i * 2 + 1]; + lsum += tsum; + } + if(len % 2) { + tsum = data_buf[i * 2]; + lsum += (tsum << 8); + } + sum = (uint16_t)lsum; + sum = ~(sum + (lsum >> 16)); + return sum; +} + +uint16_t htons(uint16_t hostshort) { +#if 1 + //#ifdef LITTLE_ENDIAN + uint16_t netshort = 0; + netshort = (hostshort & 0xFF) << 8; + netshort |= ((hostshort >> 8) & 0xFF); + return netshort; +#else + return hostshort; +#endif +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.h new file mode 100755 index 00000000000..47a711a039b --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/ICMP/ping.h @@ -0,0 +1,38 @@ +#ifndef PING_H +#define PING_H + +#include "wizchip_conf.h" + +#define BUF_LEN 32 +#define PING_REQUEST 8 +#define PING_REPLY 0 +#define CODE_ZERO 0 + +#define SOCKET_ERROR 1 +#define TIMEOUT_ERROR 2 +#define PING_SUCCESS 3 +#define REPLY_ERROR 4 +#define FUNCTION_ERROR 5 +#define PING_DEBUG + +typedef struct pingmsg { + uint8_t Type; // 0 - Ping Reply, 8 - Ping Request + uint8_t Code; // Always 0 + int16_t CheckSum; // Check sum + int16_t ID; // Identification + int16_t SeqNum; // Sequence Number + int8_t Data[BUF_LEN]; // Ping Data : 1452 = IP RAW MTU - sizeof(Type+Code+CheckSum+ID+SeqNum) +} PINGMSGR; + +uint8_t ping_auto(uint8_t s, uint8_t* addr); +uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t* addr); +uint8_t ping_request(uint8_t s, uint8_t* addr); +uint8_t ping_reply(uint8_t s, uint8_t* addr, uint16_t rlen); +uint16_t checksum(uint8_t* data_buf, uint16_t len); +uint16_t htons( + uint16_t + hostshort); /* htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).*/ + +void eth_printf(const char* format, ...); + +#endif /* PING_H */ \ No newline at end of file diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.c new file mode 100755 index 00000000000..6580aa1620c --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.c @@ -0,0 +1,582 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ +#include "MQTTClient.h" + +static void NewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessage) { + md->topicName = aTopicName; + md->message = aMessage; +} + + +static int getNextPacketId(MQTTClient *c) { + return c->next_packetid = (c->next_packetid == MAX_PACKET_ID) ? 1 : c->next_packetid + 1; +} + + +static int sendPacket(MQTTClient* c, int length, Timer* timer) +{ + int rc = FAILURE, + sent = 0; + + while (sent < length && !TimerIsExpired(timer)) + { + rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, TimerLeftMS(timer)); + if (rc < 0) // there was an error writing the data + break; + sent += rc; + } + if (sent == length) + { + TimerCountdown(&c->ping_timer, c->keepAliveInterval); // record the fact that we have successfully sent the packet + rc = SUCCESSS; + } + else + rc = FAILURE; + return rc; +} + + +void MQTTClientInit(MQTTClient* c, Network* network, unsigned int command_timeout_ms, + unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size) +{ + int i; + c->ipstack = network; + + for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i) + c->messageHandlers[i].topicFilter = 0; + c->command_timeout_ms = command_timeout_ms; + c->buf = sendbuf; + c->buf_size = sendbuf_size; + c->readbuf = readbuf; + c->readbuf_size = readbuf_size; + c->isconnected = 0; + c->ping_outstanding = 0; + c->defaultMessageHandler = NULL; + c->next_packetid = 1; + TimerInit(&c->ping_timer); +#if defined(MQTT_TASK) + MutexInit(&c->mutex); +#endif +} + + +static int decodePacket(MQTTClient* c, int* value, int timeout) +{ + unsigned char i; + int multiplier = 1; + int len = 0; + const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4; + + *value = 0; + do + { + int rc = MQTTPACKET_READ_ERROR; + + if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES) + { + rc = MQTTPACKET_READ_ERROR; /* bad data */ + goto exit; + } + rc = c->ipstack->mqttread(c->ipstack, &i, 1, timeout); + if (rc != 1) + goto exit; + *value += (i & 127) * multiplier; + multiplier *= 128; + } while ((i & 128) != 0); +exit: + return len; +} + + +static int readPacket(MQTTClient* c, Timer* timer) +{ + int rc = FAILURE; + MQTTHeader header = {0}; + int len = 0; + int rem_len = 0; + + /* 1. read the header byte. This has the packet type in it */ + if (c->ipstack->mqttread(c->ipstack, c->readbuf, 1, TimerLeftMS(timer)) != 1) + goto exit; + + len = 1; + /* 2. read the remaining length. This is variable in itself */ + decodePacket(c, &rem_len, TimerLeftMS(timer)); + len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */ + + /* 3. read the rest of the buffer using a callback to supply the rest of the data */ + if (rem_len > 0 && (c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len)) + goto exit; + + header.byte = c->readbuf[0]; + rc = header.bits.type; +exit: + return rc; +} + + +// assume topic filter and name is in correct format +// # can only be at end +// + and # can only be next to separator +static char isTopicMatched(char* topicFilter, MQTTString* topicName) +{ + char* curf = topicFilter; + char* curn = topicName->lenstring.data; + char* curn_end = curn + topicName->lenstring.len; + + while (*curf && curn < curn_end) + { + if (*curn == '/' && *curf != '/') + break; + if (*curf != '+' && *curf != '#' && *curf != *curn) + break; + if (*curf == '+') + { // skip until we meet the next separator, or end of string + char* nextpos = curn + 1; + while (nextpos < curn_end && *nextpos != '/') + nextpos = ++curn + 1; + } + else if (*curf == '#') + curn = curn_end - 1; // skip until end of string + curf++; + curn++; + }; + + return (curn == curn_end) && (*curf == '\0'); +} + + +int deliverMessage(MQTTClient* c, MQTTString* topicName, MQTTMessage* message) +{ + int i; + int rc = FAILURE; + + // we have to find the right message handler - indexed by topic + for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i) + { + if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) || + isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName))) + { + if (c->messageHandlers[i].fp != NULL) + { + MessageData md; + NewMessageData(&md, topicName, message); + c->messageHandlers[i].fp(&md); + rc = SUCCESSS; + } + } + } + + if (rc == FAILURE && c->defaultMessageHandler != NULL) + { + MessageData md; + NewMessageData(&md, topicName, message); + c->defaultMessageHandler(&md); + rc = SUCCESSS; + } + + return rc; +} + + +int keepalive(MQTTClient* c) +{ + int rc = FAILURE; + + if (c->keepAliveInterval == 0) + { + rc = SUCCESSS; + goto exit; + } + + if (TimerIsExpired(&c->ping_timer)) + { + if (!c->ping_outstanding) + { + Timer timer; + TimerInit(&timer); + TimerCountdownMS(&timer, 1000); + int len = MQTTSerialize_pingreq(c->buf, c->buf_size); + if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESSS) // send the ping packet + c->ping_outstanding = 1; + } + } + +exit: + return rc; +} + + +int cycle(MQTTClient* c, Timer* timer) +{ + // read the socket, see what work is due + unsigned short packet_type = readPacket(c, timer); + + int len = 0, + rc = SUCCESSS; + + switch (packet_type) + { + case CONNACK: + case PUBACK: + case SUBACK: + break; + case PUBLISH: + { + MQTTString topicName; + MQTTMessage msg; + int intQoS; + if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName, + (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1) + goto exit; + msg.qos = (enum QoS)intQoS; + deliverMessage(c, &topicName, &msg); + if (msg.qos != QOS0) + { + if (msg.qos == QOS1) + len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id); + else if (msg.qos == QOS2) + len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id); + if (len <= 0) + rc = FAILURE; + else + rc = sendPacket(c, len, timer); + if (rc == FAILURE) + goto exit; // there was a problem + } + break; + } + case PUBREC: + { + unsigned short mypacketid; + unsigned char dup, type; + if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) + rc = FAILURE; + else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0) + rc = FAILURE; + else if ((rc = sendPacket(c, len, timer)) != SUCCESSS) // send the PUBREL packet + rc = FAILURE; // there was a problem + if (rc == FAILURE) + goto exit; // there was a problem + break; + } + case PUBCOMP: + break; + case PINGRESP: + c->ping_outstanding = 0; + break; + } + keepalive(c); +exit: + if (rc == SUCCESSS) + rc = packet_type; + return rc; +} + + +int MQTTYield(MQTTClient* c, int timeout_ms) +{ + int rc = SUCCESSS; + Timer timer; + + TimerInit(&timer); + TimerCountdownMS(&timer, timeout_ms); + + if (cycle(c, &timer) == FAILURE) + { + rc = FAILURE; + } + + return rc; +} + + +void MQTTRun(void* parm) +{ + Timer timer; + MQTTClient* c = (MQTTClient*)parm; + + TimerInit(&timer); + + while (1) + { +#if defined(MQTT_TASK) + MutexLock(&c->mutex); +#endif + TimerCountdownMS(&timer, 500); /* Don't wait too long if no traffic is incoming */ + cycle(c, &timer); +#if defined(MQTT_TASK) + MutexUnlock(&c->mutex); +#endif + } +} + + +#if defined(MQTT_TASK) +int MQTTStartTask(MQTTClient* client) +{ + return ThreadStart(&client->thread, &MQTTRun, client); +} +#endif + + +int waitfor(MQTTClient* c, int packet_type, Timer* timer) +{ + int rc = FAILURE; + + do + { + if (TimerIsExpired(timer)) + break; // we timed out + } + while ((rc = cycle(c, timer)) != packet_type); + + return rc; +} + + +int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options) +{ + Timer connect_timer; + int rc = FAILURE; + MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer; + int len = 0; + +#if defined(MQTT_TASK) + MutexLock(&c->mutex); +#endif + if (c->isconnected) /* don't send connect packet again if we are already connected */ + goto exit; + + TimerInit(&connect_timer); + TimerCountdownMS(&connect_timer, c->command_timeout_ms); + + if (options == 0) + options = &default_options; /* set default options if none were supplied */ + + c->keepAliveInterval = options->keepAliveInterval; + TimerCountdown(&c->ping_timer, c->keepAliveInterval); + if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0) + goto exit; + if ((rc = sendPacket(c, len, &connect_timer)) != SUCCESSS) // send the connect packet + goto exit; // there was a problem + + // this will be a blocking call, wait for the connack + if (waitfor(c, CONNACK, &connect_timer) == CONNACK) + { + unsigned char connack_rc = 255; + unsigned char sessionPresent = 0; + if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1) + rc = connack_rc; + else + rc = FAILURE; + } + else + rc = FAILURE; + +exit: + if (rc == SUCCESSS) + c->isconnected = 1; + +#if defined(MQTT_TASK) + MutexUnlock(&c->mutex); +#endif + + return rc; +} + + +int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler) +{ + int rc = FAILURE; + Timer timer; + int len = 0; + MQTTString topic = MQTTString_initializer; + topic.cstring = (char *)topicFilter; + // This was added because enum QoS was previously typed to *int which resulted in HardFault and unaligned integer read. + // This coping below makes sure the parameter for MQTTSerialize_subscribe is always char no matter what compiler is using for enums + char charQos = (char)qos; + +#if defined(MQTT_TASK) + MutexLock(&c->mutex); +#endif + if (!c->isconnected) + goto exit; + + TimerInit(&timer); + TimerCountdownMS(&timer, c->command_timeout_ms); + + len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, &charQos); + if (len <= 0) + goto exit; + if ((rc = sendPacket(c, len, &timer)) != SUCCESSS) // send the subscribe packet + goto exit; // there was a problem + + if (waitfor(c, SUBACK, &timer) == SUBACK) // wait for suback + { + int count = 0, grantedQoS = -1; + unsigned short mypacketid; + if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1) + rc = grantedQoS; // 0, 1, 2 or 0x80 + if (rc != 0x80) + { + int i; + for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i) + { + if (c->messageHandlers[i].topicFilter == 0) + { + c->messageHandlers[i].topicFilter = topicFilter; + c->messageHandlers[i].fp = messageHandler; + rc = 0; + break; + } + } + } + } + else + rc = FAILURE; + +exit: +#if defined(MQTT_TASK) + MutexUnlock(&c->mutex); +#endif + return rc; +} + + +int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter) +{ + int rc = FAILURE; + Timer timer; + MQTTString topic = MQTTString_initializer; + topic.cstring = (char *)topicFilter; + int len = 0; + +#if defined(MQTT_TASK) + MutexLock(&c->mutex); +#endif + if (!c->isconnected) + goto exit; + + TimerInit(&timer); + TimerCountdownMS(&timer, c->command_timeout_ms); + + if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0) + goto exit; + if ((rc = sendPacket(c, len, &timer)) != SUCCESSS) // send the subscribe packet + goto exit; // there was a problem + + if (waitfor(c, UNSUBACK, &timer) == UNSUBACK) + { + unsigned short mypacketid; // should be the same as the packetid above + if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1) + rc = 0; + } + else + rc = FAILURE; + +exit: +#if defined(MQTT_TASK) + MutexUnlock(&c->mutex); +#endif + return rc; +} + + +int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message) +{ + int rc = FAILURE; + Timer timer; + MQTTString topic = MQTTString_initializer; + topic.cstring = (char *)topicName; + int len = 0; + +#if defined(MQTT_TASK) + MutexLock(&c->mutex); +#endif + if (!c->isconnected) + goto exit; + + TimerInit(&timer); + TimerCountdownMS(&timer, c->command_timeout_ms); + + if (message->qos == QOS1 || message->qos == QOS2) + message->id = getNextPacketId(c); + + len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, + topic, (unsigned char*)message->payload, message->payloadlen); + if (len <= 0) + goto exit; + if ((rc = sendPacket(c, len, &timer)) != SUCCESSS) // send the subscribe packet + goto exit; // there was a problem + + if (message->qos == QOS1) + { + if (waitfor(c, PUBACK, &timer) == PUBACK) + { + unsigned short mypacketid; + unsigned char dup, type; + if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) + rc = FAILURE; + } + else + rc = FAILURE; + } + else if (message->qos == QOS2) + { + if (waitfor(c, PUBCOMP, &timer) == PUBCOMP) + { + unsigned short mypacketid; + unsigned char dup, type; + if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1) + rc = FAILURE; + } + else + rc = FAILURE; + } + +exit: +#if defined(MQTT_TASK) + MutexUnlock(&c->mutex); +#endif + return rc; +} + + +int MQTTDisconnect(MQTTClient* c) +{ + int rc = FAILURE; + Timer timer; // we might wait for incomplete incoming publishes to complete + int len = 0; + +#if defined(MQTT_TASK) + MutexLock(&c->mutex); +#endif + TimerInit(&timer); + TimerCountdownMS(&timer, c->command_timeout_ms); + + len = MQTTSerialize_disconnect(c->buf, c->buf_size); + if (len > 0) + rc = sendPacket(c, len, &timer); // send the disconnect packet + + c->isconnected = 0; + +#if defined(MQTT_TASK) + MutexUnlock(&c->mutex); +#endif + return rc; +} + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.h new file mode 100755 index 00000000000..47ea41578d0 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTClient.h @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - documentation and platform specific header + *******************************************************************************/ + +#if !defined(__MQTT_CLIENT_C_) +#define __MQTT_CLIENT_C_ + +#if defined(__cplusplus) + extern "C" { +#endif + +#if defined(WIN32_DLL) || defined(WIN64_DLL) + #define DLLImport __declspec(dllimport) + #define DLLExport __declspec(dllexport) +#elif defined(LINUX_SO) + #define DLLImport extern + #define DLLExport __attribute__ ((visibility ("default"))) +#else + #define DLLImport + #define DLLExport +#endif + +#include "./MQTTPacket/src/MQTTPacket.h" +#include "stdio.h" +#include "mqtt_interface.h" + +#define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */ + +#if !defined(MAX_MESSAGE_HANDLERS) +#define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */ +#endif + +enum QoS { QOS0, QOS1, QOS2 }; + +/* all failure return codes must be negative */ +enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESSS = 0 }; + +/* The Platform specific header must define the Network and Timer structures and functions + * which operate on them. + * +typedef struct Network +{ + int (*mqttread)(Network*, unsigned char* read_buffer, int, int); + int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int); +} Network;*/ + +/* The Timer structure must be defined in the platform specific header, + * and have the following functions to operate on it. */ +extern void TimerInit(Timer*); +extern char TimerIsExpired(Timer*); +extern void TimerCountdownMS(Timer*, unsigned int); +extern void TimerCountdown(Timer*, unsigned int); +extern int TimerLeftMS(Timer*); + +typedef struct MQTTMessage +{ + enum QoS qos; + unsigned char retained; + unsigned char dup; + unsigned short id; + void *payload; + size_t payloadlen; +} MQTTMessage; + +typedef struct MessageData +{ + MQTTMessage* message; + MQTTString* topicName; +} MessageData; + +typedef void (*messageHandler)(MessageData*); + +typedef struct MQTTClient +{ + unsigned int next_packetid, + command_timeout_ms; + size_t buf_size, + readbuf_size; + unsigned char *buf, + *readbuf; + unsigned int keepAliveInterval; + char ping_outstanding; + int isconnected; + + struct MessageHandlers + { + const char* topicFilter; + void (*fp) (MessageData*); + } messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */ + + void (*defaultMessageHandler) (MessageData*); + + Network* ipstack; + Timer ping_timer; +#if defined(MQTT_TASK) + Mutex mutex; + Thread thread; +#endif +} MQTTClient; + +#define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0} + + +/** + * Create an MQTT client object + * @param client + * @param network + * @param command_timeout_ms + * @param + */ +DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms, + unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size); + +/** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack + * The nework object must be connected to the network endpoint before calling this + * @param options - connect options + * @return success code + */ +DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options); + +/** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs + * @param client - the client object to use + * @param topic - the topic to publish to + * @param message - the message to send + * @return success code + */ +DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*); + +/** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning. + * @param client - the client object to use + * @param topicFilter - the topic filter to subscribe to + * @param message - the message to send + * @return success code + */ +DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler); + +/** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning. + * @param client - the client object to use + * @param topicFilter - the topic filter to unsubscribe from + * @return success code + */ +DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter); + +/** MQTT Disconnect - send an MQTT disconnect packet and close the connection + * @param client - the client object to use + * @return success code + */ +DLLExport int MQTTDisconnect(MQTTClient* client); + +/** MQTT Yield - MQTT background + * @param client - the client object to use + * @param time - the time, in milliseconds, to yield for + * @return success code + */ +DLLExport int MQTTYield(MQTTClient* client, int time); + +#if defined(MQTT_TASK) +/** MQTT start background thread for a client. After this, MQTTYield should not be called. +* @param client - the client object to use +* @return success code +*/ +DLLExport int MQTTStartTask(MQTTClient* client); +#endif + +#if defined(__cplusplus) + } +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnect.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnect.h new file mode 100755 index 00000000000..db9025149be --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnect.h @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Xiang Rong - 442039 Add makefile to Embedded C client + *******************************************************************************/ + +#ifndef MQTTCONNECT_H_ +#define MQTTCONNECT_H_ + +#if !defined(DLLImport) + #define DLLImport +#endif +#if !defined(DLLExport) + #define DLLExport +#endif + + +typedef union +{ + unsigned char all; /**< all connect flags */ +#if defined(REVERSED) + struct + { + unsigned int username : 1; /**< 3.1 user name */ + unsigned int password : 1; /**< 3.1 password */ + unsigned int willRetain : 1; /**< will retain setting */ + unsigned int willQoS : 2; /**< will QoS value */ + unsigned int will : 1; /**< will flag */ + unsigned int cleansession : 1; /**< clean session flag */ + unsigned int : 1; /**< unused */ + } bits; +#else + struct + { + unsigned int : 1; /**< unused */ + unsigned int cleansession : 1; /**< cleansession flag */ + unsigned int will : 1; /**< will flag */ + unsigned int willQoS : 2; /**< will QoS value */ + unsigned int willRetain : 1; /**< will retain setting */ + unsigned int password : 1; /**< 3.1 password */ + unsigned int username : 1; /**< 3.1 user name */ + } bits; +#endif +} MQTTConnectFlags; /**< connect flags byte */ + + + +/** + * Defines the MQTT "Last Will and Testament" (LWT) settings for + * the connect packet. + */ +typedef struct +{ + /** The eyecatcher for this structure. must be MQTW. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** The LWT topic to which the LWT message will be published. */ + MQTTString topicName; + /** The LWT payload. */ + MQTTString message; + /** + * The retained flag for the LWT message (see MQTTAsync_message.retained). + */ + unsigned char retained; + /** + * The quality of service setting for the LWT message (see + * MQTTAsync_message.qos and @ref qos). + */ + char qos; +} MQTTPacket_willOptions; + + +#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 } + + +typedef struct +{ + /** The eyecatcher for this structure. must be MQTC. */ + char struct_id[4]; + /** The version number of this structure. Must be 0 */ + int struct_version; + /** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1 + */ + unsigned char MQTTVersion; + MQTTString clientID; + unsigned short keepAliveInterval; + unsigned char cleansession; + unsigned char willFlag; + MQTTPacket_willOptions will; + MQTTString username; + MQTTString password; +} MQTTPacket_connectData; + +typedef union +{ + unsigned char all; /**< all connack flags */ +#if defined(REVERSED) + struct + { + unsigned int sessionpresent : 1; /**< session present flag */ + unsigned int : 7; /**< unused */ + } bits; +#else + struct + { + unsigned int : 7; /**< unused */ + unsigned int sessionpresent : 1; /**< session present flag */ + } bits; +#endif +} MQTTConnackFlags; /**< connack flags byte */ + +#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \ + MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} } + +DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options); +DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len); + +DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent); +DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen); + +DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen); +DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen); + +#endif /* MQTTCONNECT_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectClient.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectClient.c new file mode 100755 index 00000000000..5f3cc2963c8 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectClient.c @@ -0,0 +1,214 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "MQTTPacket.h" +#include "StackTrace.h" + +#include + +/** + * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. + * @param options the options to be used to build the connect packet + * @return the length of buffer needed to contain the serialized version of the packet + */ +int MQTTSerialize_connectLength(MQTTPacket_connectData* options) +{ + int len = 0; + + FUNC_ENTRY; + + if (options->MQTTVersion == 3) + len = 12; /* variable depending on MQTT or MQIsdp */ + else if (options->MQTTVersion == 4) + len = 10; + + len += MQTTstrlen(options->clientID)+2; + if (options->willFlag) + len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2; + if (options->username.cstring || options->username.lenstring.data) + len += MQTTstrlen(options->username)+2; + if (options->password.cstring || options->password.lenstring.data) + len += MQTTstrlen(options->password)+2; + + FUNC_EXIT_RC(len); + return len; +} + + +/** + * Serializes the connect options into the buffer. + * @param buf the buffer into which the packet will be serialized + * @param len the length in bytes of the supplied buffer + * @param options the options to be used to build the connect packet + * @return serialized length, or error if 0 + */ +int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options) +{ + unsigned char *ptr = buf; + MQTTHeader header = {0}; + MQTTConnectFlags flags = {0}; + int len = 0; + int rc = -1; + + FUNC_ENTRY; + if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + + header.byte = 0; + header.bits.type = CONNECT; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, len); /* write remaining length */ + + if (options->MQTTVersion == 4) + { + writeCString(&ptr, "MQTT"); + writeChar(&ptr, (char) 4); + } + else + { + writeCString(&ptr, "MQIsdp"); + writeChar(&ptr, (char) 3); + } + + flags.all = 0; + flags.bits.cleansession = options->cleansession; + flags.bits.will = (options->willFlag) ? 1 : 0; + if (flags.bits.will) + { + flags.bits.willQoS = options->will.qos; + flags.bits.willRetain = options->will.retained; + } + + if (options->username.cstring || options->username.lenstring.data) + flags.bits.username = 1; + if (options->password.cstring || options->password.lenstring.data) + flags.bits.password = 1; + + writeChar(&ptr, flags.all); + writeInt(&ptr, options->keepAliveInterval); + writeMQTTString(&ptr, options->clientID); + if (options->willFlag) + { + writeMQTTString(&ptr, options->will.topicName); + writeMQTTString(&ptr, options->will.message); + } + if (flags.bits.username) + writeMQTTString(&ptr, options->username); + if (flags.bits.password) + writeMQTTString(&ptr, options->password); + + rc = ptr - buf; + + exit: FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Deserializes the supplied (wire) buffer into connack data - return code + * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) + * @param connack_rc returned integer value of the connack return code + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param len the length in bytes of the data in the supplied buffer + * @return error code. 1 is success, 0 is failure + */ +int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen) +{ + MQTTHeader header = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = NULL; + int rc = 0; + int mylen; + MQTTConnackFlags flags = {0}; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + if (header.bits.type != CONNACK) + goto exit; + + curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ + enddata = curdata + mylen; + if (enddata - curdata < 2) + goto exit; + + flags.all = readChar(&curdata); + *sessionPresent = flags.bits.sessionpresent; + *connack_rc = readChar(&curdata); + + rc = 1; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer, to avoid overruns + * @param packettype the message type + * @return serialized length, or error if 0 + */ +int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype) +{ + MQTTHeader header = {0}; + int rc = -1; + unsigned char *ptr = buf; + + FUNC_ENTRY; + if (buflen < 2) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + header.byte = 0; + header.bits.type = packettype; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */ + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer, to avoid overruns + * @return serialized length, or error if 0 + */ +int MQTTSerialize_disconnect(unsigned char* buf, int buflen) +{ + return MQTTSerialize_zero(buf, buflen, DISCONNECT); +} + + +/** + * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer, to avoid overruns + * @return serialized length, or error if 0 + */ +int MQTTSerialize_pingreq(unsigned char* buf, int buflen) +{ + return MQTTSerialize_zero(buf, buflen, PINGREQ); +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectServer.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectServer.c new file mode 100755 index 00000000000..07c7cb53743 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTConnectServer.c @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "StackTrace.h" +#include "MQTTPacket.h" +#include + +#define min(a, b) ((a < b) ? a : b) + + +/** + * Validates MQTT protocol name and version combinations + * @param protocol the MQTT protocol name as an MQTTString + * @param version the MQTT protocol version number, as in the connect packet + * @return correct MQTT combination? 1 is true, 0 is false + */ +int MQTTPacket_checkVersion(MQTTString* protocol, int version) +{ + int rc = 0; + + if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp", + min(6, protocol->lenstring.len)) == 0) + rc = 1; + else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT", + min(4, protocol->lenstring.len)) == 0) + rc = 1; + return rc; +} + + +/** + * Deserializes the supplied (wire) buffer into connect data structure + * @param data the connect data structure to be filled out + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param len the length in bytes of the data in the supplied buffer + * @return error code. 1 is success, 0 is failure + */ +int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len) +{ + MQTTHeader header = {0}; + MQTTConnectFlags flags = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = &buf[len]; + int rc = 0; + MQTTString Protocol; + int version; + int mylen = 0; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + if (header.bits.type != CONNECT) + goto exit; + + curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */ + + if (!readMQTTLenString(&Protocol, &curdata, enddata) || + enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ + goto exit; + + version = (int)readChar(&curdata); /* Protocol version */ + /* If we don't recognize the protocol version, we don't parse the connect packet on the + * basis that we don't know what the format will be. + */ + if (MQTTPacket_checkVersion(&Protocol, version)) + { + flags.all = readChar(&curdata); + data->cleansession = flags.bits.cleansession; + data->keepAliveInterval = readInt(&curdata); + if (!readMQTTLenString(&data->clientID, &curdata, enddata)) + goto exit; + data->willFlag = flags.bits.will; + if (flags.bits.will) + { + data->will.qos = flags.bits.willQoS; + data->will.retained = flags.bits.willRetain; + if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) || + !readMQTTLenString(&data->will.message, &curdata, enddata)) + goto exit; + } + if (flags.bits.username) + { + if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata)) + goto exit; /* username flag set, but no username supplied - invalid */ + if (flags.bits.password && + (enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata))) + goto exit; /* password flag set, but no password supplied - invalid */ + } + else if (flags.bits.password) + goto exit; /* password flag set without username - invalid */ + rc = 1; + } +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Serializes the connack packet into the supplied buffer. + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param connack_rc the integer connack return code to be used + * @param sessionPresent the MQTT 3.1.1 sessionPresent flag + * @return serialized length, or error if 0 + */ +int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent) +{ + MQTTHeader header = {0}; + int rc = 0; + unsigned char *ptr = buf; + MQTTConnackFlags flags = {0}; + + FUNC_ENTRY; + if (buflen < 2) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + header.byte = 0; + header.bits.type = CONNACK; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ + + flags.all = 0; + flags.bits.sessionpresent = sessionPresent; + writeChar(&ptr, flags.all); + writeChar(&ptr, connack_rc); + + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTDeserializePublish.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTDeserializePublish.c new file mode 100755 index 00000000000..dafb6a32a1d --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTDeserializePublish.c @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "StackTrace.h" +#include "MQTTPacket.h" +#include + +#define min(a, b) ((a < b) ? 1 : 0) + +/** + * Deserializes the supplied (wire) buffer into publish data + * @param dup returned integer - the MQTT dup flag + * @param qos returned integer - the MQTT QoS value + * @param retained returned integer - the MQTT retained flag + * @param packetid returned integer - the MQTT packet identifier + * @param topicName returned MQTTString - the MQTT topic in the publish + * @param payload returned byte buffer - the MQTT publish payload + * @param payloadlen returned integer - the length of the MQTT payload + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @return error code. 1 is success + */ +int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName, + unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen) +{ + MQTTHeader header = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = NULL; + int rc = 0; + int mylen = 0; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + if (header.bits.type != PUBLISH) + goto exit; + *dup = header.bits.dup; + *qos = header.bits.qos; + *retained = header.bits.retain; + + curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ + enddata = curdata + mylen; + + if (!readMQTTLenString(topicName, &curdata, enddata) || + enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ + goto exit; + + if (*qos > 0) + *packetid = readInt(&curdata); + + *payloadlen = enddata - curdata; + *payload = curdata; + rc = 1; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + + +/** + * Deserializes the supplied (wire) buffer into an ack + * @param packettype returned integer - the MQTT packet type + * @param dup returned integer - the MQTT dup flag + * @param packetid returned integer - the MQTT packet identifier + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @return error code. 1 is success, 0 is failure + */ +int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen) +{ + MQTTHeader header = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = NULL; + int rc = 0; + int mylen; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + *dup = header.bits.dup; + *packettype = header.bits.type; + + curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ + enddata = curdata + mylen; + + if (enddata - curdata < 2) + goto exit; + *packetid = readInt(&curdata); + + rc = 1; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.c new file mode 100755 index 00000000000..9c9ef9500e0 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.c @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "StackTrace.h" +#include "MQTTPacket.h" + +#include + + +const char* MQTTPacket_names[] = +{ + "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", + "PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", + "PINGREQ", "PINGRESP", "DISCONNECT" +}; + + +const char* MQTTPacket_getName(unsigned short packetid) +{ + return MQTTPacket_names[packetid]; +} + + +int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data) +{ + int strindex = 0; + + strindex = snprintf(strbuf, strbuflen, + "CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d", + (int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data, + (int)data->cleansession, data->keepAliveInterval); + if (data->willFlag) + strindex += snprintf(&strbuf[strindex], strbuflen - strindex, + ", will QoS %d, will retain %d, will topic %.*s, will message %.*s", + data->will.qos, data->will.retained, + data->will.topicName.lenstring.len, data->will.topicName.lenstring.data, + data->will.message.lenstring.len, data->will.message.lenstring.data); + if (data->username.lenstring.data && data->username.lenstring.len > 0) + strindex += snprintf(&strbuf[strindex], strbuflen - strindex, + ", user name %.*s", data->username.lenstring.len, data->username.lenstring.data); + if (data->password.lenstring.data && data->password.lenstring.len > 0) + strindex += snprintf(&strbuf[strindex], strbuflen - strindex, + ", password %.*s", data->password.lenstring.len, data->password.lenstring.data); + return strindex; +} + + +int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent) +{ + int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc); + return strindex; +} + + +int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, + unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen) +{ + int strindex = snprintf(strbuf, strbuflen, + "PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s", + dup, qos, retained, packetid, + (topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data, + payloadlen, (payloadlen < 20) ? payloadlen : 20, payload); + return strindex; +} + + +int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid) +{ + int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid); + if (dup) + strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup); + return strindex; +} + + +int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, + MQTTString topicFilters[], int requestedQoSs[]) +{ + return snprintf(strbuf, strbuflen, + "SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d", + dup, packetid, count, + topicFilters[0].lenstring.len, topicFilters[0].lenstring.data, + requestedQoSs[0]); +} + + +int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs) +{ + return snprintf(strbuf, strbuflen, + "SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]); +} + + +int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[]) +{ + return snprintf(strbuf, strbuflen, + "UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s", + dup, packetid, count, + topicFilters[0].lenstring.len, topicFilters[0].lenstring.data); +} + + +char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen) +{ + int index = 0; + int rem_length = 0; + MQTTHeader header = {0}; + header.byte = buf[index++]; + index += MQTTPacket_decodeBuf(&buf[index], &rem_length); + + switch (header.bits.type) + { + case CONNACK: + { + unsigned char sessionPresent, connack_rc; + if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1) + MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent); + } + break; + case PUBLISH: + { + unsigned char dup, retained, *payload; + unsigned short packetid; + int qos, payloadlen; + MQTTString topicName = MQTTString_initializer; + if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName, + &payload, &payloadlen, buf, buflen) == 1) + MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, + topicName, payload, payloadlen); + } + break; + case PUBACK: + case PUBREC: + case PUBREL: + case PUBCOMP: + { + unsigned char packettype, dup; + unsigned short packetid; + if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1) + MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid); + } + break; + case SUBACK: + { + unsigned short packetid; + int maxcount = 1, count = 0; + int grantedQoSs[1]; + if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1) + MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs); + } + break; + case UNSUBACK: + { + unsigned short packetid; + if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1) + MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid); + } + break; + case PINGREQ: + case PINGRESP: + case DISCONNECT: + snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]); + break; + } + return strbuf; +} + + +char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen) +{ + int index = 0; + int rem_length = 0; + MQTTHeader header = {0}; + + header.byte = buf[index++]; + index += MQTTPacket_decodeBuf(&buf[index], &rem_length); + + switch (header.bits.type) + { + case CONNECT: + { + MQTTPacket_connectData data; + int rc; + if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1) + MQTTStringFormat_connect(strbuf, strbuflen, &data); + } + break; + case PUBLISH: + { + unsigned char dup, retained, *payload; + unsigned short packetid; + int qos, payloadlen; + MQTTString topicName = MQTTString_initializer; + if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName, + &payload, &payloadlen, buf, buflen) == 1) + MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, + topicName, payload, payloadlen); + } + break; + case PUBACK: + case PUBREC: + case PUBREL: + case PUBCOMP: + { + unsigned char packettype, dup; + unsigned short packetid; + if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1) + MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid); + } + break; + case SUBSCRIBE: + { + unsigned char dup; + unsigned short packetid; + int maxcount = 1, count = 0; + MQTTString topicFilters[1]; + int requestedQoSs[1]; + if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count, + topicFilters, requestedQoSs, buf, buflen) == 1) + MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);; + } + break; + case UNSUBSCRIBE: + { + unsigned char dup; + unsigned short packetid; + int maxcount = 1, count = 0; + MQTTString topicFilters[1]; + if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1) + MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters); + } + break; + case PINGREQ: + case PINGRESP: + case DISCONNECT: + snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]); + break; + } + strbuf[strbuflen] = '\0'; + return strbuf; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.h new file mode 100755 index 00000000000..47b0c414341 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTFormat.h @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#if !defined(MQTTFORMAT_H) +#define MQTTFORMAT_H + +#include "StackTrace.h" +#include "MQTTPacket.h" + +const char* MQTTPacket_getName(unsigned short packetid); +int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data); +int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent); +int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, + unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen); +int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid); +int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, + MQTTString topicFilters[], int requestedQoSs[]); +int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs); +int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[]); +char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen); +char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen); + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.c new file mode 100755 index 00000000000..bd5f90a537f --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.c @@ -0,0 +1,410 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Sergio R. Caprile - non-blocking packet read functions for stream transport + *******************************************************************************/ + +#include "StackTrace.h" +#include "MQTTPacket.h" + +#include + +/** + * Encodes the message length according to the MQTT algorithm + * @param buf the buffer into which the encoded data is written + * @param length the length to be encoded + * @return the number of bytes written to buffer + */ +int MQTTPacket_encode(unsigned char* buf, int length) +{ + int rc = 0; + + FUNC_ENTRY; + do + { + char d = length % 128; + length /= 128; + /* if there are more digits to encode, set the top bit of this digit */ + if (length > 0) + d |= 0x80; + buf[rc++] = d; + } while (length > 0); + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Decodes the message length according to the MQTT algorithm + * @param getcharfn pointer to function to read the next character from the data source + * @param value the decoded length returned + * @return the number of bytes read from the socket + */ +int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value) +{ + unsigned char c; + int multiplier = 1; + int len = 0; +#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4 + + FUNC_ENTRY; + *value = 0; + do + { + int rc = MQTTPACKET_READ_ERROR; + + if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES) + { + rc = MQTTPACKET_READ_ERROR; /* bad data */ + goto exit; + } + rc = (*getcharfn)(&c, 1); + if (rc != 1) + goto exit; + *value += (c & 127) * multiplier; + multiplier *= 128; + } while ((c & 128) != 0); +exit: + FUNC_EXIT_RC(len); + return len; +} + + +int MQTTPacket_len(int rem_len) +{ + rem_len += 1; /* header byte */ + + /* now remaining_length field */ + if (rem_len < 128) + rem_len += 1; + else if (rem_len < 16384) + rem_len += 2; + else if (rem_len < 2097151) + rem_len += 3; + else + rem_len += 4; + return rem_len; +} + + +static unsigned char* bufptr; + +int bufchar(unsigned char* c, int count) +{ + int i; + + for (i = 0; i < count; ++i) + *c = *bufptr++; + return count; +} + + +int MQTTPacket_decodeBuf(unsigned char* buf, int* value) +{ + bufptr = buf; + return MQTTPacket_decode(bufchar, value); +} + + +/** + * Calculates an integer from two bytes read from the input buffer + * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned + * @return the integer value calculated + */ +int readInt(unsigned char** pptr) +{ + unsigned char* ptr = *pptr; + int len = 256*(*ptr) + (*(ptr+1)); + *pptr += 2; + return len; +} + + +/** + * Reads one character from the input buffer. + * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned + * @return the character read + */ +char readChar(unsigned char** pptr) +{ + char c = **pptr; + (*pptr)++; + return c; +} + + +/** + * Writes one character to an output buffer. + * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned + * @param c the character to write + */ +void writeChar(unsigned char** pptr, char c) +{ + **pptr = c; + (*pptr)++; +} + + +/** + * Writes an integer as 2 bytes to an output buffer. + * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned + * @param anInt the integer to write + */ +void writeInt(unsigned char** pptr, int anInt) +{ + **pptr = (unsigned char)(anInt / 256); + (*pptr)++; + **pptr = (unsigned char)(anInt % 256); + (*pptr)++; +} + + +/** + * Writes a "UTF" string to an output buffer. Converts C string to length-delimited. + * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned + * @param string the C string to write + */ +void writeCString(unsigned char** pptr, const char* string) +{ + int len = strlen(string); + writeInt(pptr, len); + memcpy(*pptr, string, len); + *pptr += len; +} + + +int getLenStringLen(char* ptr) +{ + int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1)); + return len; +} + + +void writeMQTTString(unsigned char** pptr, MQTTString mqttstring) +{ + if (mqttstring.lenstring.len > 0) + { + writeInt(pptr, mqttstring.lenstring.len); + memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len); + *pptr += mqttstring.lenstring.len; + } + else if (mqttstring.cstring) + writeCString(pptr, mqttstring.cstring); + else + writeInt(pptr, 0); +} + + +/** + * @param mqttstring the MQTTString structure into which the data is to be read + * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned + * @param enddata pointer to the end of the data: do not read beyond + * @return 1 if successful, 0 if not + */ +int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata) +{ + int rc = 0; + + FUNC_ENTRY; + /* the first two bytes are the length of the string */ + if (enddata - (*pptr) > 1) /* enough length to read the integer? */ + { + mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */ + if (&(*pptr)[mqttstring->lenstring.len] <= enddata) + { + mqttstring->lenstring.data = (char*)*pptr; + *pptr += mqttstring->lenstring.len; + rc = 1; + } + } + mqttstring->cstring = NULL; + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string + * @param mqttstring the string to return the length of + * @return the length of the string + */ +int MQTTstrlen(MQTTString mqttstring) +{ + int rc = 0; + + if (mqttstring.cstring) + rc = strlen(mqttstring.cstring); + else + rc = mqttstring.lenstring.len; + return rc; +} + + +/** + * Compares an MQTTString to a C string + * @param a the MQTTString to compare + * @param bptr the C string to compare + * @return boolean - equal or not + */ +int MQTTPacket_equals(MQTTString* a, char* bptr) +{ + int alen = 0, + blen = 0; + char *aptr; + + if (a->cstring) + { + aptr = a->cstring; + alen = strlen(a->cstring); + } + else + { + aptr = a->lenstring.data; + alen = a->lenstring.len; + } + blen = strlen(bptr); + + return (alen == blen) && (strncmp(aptr, bptr, alen) == 0); +} + + +/** + * Helper function to read packet data from some source into a buffer + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param getfn pointer to a function which will read any number of bytes from the needed source + * @return integer MQTT packet type, or -1 on error + * @note the whole message must fit into the caller's buffer + */ +int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)) +{ + int rc = -1; + MQTTHeader header = {0}; + int len = 0; + int rem_len = 0; + + /* 1. read the header byte. This has the packet type in it */ + if ((*getfn)(buf, 1) != 1) + goto exit; + + len = 1; + /* 2. read the remaining length. This is variable in itself */ + MQTTPacket_decode(getfn, &rem_len); + len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */ + + /* 3. read the rest of the buffer using a callback to supply the rest of the data */ + if((rem_len + len) > buflen) + goto exit; + if ((*getfn)(buf + len, rem_len) != rem_len) + goto exit; + + header.byte = buf[0]; + rc = header.bits.type; +exit: + return rc; +} + +/** + * Decodes the message length according to the MQTT algorithm, non-blocking + * @param trp pointer to a transport structure holding what is needed to solve getting data from it + * @param value the decoded length returned + * @return integer the number of bytes read from the socket, 0 for call again, or -1 on error + */ +static int MQTTPacket_decodenb(MQTTTransport *trp) +{ + unsigned char c; + int rc = MQTTPACKET_READ_ERROR; + + FUNC_ENTRY; + if(trp->len == 0){ /* initialize on first call */ + trp->multiplier = 1; + trp->rem_len = 0; + } + do { + int frc; + if (++(trp->len) > MAX_NO_OF_REMAINING_LENGTH_BYTES) + goto exit; + if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1) + goto exit; + if (frc == 0){ + rc = 0; + goto exit; + } + trp->rem_len += (c & 127) * trp->multiplier; + trp->multiplier *= 128; + } while ((c & 128) != 0); + rc = trp->len; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + +/** + * Helper function to read packet data from some source into a buffer, non-blocking + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param trp pointer to a transport structure holding what is needed to solve getting data from it + * @return integer MQTT packet type, 0 for call again, or -1 on error + * @note the whole message must fit into the caller's buffer + */ +int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp) +{ + int rc = -1, frc; + MQTTHeader header = {0}; + + switch(trp->state){ + default: + trp->state = 0; + /*FALLTHROUGH*/ + case 0: + /* read the header byte. This has the packet type in it */ + if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1) + goto exit; + if (frc == 0) + return 0; + trp->len = 0; + ++trp->state; + /*FALLTHROUGH*/ + /* read the remaining length. This is variable in itself */ + case 1: + if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR) + goto exit; + if(frc == 0) + return 0; + trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */ + if((trp->rem_len + trp->len) > buflen) + goto exit; + ++trp->state; + /*FALLTHROUGH*/ + case 2: + /* read the rest of the buffer using a callback to supply the rest of the data */ + if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1) + goto exit; + if (frc == 0) + return 0; + trp->rem_len -= frc; + trp->len += frc; + if(trp->rem_len) + return 0; + + header.byte = buf[0]; + rc = header.bits.type; + break; + } + +exit: + trp->state = 0; + return rc; +} + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.h new file mode 100755 index 00000000000..588966d8b62 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPacket.h @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Xiang Rong - 442039 Add makefile to Embedded C client + *******************************************************************************/ + +#ifndef MQTTPACKET_H_ +#define MQTTPACKET_H_ + +#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */ +extern "C" { +#endif + +#if defined(WIN32_DLL) || defined(WIN64_DLL) + #define DLLImport __declspec(dllimport) + #define DLLExport __declspec(dllexport) +#elif defined(LINUX_SO) + #define DLLImport extern + #define DLLExport __attribute__ ((visibility ("default"))) +#else + #define DLLImport + #define DLLExport +#endif + +enum errors +{ + MQTTPACKET_BUFFER_TOO_SHORT = -2, + MQTTPACKET_READ_ERROR = -1, + MQTTPACKET_READ_COMPLETE +}; + +enum msgTypes +{ + CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, + PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, + PINGREQ, PINGRESP, DISCONNECT +}; + +/** + * Bitfields for the MQTT header byte. + */ +typedef union +{ + unsigned char byte; /**< the whole byte */ +#if defined(REVERSED) + struct + { + unsigned int type : 4; /**< message type nibble */ + unsigned int dup : 1; /**< DUP flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + unsigned int retain : 1; /**< retained flag bit */ + } bits; +#else + struct + { + unsigned int retain : 1; /**< retained flag bit */ + unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ + unsigned int dup : 1; /**< DUP flag bit */ + unsigned int type : 4; /**< message type nibble */ + } bits; +#endif +} MQTTHeader; + +typedef struct +{ + int len; + char* data; +} MQTTLenString; + +typedef struct +{ + char* cstring; + MQTTLenString lenstring; +} MQTTString; + +#define MQTTString_initializer {NULL, {0, NULL}} + +int MQTTstrlen(MQTTString mqttstring); + +#include "MQTTConnect.h" +#include "MQTTPublish.h" +#include "MQTTSubscribe.h" +#include "MQTTUnsubscribe.h" +#include "MQTTFormat.h" + +int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid); +int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen); + +int MQTTPacket_len(int rem_len); +int MQTTPacket_equals(MQTTString* a, char* b); + +int MQTTPacket_encode(unsigned char* buf, int length); +int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value); +int MQTTPacket_decodeBuf(unsigned char* buf, int* value); + +int readInt(unsigned char** pptr); +char readChar(unsigned char** pptr); +void writeChar(unsigned char** pptr, char c); +void writeInt(unsigned char** pptr, int anInt); +int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata); +void writeCString(unsigned char** pptr, const char* string); +void writeMQTTString(unsigned char** pptr, MQTTString mqttstring); + +DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)); + +typedef struct { + int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */ + void *sck; /* pointer to whatever the system may use to identify the transport */ + int multiplier; + int rem_len; + int len; + char state; +}MQTTTransport; + +int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp); + +#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ +} +#endif + + +#endif /* MQTTPACKET_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPublish.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPublish.h new file mode 100755 index 00000000000..ebe479dd5bb --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTPublish.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Xiang Rong - 442039 Add makefile to Embedded C client + *******************************************************************************/ + +#ifndef MQTTPUBLISH_H_ +#define MQTTPUBLISH_H_ + +#if !defined(DLLImport) + #define DLLImport +#endif +#if !defined(DLLExport) + #define DLLExport +#endif + +DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, + MQTTString topicName, unsigned char* payload, int payloadlen); + +DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName, + unsigned char** payload, int* payloadlen, unsigned char* buf, int len); + +DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid); +DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid); +DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid); + +#endif /* MQTTPUBLISH_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSerializePublish.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSerializePublish.c new file mode 100755 index 00000000000..77a58b54ac1 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSerializePublish.c @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144 + *******************************************************************************/ + +#include "MQTTPacket.h" +#include "StackTrace.h" + +#include + + +/** + * Determines the length of the MQTT publish packet that would be produced using the supplied parameters + * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0) + * @param topicName the topic name to be used in the publish + * @param payloadlen the length of the payload to be sent + * @return the length of buffer needed to contain the serialized version of the packet + */ +int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen) +{ + int len = 0; + + len += 2 + MQTTstrlen(topicName) + payloadlen; + if (qos > 0) + len += 2; /* packetid */ + return len; +} + + +/** + * Serializes the supplied publish data into the supplied buffer, ready for sending + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param dup integer - the MQTT dup flag + * @param qos integer - the MQTT QoS value + * @param retained integer - the MQTT retained flag + * @param packetid integer - the MQTT packet identifier + * @param topicName MQTTString - the MQTT topic in the publish + * @param payload byte buffer - the MQTT publish payload + * @param payloadlen integer - the length of the MQTT payload + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, + MQTTString topicName, unsigned char* payload, int payloadlen) +{ + unsigned char *ptr = buf; + MQTTHeader header = {0}; + int rem_len = 0; + int rc = 0; + + FUNC_ENTRY; + if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + + header.bits.type = PUBLISH; + header.bits.dup = dup; + header.bits.qos = qos; + header.bits.retain = retained; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; + + writeMQTTString(&ptr, topicName); + + if (qos > 0) + writeInt(&ptr, packetid); + + memcpy(ptr, payload, payloadlen); + ptr += payloadlen; + + rc = ptr - buf; + +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + + +/** + * Serializes the ack packet into the supplied buffer. + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param type the MQTT packet type + * @param dup the MQTT dup flag + * @param packetid the MQTT packet identifier + * @return serialized length, or error if 0 + */ +int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid) +{ + MQTTHeader header = {0}; + int rc = 0; + unsigned char *ptr = buf; + + FUNC_ENTRY; + if (buflen < 4) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + header.bits.type = packettype; + header.bits.dup = dup; + header.bits.qos = (packettype == PUBREL) ? 1 : 0; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ + writeInt(&ptr, packetid); + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Serializes a puback packet into the supplied buffer. + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param packetid integer - the MQTT packet identifier + * @return serialized length, or error if 0 + */ +int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid) +{ + return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid); +} + + +/** + * Serializes a pubrel packet into the supplied buffer. + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param dup integer - the MQTT dup flag + * @param packetid integer - the MQTT packet identifier + * @return serialized length, or error if 0 + */ +int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid) +{ + return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid); +} + + +/** + * Serializes a pubrel packet into the supplied buffer. + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param packetid integer - the MQTT packet identifier + * @return serialized length, or error if 0 + */ +int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid) +{ + return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid); +} + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribe.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribe.h new file mode 100755 index 00000000000..a31fd704a0d --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribe.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Xiang Rong - 442039 Add makefile to Embedded C client + *******************************************************************************/ + +#ifndef MQTTSUBSCRIBE_H_ +#define MQTTSUBSCRIBE_H_ + +#if !defined(DLLImport) + #define DLLImport +#endif +#if !defined(DLLExport) + #define DLLExport +#endif + +DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[], char requestedQoSs[]); + +DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, + int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len); + +DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs); + +DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len); + + +#endif /* MQTTSUBSCRIBE_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeClient.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeClient.c new file mode 100755 index 00000000000..1a02255ff18 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeClient.c @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "MQTTPacket.h" +#include "StackTrace.h" + +#include + +/** + * Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters + * @param count the number of topic filter strings in topicFilters + * @param topicFilters the array of topic filter strings to be used in the publish + * @return the length of buffer needed to contain the serialized version of the packet + */ +int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[]) +{ + int i; + int len = 2; /* packetid */ + + for (i = 0; i < count; ++i) + len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */ + return len; +} + + +/** + * Serializes the supplied subscribe data into the supplied buffer, ready for sending + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied bufferr + * @param dup integer - the MQTT dup flag + * @param packetid integer - the MQTT packet identifier + * @param count - number of members in the topicFilters and reqQos arrays + * @param topicFilters - array of topic filter names + * @param requestedQoSs - array of requested QoS + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count, + MQTTString topicFilters[], char requestedQoSs[]) +{ + unsigned char *ptr = buf; + MQTTHeader header = {0}; + int rem_len = 0; + int rc = 0; + int i = 0; + + FUNC_ENTRY; + if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + + header.byte = 0; + header.bits.type = SUBSCRIBE; + header.bits.dup = dup; + header.bits.qos = 1; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; + + writeInt(&ptr, packetid); + + for (i = 0; i < count; ++i) + { + writeMQTTString(&ptr, topicFilters[i]); + writeChar(&ptr, requestedQoSs[i]); + } + + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + + +/** + * Deserializes the supplied (wire) buffer into suback data + * @param packetid returned integer - the MQTT packet identifier + * @param maxcount - the maximum number of members allowed in the grantedQoSs array + * @param count returned integer - number of members in the grantedQoSs array + * @param grantedQoSs returned array of integers - the granted qualities of service + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @return error code. 1 is success, 0 is failure + */ +int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen) +{ + MQTTHeader header = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = NULL; + int rc = 0; + int mylen; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + if (header.bits.type != SUBACK) + goto exit; + + curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ + enddata = curdata + mylen; + if (enddata - curdata < 2) + goto exit; + + *packetid = readInt(&curdata); + + *count = 0; + while (curdata < enddata) + { + if (*count > maxcount) + { + rc = -1; + goto exit; + } + grantedQoSs[(*count)++] = readChar(&curdata); + } + + rc = 1; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeServer.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeServer.c new file mode 100755 index 00000000000..5579645fec3 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTSubscribeServer.c @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "MQTTPacket.h" +#include "StackTrace.h" + +#include + + +/** + * Deserializes the supplied (wire) buffer into subscribe data + * @param dup integer returned - the MQTT dup flag + * @param packetid integer returned - the MQTT packet identifier + * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays + * @param count - number of members in the topicFilters and requestedQoSs arrays + * @param topicFilters - array of topic filter names + * @param requestedQoSs - array of requested QoS + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[], + int requestedQoSs[], unsigned char* buf, int buflen) +{ + MQTTHeader header = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = NULL; + int rc = -1; + int mylen = 0; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + if (header.bits.type != SUBSCRIBE) + goto exit; + *dup = header.bits.dup; + + curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ + enddata = curdata + mylen; + + *packetid = readInt(&curdata); + + *count = 0; + while (curdata < enddata) + { + if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata)) + goto exit; + if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */ + goto exit; + requestedQoSs[*count] = readChar(&curdata); + (*count)++; + } + + rc = 1; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Serializes the supplied suback data into the supplied buffer, ready for sending + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param packetid integer - the MQTT packet identifier + * @param count - number of members in the grantedQoSs array + * @param grantedQoSs - array of granted QoS + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs) +{ + MQTTHeader header = {0}; + int rc = -1; + unsigned char *ptr = buf; + int i; + + FUNC_ENTRY; + if (buflen < 2 + count) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + header.byte = 0; + header.bits.type = SUBACK; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */ + + writeInt(&ptr, packetid); + + for (i = 0; i < count; ++i) + writeChar(&ptr, grantedQoSs[i]); + + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribe.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribe.h new file mode 100755 index 00000000000..355ca9a427f --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribe.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Xiang Rong - 442039 Add makefile to Embedded C client + *******************************************************************************/ + +#ifndef MQTTUNSUBSCRIBE_H_ +#define MQTTUNSUBSCRIBE_H_ + +#if !defined(DLLImport) + #define DLLImport +#endif +#if !defined(DLLExport) + #define DLLExport +#endif + +DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[]); + +DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[], + unsigned char* buf, int len); + +DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid); + +DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len); + +#endif /* MQTTUNSUBSCRIBE_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeClient.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeClient.c new file mode 100755 index 00000000000..e7ec530215a --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeClient.c @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "MQTTPacket.h" +#include "StackTrace.h" + +#include + +/** + * Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters + * @param count the number of topic filter strings in topicFilters + * @param topicFilters the array of topic filter strings to be used in the publish + * @return the length of buffer needed to contain the serialized version of the packet + */ +int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[]) +{ + int i; + int len = 2; /* packetid */ + + for (i = 0; i < count; ++i) + len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/ + return len; +} + + +/** + * Serializes the supplied unsubscribe data into the supplied buffer, ready for sending + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @param dup integer - the MQTT dup flag + * @param packetid integer - the MQTT packet identifier + * @param count - number of members in the topicFilters array + * @param topicFilters - array of topic filter names + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, + int count, MQTTString topicFilters[]) +{ + unsigned char *ptr = buf; + MQTTHeader header = {0}; + int rem_len = 0; + int rc = -1; + int i = 0; + + FUNC_ENTRY; + if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + + header.byte = 0; + header.bits.type = UNSUBSCRIBE; + header.bits.dup = dup; + header.bits.qos = 1; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; + + writeInt(&ptr, packetid); + + for (i = 0; i < count; ++i) + writeMQTTString(&ptr, topicFilters[i]); + + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Deserializes the supplied (wire) buffer into unsuback data + * @param packetid returned integer - the MQTT packet identifier + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @return error code. 1 is success, 0 is failure + */ +int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen) +{ + unsigned char type = 0; + unsigned char dup = 0; + int rc = 0; + + FUNC_ENTRY; + rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen); + if (type == UNSUBACK) + rc = 1; + FUNC_EXIT_RC(rc); + return rc; +} + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeServer.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeServer.c new file mode 100755 index 00000000000..42b6102a700 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/MQTTUnsubscribeServer.c @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "MQTTPacket.h" +#include "StackTrace.h" + +#include + + +/** + * Deserializes the supplied (wire) buffer into unsubscribe data + * @param dup integer returned - the MQTT dup flag + * @param packetid integer returned - the MQTT packet identifier + * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays + * @param count - number of members in the topicFilters and requestedQoSs arrays + * @param topicFilters - array of topic filter names + * @param buf the raw buffer data, of the correct length determined by the remaining length field + * @param buflen the length in bytes of the data in the supplied buffer + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[], + unsigned char* buf, int len) +{ + MQTTHeader header = {0}; + unsigned char* curdata = buf; + unsigned char* enddata = NULL; + int rc = 0; + int mylen = 0; + + FUNC_ENTRY; + header.byte = readChar(&curdata); + if (header.bits.type != UNSUBSCRIBE) + goto exit; + *dup = header.bits.dup; + + curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ + enddata = curdata + mylen; + + *packetid = readInt(&curdata); + + *count = 0; + while (curdata < enddata) + { + if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata)) + goto exit; + (*count)++; + } + + rc = 1; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + +/** + * Serializes the supplied unsuback data into the supplied buffer, ready for sending + * @param buf the buffer into which the packet will be serialized + * @param buflen the length in bytes of the supplied buffer + * @param packetid integer - the MQTT packet identifier + * @return the length of the serialized data. <= 0 indicates error + */ +int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid) +{ + MQTTHeader header = {0}; + int rc = 0; + unsigned char *ptr = buf; + + FUNC_ENTRY; + if (buflen < 2) + { + rc = MQTTPACKET_BUFFER_TOO_SHORT; + goto exit; + } + header.byte = 0; + header.bits.type = UNSUBACK; + writeChar(&ptr, header.byte); /* write header */ + + ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ + + writeInt(&ptr, packetid); + + rc = ptr - buf; +exit: + FUNC_EXIT_RC(rc); + return rc; +} + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/StackTrace.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/StackTrace.h new file mode 100755 index 00000000000..2808a0d18ae --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/MQTTPacket/src/StackTrace.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Ian Craggs - initial API and implementation and/or initial documentation + * Ian Craggs - fix for bug #434081 + *******************************************************************************/ + +#ifndef STACKTRACE_H_ +#define STACKTRACE_H_ + +#include +#define NOSTACKTRACE 1 + +#if defined(NOSTACKTRACE) +#define FUNC_ENTRY +#define FUNC_ENTRY_NOLOG +#define FUNC_ENTRY_MED +#define FUNC_ENTRY_MAX +#define FUNC_EXIT +#define FUNC_EXIT_NOLOG +#define FUNC_EXIT_MED +#define FUNC_EXIT_MAX +#define FUNC_EXIT_RC(x) +#define FUNC_EXIT_MED_RC(x) +#define FUNC_EXIT_MAX_RC(x) + +#else + +#if defined(WIN32) +#define inline __inline +#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1) +#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) +#else +#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) +#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) +#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) +#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) +#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) +#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) +#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) +#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) +#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) +#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) +#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) + +void StackTrace_entry(const char* name, int line, int trace); +void StackTrace_exit(const char* name, int line, void* return_value, int trace); + +void StackTrace_printStack(FILE* dest); +char* StackTrace_get(unsigned long); + +#endif + +#endif + + + + +#endif /* STACKTRACE_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.c new file mode 100755 index 00000000000..375354386a8 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.c @@ -0,0 +1,182 @@ +//***************************************************************************** +//! \file mqtt_interface.c +//! \brief Paho MQTT to WIZnet Chip interface implement file. +//! \details The process of porting an interface to use paho MQTT. +//! \version 1.0.0 +//! \date 2016/12/06 +//! \par Revision history +//! <2016/12/06> 1st Release +//! +//! \author Peter Bang & Justin Kim +//! \copyright +//! +//! Copyright (c) 2016, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "mqtt_interface.h" +#include "wizchip_conf.h" +#include "socket.h" + +unsigned long MilliTimer; + +/* + * @brief MQTT MilliTimer handler + * @note MUST BE register to your system 1m Tick timer handler. + */ +void MilliTimer_Handler(void) { + MilliTimer++; +} + +/* + * @brief Timer Initialize + * @param timer : pointer to a Timer structure + * that contains the configuration information for the Timer. + */ +void TimerInit(Timer* timer) { + timer->end_time = 0; +} + +/* + * @brief expired Timer + * @param timer : pointer to a Timer structure + * that contains the configuration information for the Timer. + */ +char TimerIsExpired(Timer* timer) { + long left = timer->end_time - MilliTimer; + return (left < 0); +} + +/* + * @brief Countdown millisecond Timer + * @param timer : pointer to a Timer structure + * that contains the configuration information for the Timer. + * timeout : setting timeout millisecond. + */ +void TimerCountdownMS(Timer* timer, unsigned int timeout) { + timer->end_time = MilliTimer + timeout; +} + +/* + * @brief Countdown second Timer + * @param timer : pointer to a Timer structure + * that contains the configuration information for the Timer. + * timeout : setting timeout millisecond. + */ +void TimerCountdown(Timer* timer, unsigned int timeout) { + timer->end_time = MilliTimer + (timeout * 1000); +} + +/* + * @brief left millisecond Timer + * @param timer : pointer to a Timer structure + * that contains the configuration information for the Timer. + */ +int TimerLeftMS(Timer* timer) { + long left = timer->end_time - MilliTimer; + return (left < 0) ? 0 : left; +} + +/* + * @brief New network setting + * @param n : pointer to a Network structure + * that contains the configuration information for the Network. + * sn : socket number where x can be (0..7). + * @retval None + */ +void NewNetwork(Network* n, int sn) { + n->my_socket = sn; + n->mqttread = w5x00_read; + n->mqttwrite = w5x00_write; + n->disconnect = w5x00_disconnect; +} + +/* + * @brief read function + * @param n : pointer to a Network structure + * that contains the configuration information for the Network. + * buffer : pointer to a read buffer. + * len : buffer length. + * @retval received data length or SOCKERR code + */ +int w5x00_read(Network* n, unsigned char* buffer, int len, long time) +{ + + if((getSn_SR(n->my_socket) == SOCK_ESTABLISHED) && (getSn_RX_RSR(n->my_socket)>0)) + return recv(n->my_socket, buffer, len); + + return SOCK_ERROR; +} + +/* + * @brief write function + * @param n : pointer to a Network structure + * that contains the configuration information for the Network. + * buffer : pointer to a read buffer. + * len : buffer length. + * @retval length of data sent or SOCKERR code + */ +int w5x00_write(Network* n, unsigned char* buffer, int len, long time) +{ + if(getSn_SR(n->my_socket) == SOCK_ESTABLISHED) + return send(n->my_socket, buffer, len); + + return SOCK_ERROR; +} + +/* + * @brief disconnect function + * @param n : pointer to a Network structure + * that contains the configuration information for the Network. + */ +void w5x00_disconnect(Network* n) +{ + disconnect(n->my_socket); +} + +/* + * @brief connect network function + * @param n : pointer to a Network structure + * that contains the configuration information for the Network. + * ip : server iP. + * port : server port. + * @retval SOCKOK code or SOCKERR code + */ +int ConnectNetwork(Network* n, uint8_t* ip, uint16_t port) +{ + uint16_t myport = 12345; + + if(socket(n->my_socket, Sn_MR_TCP, myport, 0) != n->my_socket) + return SOCK_ERROR; + + if(connect(n->my_socket, ip, port) != SOCK_OK) + return SOCK_ERROR; + + return SOCK_OK; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.h new file mode 100755 index 00000000000..a7d2b30b4d4 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/MQTT/mqtt_interface.h @@ -0,0 +1,271 @@ +//***************************************************************************** +//! \file mqtt_interface.h +//! \brief Paho MQTT to WIZnet Chip interface Header file. +//! \details The process of porting an interface to use paho MQTT. +//! \version 1.0.0 +//! \date 2016/12/06 +//! \par Revision history +//! <2016/12/06> 1st Release +//! +//! \author Peter Bang & Justin Kim +//! \copyright +//! +//! Copyright (c) 2016, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/* MQTT subscribe Example.... W5500 + STM32F103(IoT board) +//Include: Board configuration +#include "IoTEVB.h" + +//Include: MCU peripheral Library +#include "stm32f10x_rcc.h" +#include "stm32f10x.h" + +//Include: W5500 iolibrary +#include "w5500.h" +#include "wizchip_conf.h" +#include "misc.h" + +//Include: Internet iolibrary +#include "MQTTClient.h" + +//Include: MCU Specific W5500 driver +#include "W5500HardwareDriver.h" + +//Include: Standard IO Library +#include + +//Socket number defines +#define TCP_SOCKET 0 + +//Receive Buffer Size define +#define BUFFER_SIZE 2048 + +//Global variables +unsigned char targetIP[4] = {}; // mqtt server IP +unsigned int targetPort = 1883; // mqtt server port +uint8_t mac_address[6] = {}; +wiz_NetInfo gWIZNETINFO = { .mac = {}, //user MAC + .ip = {}, //user IP + .sn = {}, + .gw = {}, + .dns = {}, + .dhcp = NETINFO_STATIC}; + +unsigned char tempBuffer[BUFFER_SIZE] = {}; + +struct opts_struct +{ + char* clientid; + int nodelimiter; + char* delimiter; + enum QoS qos; + char* username; + char* password; + char* host; + int port; + int showtopics; +} opts ={ (char*)"stdout-subscriber", 0, (char*)"\n", QOS0, NULL, NULL, targetIP, targetPort, 0 }; + + +// @brief messageArrived callback function +void messageArrived(MessageData* md) +{ + unsigned char testbuffer[100]; + MQTTMessage* message = md->message; + + if (opts.showtopics) + { + memcpy(testbuffer,(char*)message->payload,(int)message->payloadlen); + *(testbuffer + (int)message->payloadlen + 1) = "\n"; + printf("%s\r\n",testbuffer); + } + + if (opts.nodelimiter) + printf("%.*s", (int)message->payloadlen, (char*)message->payload); + else + printf("%.*s%s", (int)message->payloadlen, (char*)message->payload, opts.delimiter); +} + + +// @brief 1 millisecond Tick Timer setting +void NVIC_configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); + SysTick_Config(72000); + NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Highest priority + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +// @brief 1 millisecond Tick Timer Handler setting +void SysTick_Handler(void) +{ + MilliTimer_Handler(); +} + +int main(void) +{ + led_ctrl led1,led2; + int i; + int rc = 0; + unsigned char buf[100]; + //Usart initialization for Debug. + USART1Initialze(); + printf("USART initialized.\n\r"); + + I2C1Initialize(); + printf("I2C initialized.\n\r"); + + MACEEP_Read(mac_address,0xfa,6); + + printf("Mac address\n\r"); + for(i = 0 ; i < 6 ; i++) + { + printf("%02x ",mac_address[i]); + } + printf("\n\r"); + + //LED initialization. + led_initialize(); + led1 = led2 = ON; + + led2Ctrl(led2); + led1Ctrl(led1); + + //W5500 initialization. + W5500HardwareInitilize(); + printf("W5500 hardware interface initialized.\n\r"); + + W5500Initialze(); + printf("W5500 IC initialized.\n\r"); + + //Set network informations + wizchip_setnetinfo(&gWIZNETINFO); + + setSHAR(mac_address); + + print_network_information(); + + Network n; + MQTTClient c; + + NewNetwork(&n, TCP_SOCKET); + ConnectNetwork(&n, targetIP, targetPort); + MQTTClientInit(&c,&n,1000,buf,100,tempBuffer,2048); + + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.willFlag = 0; + data.MQTTVersion = 3; + data.clientID.cstring = opts.clientid; + data.username.cstring = opts.username; + data.password.cstring = opts.password; + + data.keepAliveInterval = 60; + data.cleansession = 1; + + rc = MQTTConnect(&c, &data); + printf("Connected %d\r\n", rc); + opts.showtopics = 1; + + printf("Subscribing to %s\r\n", "hello/wiznet"); + rc = MQTTSubscribe(&c, "hello/wiznet", opts.qos, messageArrived); + printf("Subscribed %d\r\n", rc); + + while(1) + { + MQTTYield(&c, data.keepAliveInterval); + } +} +*/ + +#ifndef __MQTT_INTERFACE_H_ +#define __MQTT_INTERFACE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * @brief MQTT MilliTimer handler + * @note MUST BE register to your system 1m Tick timer handler + */ +void MilliTimer_Handler(void); + +/* + * @brief Timer structure + */ +typedef struct Timer Timer; +struct Timer { + unsigned long systick_period; + unsigned long end_time; +}; + +/* + * @brief Network structure + */ +typedef struct Network Network; +struct Network +{ + int my_socket; + int (*mqttread) (Network*, unsigned char*, int, long); + int (*mqttwrite) (Network*, unsigned char*, int, long); + void (*disconnect) (Network*); +}; + +/* + * @brief Timer function + */ +void TimerInit(Timer*); +char TimerIsExpired(Timer*); +void TimerCountdownMS(Timer*, unsigned int); +void TimerCountdown(Timer*, unsigned int); +int TimerLeftMS(Timer*); + +/* + * @brief Network interface porting + */ +int w5x00_read(Network*, unsigned char*, int, long); +int w5x00_write(Network*, unsigned char*, int, long); +void w5x00_disconnect(Network*); +void NewNetwork(Network* n, int sn); +int ConnectNetwork(Network* n, uint8_t* ip, uint16_t port); + +#ifdef __cplusplus +} +#endif + +#endif //__MQTT_INTERFACE_H_ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp.c new file mode 100755 index 00000000000..b7050978d3b --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp.c @@ -0,0 +1,927 @@ +#include +#include +#include +#include +#include + +#include "socket.h" +#include "snmp.h" +#include "snmp_custom.h" + +/********************************************************************************************/ +/* SNMP : Functions declaration */ +/********************************************************************************************/ +// SNMP Parsing functions +int32_t findEntry(uint8_t *oid, int32_t len); +int32_t getOID(int32_t id, uint8_t *oid, uint8_t *len); +int32_t getValue( uint8_t *vptr, int32_t vlen); +int32_t getEntry(int32_t id, uint8_t *dataType, void *ptr, int32_t *len); +int32_t setEntry(int32_t id, void *val, int32_t vlen, uint8_t dataType, int32_t index); +int32_t makeTrapVariableBindings(dataEntryType *oid_data, void *ptr, uint32_t *len); + +int32_t parseLength(const uint8_t *msg, int32_t *len); +int32_t parseTLV(const uint8_t *msg, int32_t index, tlvStructType *tlv); +void insertRespLen(int32_t reqStart, int32_t respStart, int32_t size); +int32_t parseVarBind(int32_t reqType, int32_t index); +int32_t parseSequence(int32_t reqType, int32_t index); +int32_t parseSequenceOf(int32_t reqType); +int32_t parseRequest(); +int32_t parseCommunity(); +int32_t parseVersion(); +int32_t parseSNMPMessage(); + +// Debugging function +#ifdef _SNMP_DEBUG_ +void dumpCode(uint8_t* header, uint8_t* tail, uint8_t *buff, int32_t len); +#endif + +// Utils +void ipToByteArray(int8_t *ip, uint8_t *pDes); + +/********************************************************************************************/ +/* SNMP : Variable declaration */ +/********************************************************************************************/ +// SNMP message structures +struct messageStruct request_msg; +struct messageStruct response_msg; + +// SNMP Time counter +static time_t startTime = 0; +volatile uint32_t snmp_tick_10ms = 0; //volatile uint32_t snmp_tick_1ms = 0; + +// SNMP Sockets +static uint8_t SOCK_SNMP_AGENT; +static uint8_t SOCK_SNMP_TRAP; + +uint8_t packet_trap[MAX_TRAPMSG_LEN] = {0,}; +uint8_t errorStatus, errorIndex; + + +/********************************************************************************************/ +/* SNMP : Time handler */ +/********************************************************************************************/ +void currentUptime(void *ptr, uint8_t *len) +{ + time_t curTime = getSNMPTimeTick(); + + //*(uint32_t *)ptr = (uint32_t)(curTime - startTime) / 10; // calculation for 1ms tick + *(uint32_t *)ptr = (uint32_t)(curTime - startTime); // calculation for 10ms tick + *len = 4; +} + +void SNMP_time_handler(void) +{ + //snmp_tick_1ms++; + snmp_tick_10ms++; +} + +uint32_t getSNMPTimeTick(void) +{ + //return snmp_tick_1ms; + return snmp_tick_10ms; +} + + +/********************************************************************************************/ +/* SNMP : Library Part */ +/********************************************************************************************/ +/** + * @addtogroup snmp_module + * @{ + */ + +/** + * Initialize SNMP Daemon. + * This should be called just one time at first time + * + * @param none + * @return none + */ +void snmpd_init(uint8_t * managerIP, uint8_t * agentIP, uint8_t sn_agent, uint8_t sn_trap) +{ +#ifdef _SNMP_DEBUG_ + printf("\r\n - SNMP : Start SNMP Agent Daemon\r\n"); +#endif + SOCK_SNMP_AGENT = sn_agent; + SOCK_SNMP_TRAP = sn_trap; + + if((SOCK_SNMP_AGENT > _WIZCHIP_SOCK_NUM_) || (SOCK_SNMP_TRAP > _WIZCHIP_SOCK_NUM_)) return; + + startTime = getSNMPTimeTick(); // Start time (unit: 10ms) + initTable(); // Settings for OID entry values + + initial_Trap(managerIP, agentIP); + +/* + // Example Codes for SNMP Trap + { + dataEntryType enterprise_oid = {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00}, + SNMPDTYPE_OBJ_ID, 0x0a, {"\x2b\x06\x01\x04\x01\x81\x9b\x19\x10\x00"}, NULL, NULL}; + + dataEntryType trap_oid1 = {8, {0x2b, 6, 1, 4, 1, 0, 11, 0}, SNMPDTYPE_OCTET_STRING, 30, {""}, NULL, NULL}; + dataEntryType trap_oid2 = {8, {0x2b, 6, 1, 4, 1, 0, 12, 0}, SNMPDTYPE_INTEGER, 4, {""}, NULL, NULL}; + + strcpy((char *)trap_oid1.u.octetstring, "Alert!!!"); // String added + trap_oid2.u.intval = 123456; // Integer value added + + // Generic Trap: warmStart + snmp_sendTrap((void *)"192.168.0.214", (void *)"192.168.0.112", (void *)"public", enterprise_oid, SNMPTRAP_WARMSTART, 0, 0); + + // Enterprise-Specific Trap + snmp_sendTrap((void *)"192.168.0.214", (void *)"192.168.0.112", (void *)"public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2); + } +*/ +} + + +/** + * SNMP Process Handler. + * UDP Socket and SNMP Agent transaction handling. + * + * @param none + * @return none + */ + +int32_t snmpd_run(void) +{ + int32_t ret; + int32_t len = 0; + + uint8_t svr_addr[6]; + uint16_t svr_port; + + if(SOCK_SNMP_AGENT > _WIZCHIP_SOCK_NUM_) return -99; + + switch(getSn_SR(SOCK_SNMP_AGENT)) + { + case SOCK_UDP : + if ( (len = getSn_RX_RSR(SOCK_SNMP_AGENT)) > 0) + { + request_msg.len= recvfrom(SOCK_SNMP_AGENT, request_msg.buffer, len, svr_addr, &svr_port); + } + else + { + request_msg.len = 0; + } + + if (request_msg.len > 0) + { +#ifdef _SNMP_DEBUG_ + dumpCode((void *)"\r\n[Request]\r\n", (void *)"\r\n", request_msg.buffer, request_msg.len); +#endif + // Initialize + request_msg.index = 0; + response_msg.index = 0; + errorStatus = errorIndex = 0; + memset(response_msg.buffer, 0x00, MAX_SNMPMSG_LEN); + + // Received message parsing and send response process + if (parseSNMPMessage() != -1) + { + sendto(SOCK_SNMP_AGENT, response_msg.buffer, response_msg.index, svr_addr, svr_port); + } + +#ifdef _SNMP_DEBUG_ + dumpCode((void *)"\r\n[Response]\r\n", (void *)"\r\n", response_msg.buffer, response_msg.index); +#endif + } + break; + + case SOCK_CLOSED : + if((ret = socket(SOCK_SNMP_AGENT, Sn_MR_UDP, PORT_SNMP_AGENT, 0x00)) != SOCK_SNMP_AGENT) + return ret; +#ifdef _SNMP_DEBUG_ + printf(" - [%d] UDP Socket for SNMP Agent, port [%d]\r\n", SOCK_SNMP_AGENT, PORT_SNMP_AGENT); +#endif + break; + + default : + break; + } + + + return 1; +} + + +int32_t findEntry(uint8_t *oid, int32_t len) +{ + int32_t i; + + for (i = 0 ; i < maxData ; i++) + { + if (len == snmpData[i].oidlen) + { + if (!memcmp(snmpData[i].oid, oid, len)) return(i); + } + } + + return OID_NOT_FOUND; +} + + +int32_t getOID(int32_t id, uint8_t *oid, uint8_t *len) +{ + int32_t j; + + if (!((id >= 0) && (id < maxData))) return INVALID_ENTRY_ID; + + *len = snmpData[id].oidlen; + + for (j = 0 ; j < *len ; j++) + { + oid[j] = snmpData[id].oid[j]; + } + + return SNMP_SUCCESS; +} + + +int32_t getValue( uint8_t *vptr, int32_t vlen) +{ + int32_t index = 0; + int32_t value = 0; + + while (index < vlen) + { + if (index != 0) value <<= 8; + value |= vptr[index++]; + } + + return value; +} + + +int32_t getEntry(int32_t id, uint8_t *dataType, void *ptr, int32_t *len) +{ + uint8_t * ptr_8; + int32_t value; + + uint8_t * string; + int32_t j; + + if (!((id >= 0) && (id < maxData))) return INVALID_ENTRY_ID; + + *dataType = snmpData[id].dataType; + + switch(*dataType) + { + case SNMPDTYPE_OCTET_STRING : + case SNMPDTYPE_OBJ_ID : + { + string = ptr; + + if (snmpData[id].getfunction != NULL) + { + snmpData[id].getfunction( (void *)&snmpData[id].u.octetstring, &snmpData[id].dataLen ); + } + + if ( (*dataType)==SNMPDTYPE_OCTET_STRING ) + { + snmpData[id].dataLen = (uint8_t)strlen((char const*)&snmpData[id].u.octetstring); + } + + *len = snmpData[id].dataLen; + for (j = 0 ; j < *len ; j++) + { + string[j] = snmpData[id].u.octetstring[j]; + } + } + break; + + case SNMPDTYPE_INTEGER : + case SNMPDTYPE_TIME_TICKS : + case SNMPDTYPE_COUNTER : + case SNMPDTYPE_GAUGE : + { + if (snmpData[id].getfunction != NULL) + { + snmpData[id].getfunction( (void *)&snmpData[id].u.intval, &snmpData[id].dataLen ); + } + + if(snmpData[id].dataLen) *len = snmpData[id].dataLen; + else *len = sizeof(uint32_t); + + /* + // Original code (IAR, STM32) + // This code is not working in NXP+LPCXpresso (32-bit pointer operation error) + value = (int32_t *)ptr; + *value = HTONL(snmpData[id].u.intval); + */ + + ptr_8 = ptr; + //value = HTONL(snmpData[id].u.intval); // Endian convert when processing 32bit pointer operation + value = snmpData[id].u.intval; + + for (j = 0 ; j < *len ; j++) + { + ptr_8[j] = (uint8_t)((value >> ((*len-j-1)*8))); + } + } + break; + + default : + return INVALID_DATA_TYPE; + } + + return SNMP_SUCCESS; +} + + +int32_t setEntry(int32_t id, void *val, int32_t vlen, uint8_t dataType, int32_t index) +{ + + int32_t retStatus=OID_NOT_FOUND; + int32_t j; + + if (snmpData[id].dataType != dataType) + { + errorStatus = BAD_VALUE; + errorIndex = index; + return INVALID_DATA_TYPE; + } + + switch(snmpData[id].dataType) + { + case SNMPDTYPE_OCTET_STRING : + case SNMPDTYPE_OBJ_ID : + { + uint8_t *string = val; + for (j = 0 ; j < vlen ; j++) + { + snmpData[id].u.octetstring[j] = string[j]; + } + snmpData[id].dataLen = vlen; + } + retStatus = SNMP_SUCCESS; + break; + + case SNMPDTYPE_INTEGER : + case SNMPDTYPE_TIME_TICKS : + case SNMPDTYPE_COUNTER : + case SNMPDTYPE_GAUGE : + { + snmpData[id].u.intval = getValue( (uint8_t *)val, vlen); + snmpData[id].dataLen = vlen; + + if (snmpData[id].setfunction != NULL) + { + snmpData[id].setfunction(snmpData[id].u.intval); + } + + } + retStatus = SNMP_SUCCESS; + break; + + default : + retStatus = INVALID_DATA_TYPE; + break; + + } + + return retStatus; +} + + +int32_t parseLength(const uint8_t *msg, int32_t *len) +{ + int32_t i=1; + + if (msg[0] & 0x80) + { + int32_t tlen = (msg[0] & 0x7f) - 1; + *len = msg[i++]; + + while (tlen--) + { + *len <<= 8; + *len |= msg[i++]; + } + } + else + { + *len = msg[0]; + } + + return i; +} + + +int32_t parseTLV(const uint8_t *msg, int32_t index, tlvStructType *tlv) +{ + int32_t Llen = 0; + + tlv->start = index; + + Llen = parseLength((const uint8_t *)&msg[index+1], &tlv->len ); + + tlv->vstart = index + Llen + 1; + + switch (msg[index]) + { + case SNMPDTYPE_SEQUENCE: + case GET_REQUEST: + case GET_NEXT_REQUEST: + case SET_REQUEST: + tlv->nstart = tlv->vstart; + break; + default: + tlv->nstart = tlv->vstart + tlv->len; + break; + } + + return 0; +} + + +void insertRespLen(int32_t reqStart, int32_t respStart, int32_t size) +{ + int32_t indexStart, lenLength; + uint32_t mask = 0xff; + int32_t shift = 0; + + if (request_msg.buffer[reqStart+1] & 0x80) + { + lenLength = request_msg.buffer[reqStart+1] & 0x7f; + indexStart = respStart+2; + + while (lenLength--) + { + response_msg.buffer[indexStart+lenLength] = + (uint8_t)((size & mask) >> shift); + shift+=8; + mask <<= shift; + } + } + else + { + response_msg.buffer[respStart+1] = (uint8_t)(size & 0xff); + } +} + +int32_t parseVarBind(int32_t reqType, int32_t index) +{ + int32_t seglen = 0, id; + tlvStructType name, value; + int32_t size = 0; + + //extern const int32_t maxData; + + parseTLV(request_msg.buffer, request_msg.index, &name); + + if ( request_msg.buffer[name.start] != SNMPDTYPE_OBJ_ID ) return -1; + + id = findEntry(&request_msg.buffer[name.vstart], name.len); + + if ((reqType == GET_REQUEST) || (reqType == SET_REQUEST)) + { + seglen = name.nstart - name.start; + COPY_SEGMENT(name); + size = seglen; + } + else if (reqType == GET_NEXT_REQUEST) + { + response_msg.buffer[response_msg.index] = request_msg.buffer[name.start]; + + if (++id >= maxData) + { + id = OID_NOT_FOUND; + seglen = name.nstart - name.start; + COPY_SEGMENT(name); + size = seglen; + } + else + { + request_msg.index += name.nstart - name.start; + + getOID(id, &response_msg.buffer[response_msg.index+2], &response_msg.buffer[response_msg.index+1]); + + seglen = response_msg.buffer[response_msg.index+1]+2; + response_msg.index += seglen ; + size = seglen; + } + } + + parseTLV(request_msg.buffer, request_msg.index, &value); + + if (id != OID_NOT_FOUND) + { + uint8_t dataType; + int32_t len; + + if ((reqType == GET_REQUEST) || (reqType == GET_NEXT_REQUEST)) + { + getEntry(id, &dataType, &response_msg.buffer[response_msg.index+2], &len); + + response_msg.buffer[response_msg.index] = dataType; + response_msg.buffer[response_msg.index+1] = len; + seglen = (2 + len); + response_msg.index += seglen; + + request_msg.index += (value.nstart - value.start); + + } + else if (reqType == SET_REQUEST) + { + setEntry(id, &request_msg.buffer[value.vstart], value.len, request_msg.buffer[value.start], index); + seglen = value.nstart - value.start; + COPY_SEGMENT(value); + } + } + else + { + seglen = value.nstart - value.start; + COPY_SEGMENT(value); + + errorIndex = index; + errorStatus = NO_SUCH_NAME; + } + + size += seglen; + + return size; +} + + +int32_t parseSequence(int32_t reqType, int32_t index) +{ + int32_t seglen; + tlvStructType seq; + int32_t size = 0, respLoc; + + parseTLV(request_msg.buffer, request_msg.index, &seq); + + if ( request_msg.buffer[seq.start] != SNMPDTYPE_SEQUENCE ) return -1; + + seglen = seq.vstart - seq.start; + respLoc = response_msg.index; + COPY_SEGMENT(seq); + + size = parseVarBind( reqType, index ); + insertRespLen(seq.start, respLoc, size); + size += seglen; + + return size; +} + + +int32_t parseSequenceOf(int32_t reqType) +{ + int32_t seglen; + tlvStructType seqof; + int32_t size = 0, respLoc; + int32_t index = 0; + + parseTLV(request_msg.buffer, request_msg.index, &seqof); + + if ( request_msg.buffer[seqof.start] != SNMPDTYPE_SEQUENCE_OF ) return -1; + + seglen = seqof.vstart - seqof.start; + respLoc = response_msg.index; + COPY_SEGMENT(seqof); + + while (request_msg.index < request_msg.len) + { + size += parseSequence( reqType, index++ ); + } + + insertRespLen(seqof.start, respLoc, size); + + return size; +} + + +int32_t parseRequest() +{ + int32_t ret, seglen; + tlvStructType snmpreq, requestid, errStatus, errIndex; + int32_t size = 0, respLoc, reqType; + + parseTLV(request_msg.buffer, request_msg.index, &snmpreq); + + reqType = request_msg.buffer[snmpreq.start]; + + if ( !VALID_REQUEST(reqType) ) return -1; + + seglen = snmpreq.vstart - snmpreq.start; + respLoc = snmpreq.start; + size += seglen; + COPY_SEGMENT(snmpreq); + + response_msg.buffer[snmpreq.start] = GET_RESPONSE; + + parseTLV(request_msg.buffer, request_msg.index, &requestid); + seglen = requestid.nstart - requestid.start; + size += seglen; + COPY_SEGMENT(requestid); + + parseTLV(request_msg.buffer, request_msg.index, &errStatus); + seglen = errStatus.nstart - errStatus.start; + size += seglen; + COPY_SEGMENT(errStatus); + + parseTLV(request_msg.buffer, request_msg.index, &errIndex); + seglen = errIndex.nstart - errIndex.start; + size += seglen; + COPY_SEGMENT(errIndex); + + ret = parseSequenceOf(reqType); + if (ret == -1) return -1; + else size += ret; + + insertRespLen(snmpreq.start, respLoc, size); + + if (errorStatus) + { + response_msg.buffer[errStatus.vstart] = errorStatus; + response_msg.buffer[errIndex.vstart] = errorIndex + 1; + } + + return size; +} + + +int32_t parseCommunity() +{ + int32_t seglen; + tlvStructType community; + int32_t size=0; + + parseTLV(request_msg.buffer, request_msg.index, &community); + + if (!((request_msg.buffer[community.start] == SNMPDTYPE_OCTET_STRING) && (community.len == COMMUNITY_SIZE))) + { + return -1; + } + + if (!memcmp(&request_msg.buffer[community.vstart], (int8_t *)COMMUNITY, COMMUNITY_SIZE)) + { + seglen = community.nstart - community.start; + size += seglen; + COPY_SEGMENT(community); + + size += parseRequest(); + } + else + { + return -1; + } + + return size; +} + + +int32_t parseVersion() +{ + int32_t size = 0, seglen; + tlvStructType tlv; + + size = parseTLV(request_msg.buffer, request_msg.index, &tlv); + + if (!((request_msg.buffer[tlv.start] == SNMPDTYPE_INTEGER) && (request_msg.buffer[tlv.vstart] == SNMP_V1))) + return -1; + + seglen = tlv.nstart - tlv.start; + size += seglen; + COPY_SEGMENT(tlv); + size = parseCommunity(); + + if (size == -1) return size; + else return (size + seglen); +} + + +int32_t parseSNMPMessage() +{ + int32_t size = 0, seglen, respLoc; + tlvStructType tlv; + + parseTLV(request_msg.buffer, request_msg.index, &tlv); + + if (request_msg.buffer[tlv.start] != SNMPDTYPE_SEQUENCE_OF) return -1; + + seglen = tlv.vstart - tlv.start; + respLoc = tlv.start; + COPY_SEGMENT(tlv); + + size = parseVersion(); + + if (size == -1) return -1; + else size += seglen; + + insertRespLen(tlv.start, respLoc, size); + + return 0; +} + +void ipToByteArray(int8_t *ip, uint8_t *pDes) +{ + uint32_t i, ip1=0, ip2=0, ip3=0, ip4=0; + int8_t buff[32]; + uint32_t len = (uint32_t)strlen((char const*)ip); + strcpy((char *)buff, (char const*)ip); + + for (i=0; ioidlen; + + for (j = 0 ; j < oid_data->oidlen ; j++) + { + ((uint8_t*)ptr)[j+4] = oid_data->oid[j]; + } + + switch(oid_data->dataType) + { + case SNMPDTYPE_OCTET_STRING : + case SNMPDTYPE_OBJ_ID : + { + uint8_t *string = &((uint8_t*)ptr)[4+oid_data->oidlen+2]; + + if ( oid_data->dataType==SNMPDTYPE_OCTET_STRING ) + { + oid_data->dataLen = (uint8_t)strlen((char const*)&oid_data->u.octetstring); + } + for (j = 0 ; j < oid_data->dataLen ; j++) + { + string[j] = oid_data->u.octetstring[j]; + } + + ((uint8_t*)ptr)[4+oid_data->oidlen] = oid_data->dataType; + ((uint8_t*)ptr)[4+oid_data->oidlen+1] = oid_data->dataLen; + ((uint8_t*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen; + *len = 4 + oid_data->oidlen + 2 + oid_data->dataLen; + } + break; + + case SNMPDTYPE_INTEGER : + case SNMPDTYPE_TIME_TICKS : + case SNMPDTYPE_COUNTER : + case SNMPDTYPE_GAUGE : + { + oid_data->dataLen = 4; + + *(int32_t*)(&((uint8_t*)ptr)[4+oid_data->oidlen+2]) = HTONL(oid_data->u.intval); + + ((uint8_t*)ptr)[4+oid_data->oidlen] = oid_data->dataType; + ((uint8_t*)ptr)[4+oid_data->oidlen+1] = oid_data->dataLen; + ((uint8_t*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen; + *len = 4 + oid_data->oidlen + 2 + oid_data->dataLen; + } + break; + + default : + return INVALID_DATA_TYPE; + } + + return SNMP_SUCCESS; +} + + +int32_t snmp_sendTrap(uint8_t * managerIP, uint8_t * agentIP, int8_t* community, dataEntryType enterprise_oid, uint32_t genericTrap, uint32_t specificTrap, uint32_t va_count, ...) +{ + uint32_t i; + int32_t packet_index = 0; + int32_t packet_buff1 = 0; + int32_t packet_buff2 = 0; + int32_t packet_buff3 = 0; + + va_list ap; + uint32_t length_var_bindings = 0; + uint32_t length_buff = 0; + + //SNMP Trap packet generation + packet_trap[packet_index++] = 0x30; // ASN.1 Header + + packet_trap[packet_index] = 0xff; // pdu_length, temp + packet_buff1 = packet_index++; + + packet_trap[packet_index++] = 0x02; // Version + packet_trap[packet_index++] = 0x01; + packet_trap[packet_index++] = 0x00; + + packet_trap[packet_index++] = 0x04; // Community + packet_trap[packet_index++] = (uint8_t)strlen((char const*)community); + memcpy(&(packet_trap[packet_index]), community, strlen((char const*)community)); + + packet_index = packet_index + (uint8_t)strlen((char const*)community); + + packet_trap[packet_index++] = 0xa4; // trap + packet_trap[packet_index] = 0xff; // length, temp + packet_buff2 = packet_index++; + + packet_trap[packet_index++] = 0x06; // enterprise_oid + packet_trap[packet_index++] = enterprise_oid.oidlen; + for (i=0; i> 24) & 0x000000ff) | \ + (((x) >> 8) & 0x0000ff00) | \ + (((x) << 8) & 0x00ff0000) | \ + (((x) << 24) & 0xff000000)) +#endif + +typedef struct { + uint8_t oidlen; + uint8_t oid[MAX_OID]; + uint8_t dataType; + uint8_t dataLen; + union { + uint8_t octetstring[MAX_STRING]; + uint32_t intval; + } u; + void (*getfunction)(void *, uint8_t *); + void (*setfunction)(int32_t); +} dataEntryType; + +struct messageStruct { + uint8_t buffer[MAX_SNMPMSG_LEN]; + int32_t len; + int32_t index; +}; + +typedef struct { + int32_t start; /* Absolute Index of the TLV */ + int32_t len; /* The L value of the TLV */ + int32_t vstart; /* Absolute Index of this TLV's Value */ + int32_t nstart; /* Absolute Index of the next TLV */ +} tlvStructType; + + +/********************************************************************************************/ +/* SNMP : Functions */ +/********************************************************************************************/ +// SNMP Main functions +void snmpd_init(uint8_t * managerIP, uint8_t * agentIP, uint8_t sn_agent, uint8_t sn_trap); +int32_t snmpd_run(void); +int32_t snmp_sendTrap(uint8_t * managerIP, uint8_t * agentIP, int8_t* community, dataEntryType enterprise_oid, uint32_t genericTrap, uint32_t specificTrap, uint32_t va_count, ...); + +// SNMP Time handler functions +void SNMP_time_handler(void); +uint32_t getSNMPTimeTick(void); +void currentUptime(void *ptr, uint8_t *len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.c new file mode 100755 index 00000000000..68590c70fb9 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.c @@ -0,0 +1,147 @@ + +/******************************************************************************************** + * SNMP : User Customization Part + * - OID Registration + * - User defined functions for OID related + * + Integer value, String + * + I/O control / Chip registers + * + Network Informations + * + Etc. + * + *********************************************************************************************/ +#include "snmp_custom.h" + +#ifdef _USE_WIZNET_W5500_EVB_ + #include "board.h" +#endif + +dataEntryType snmpData[] = +{ + // System MIB + // SysDescr Entry + {8, {0x2b, 6, 1, 2, 1, 1, 1, 0}, + SNMPDTYPE_OCTET_STRING, 30, {"WIZnet Embedded SNMP Agent"}, + NULL, NULL}, + + // SysObjectID Entry + {8, {0x2b, 6, 1, 2, 1, 1, 2, 0}, + SNMPDTYPE_OBJ_ID, 8, {"\x2b\x06\x01\x02\x01\x01\x02\x00"}, + NULL, NULL}, + + // SysUptime Entry + {8, {0x2b, 6, 1, 2, 1, 1, 3, 0}, + SNMPDTYPE_TIME_TICKS, 0, {""}, + currentUptime, NULL}, + + // sysContact Entry + {8, {0x2b, 6, 1, 2, 1, 1, 4, 0}, + SNMPDTYPE_OCTET_STRING, 30, {"http://www.wizwiki.net/forum"}, + NULL, NULL}, + + // sysName Entry + {8, {0x2b, 6, 1, 2, 1, 1, 5, 0}, + SNMPDTYPE_OCTET_STRING, 30, {"http://www.wiznet.co.kr"}, + NULL, NULL}, + + // Location Entry + {8, {0x2b, 6, 1, 2, 1, 1, 6, 0}, + SNMPDTYPE_OCTET_STRING, 30, {"4F Humax Village"}, + NULL, NULL}, + + // SysServices + {8, {0x2b, 6, 1, 2, 1, 1, 7, 0}, + SNMPDTYPE_INTEGER, 4, {""}, + NULL, NULL}, + +#ifdef _USE_WIZNET_W5500_EVB_ + // Get the WIZnet W5500-EVB LED Status + {8, {0x2b, 6, 1, 4, 1, 6, 1, 0}, + SNMPDTYPE_OCTET_STRING, 40, {""}, + get_LEDStatus_all, NULL}, + + // Set the LED_R (RGB LED) + {8, {0x2b, 6, 1, 4, 1, 6, 1, 1}, + SNMPDTYPE_INTEGER, 4, {""}, + NULL, set_LEDStatus_R}, + + // Set the LED_G (RGB LED) + {8, {0x2b, 6, 1, 4, 1, 6, 1, 2}, + SNMPDTYPE_INTEGER, 4, {""}, + NULL, set_LEDStatus_G}, + + // Set the LED_B (RGB LED) + {8, {0x2b, 6, 1, 4, 1, 6, 1, 3}, + SNMPDTYPE_INTEGER, 4, {""}, + NULL, set_LEDStatus_B}, +#endif + + // OID Test #1 (long-length OID example, 19865) + {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00}, + SNMPDTYPE_OCTET_STRING, 30, {"long-length OID Test #1"}, + NULL, NULL}, + + // OID Test #2 (long-length OID example, 22210) + {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xad, 0x42, 0x01, 0x00}, + SNMPDTYPE_OCTET_STRING, 35, {"long-length OID Test #2"}, + NULL, NULL}, + + // OID Test #2: SysObjectID Entry + {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xad, 0x42, 0x02, 0x00}, + SNMPDTYPE_OBJ_ID, 0x0a, {"\x2b\x06\x01\x04\x01\x81\xad\x42\x02\x00"}, + NULL, NULL}, +}; + +const int32_t maxData = (sizeof(snmpData) / sizeof(dataEntryType)); + +void initTable() +{ + // Example integer value for [OID 1.3.6.1.2.1.1.7.0] + snmpData[6].u.intval = -5; + +} + + +// W5500-EVB: LED Control /////////////////////////////////////////////////////////////////////////// +#ifdef _USE_WIZNET_W5500_EVB_ +void get_LEDStatus_all(void *ptr, uint8_t *len) +{ + uint8_t led_status[3] = {0, }; + + led_status[LED_R] = (uint8_t)Board_LED_Test(LED_R); + led_status[LED_G] = (uint8_t)Board_LED_Test(LED_G); + led_status[LED_B] = (uint8_t)Board_LED_Test(LED_B); + + *len = sprintf((char *)ptr, "LED R [%s] / G [%s] / B [%s]", led_status[LED_R]?"On":"Off", led_status[LED_G]?"On":"Off", led_status[LED_B]?"On":"Off"); +} + +void set_LEDStatus_R(int32_t val) +{ + if(val == 0) Board_LED_Set(LED_R, false); + else Board_LED_Set(LED_R, true); +} + +void set_LEDStatus_G(int32_t val) +{ + if(val == 0) Board_LED_Set(LED_G, false); + else Board_LED_Set(LED_G, true); +} + +void set_LEDStatus_B(int32_t val) +{ + if(val == 0) Board_LED_Set(LED_B, false); + else Board_LED_Set(LED_B, true); +} +#endif +///////////////////////////////////////////////////////////////////////////////////////////////////// + +void initial_Trap(uint8_t * managerIP, uint8_t * agentIP) +{ + // SNMP Trap: WarmStart(1) Trap + { + dataEntryType enterprise_oid = {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00}, + SNMPDTYPE_OBJ_ID, 0x0a, {"\x2b\x06\x01\x04\x01\x81\x9b\x19\x10\x00"}, NULL, NULL}; + // Generic Trap: warmStart COMMUNITY + snmp_sendTrap(managerIP, agentIP, (void *)COMMUNITY, enterprise_oid, SNMPTRAP_WARMSTART, 0, 0); + } + +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.h new file mode 100755 index 00000000000..c4afa30e28a --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/snmp_custom.h @@ -0,0 +1,41 @@ +#ifndef _SNMP_CUSTOM_H_ +#define _SNMP_CUSTOM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#include "snmp.h" + +extern dataEntryType snmpData[]; +extern const int32_t maxData; + +// Define for using W5500-EVB: H/W Dependency (e.g., LEDs...) +//#define _USE_WIZNET_W5500_EVB_ + +#define COMMUNITY "public\0" +#define COMMUNITY_SIZE (strlen(COMMUNITY)) + +/* Predefined function: Response value control */ +void initTable(); + +/* User defined functions: LED control examples */ +#ifdef _USE_WIZNET_W5500_EVB_ + void get_LEDStatus_all(void *ptr, uint8_t *len); + void set_LEDStatus_R(int32_t val); + void set_LEDStatus_G(int32_t val); + void set_LEDStatus_B(int32_t val); +#endif +/* SNMP Trap: warmStart(1) */ +void initial_Trap(uint8_t * managerIP, uint8_t * agentIP); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/OID_Converter/Readme.txt b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/OID_Converter/Readme.txt new file mode 100755 index 00000000000..4476586157b --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/OID_Converter/Readme.txt @@ -0,0 +1,45 @@ +============================================================ + +============================================================ + ++ Example OID for convert + 1.3.6.1.4.1.19865.1.0 + +(1) Convert Usage + CMD>>oid 1.3.6.1.4.1.19865.1.0 + => 06 0A 2B 06 01 04 01 81 9B 19 01 00 + + >> TLV(tag-length-value) Example OID + (06) Tag + (0A) Length + [2B] 1(iso).3(identified-organization) (in ASN.1 BER encoding, i.e. 1*40+3 = 0x2b) + [06] 6(dod) + [01] 1(internet) + [04] 4(private) + [01] 1(enterprise) + [81 9B 19] 19865(Vendor-Specific) + ... + +(2) Add the entry to OID table in source code (DataEntryType, put the converted value to array) + {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00}, + SNMPDTYPE_OCTET_STRING, 30, {"long-length OID Test"}, + NULL, NULL}, + +============================================================ +OID Converter: OID encoder/decoder +v1.3 - Matthias Gaertner 1999/2001 - Freeware +============================================================ + +The OID converter is a handy little tool to convert ASN.1 OIDs from readable dotted decimal notation to binary hexadecimal Distinguished Encoding Rules (DER) representation and vice versa. +If you're into x.509 certificates, this may be useful to you, too. + +Usage: + OID [-c|-C] [-o] {-i|1.2.3.4} + converts dotted form to ASCII HEX DER output. + OID -x [-o] {-i|hex-digits} + decodes ASCII HEX DER and gives dotted form. + +If you need more information, please refer to Matthias Gaertner's page, +http://www.rtner.de/software/oid.html + +=============================================================================================== \ No newline at end of file diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/net-snmp-5.7(win32-bin)/snmptrapd.conf b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/net-snmp-5.7(win32-bin)/snmptrapd.conf new file mode 100755 index 00000000000..494e4ec7d4f --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNMP/tools/net-snmp-5.7(win32-bin)/snmptrapd.conf @@ -0,0 +1,33 @@ +# +# net-snmp (or ucd-snmp) persistent data file. +# +############################################################################ +# STOP STOP STOP STOP STOP STOP STOP STOP STOP +# +# **** DO NOT EDIT THIS FILE **** +# +# STOP STOP STOP STOP STOP STOP STOP STOP STOP +############################################################################ +# +# DO NOT STORE CONFIGURATION ENTRIES HERE. +# Please save normal configuration tokens for snmptrapd in SNMPCONFPATH/snmptrapd.conf. +# Only "createUser" tokens should be placed here by snmptrapd administrators. +# (Did I mention: do not edit this file?) +# + + +authCommunity log,execute,net public + + + + + + + + + + + + +engineBoots 1 +oldEngineID 0x80001f88803d6f00001ba7934e00000000 diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNTP/sntp.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNTP/sntp.c new file mode 100755 index 00000000000..5b9c4633329 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/SNTP/sntp.c @@ -0,0 +1,450 @@ +/* + * sntp.c + * + * Created on: 2014. 12. 15. + * Author: Administrator + */ + + +#include + +#include "sntp.h" +#include "socket.h" + +ntpformat NTPformat; +datetime Nowdatetime; +uint8_t ntpmessage[48]; +uint8_t *data_buf; +uint8_t NTP_SOCKET; +uint8_t time_zone; +uint16_t ntp_retry_cnt=0; //counting the ntp retry number + +/* +00)UTC-12:00 Baker Island, Howland Island (both uninhabited) +01) UTC-11:00 American Samoa, Samoa +02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii) +03) UTC-09:30 Marquesas Islands +04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska) +05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California) +06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state)) +07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta) +08) UTC-07:00 Mexico (Chihuahua), United States (Colorado) +09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras +10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas) +11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru +12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec) +13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.) +14) UTC-04:30 Venezuela +15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay, +16) UTC-04:00 Puerto Rico, Trinidad and Tobago +17) UTC-03:30 Canada (Newfoundland) +18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay +19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands +20) UTC-01:00 Portugal (Azores), Cape Verde +21) UTC±00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira) +22) UTC±00:00 Spain (Canary Islands), Morocco, United Kingdom +23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina, +24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo, +25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland +26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia, +27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine +28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia, +29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen +30) UTC+03:30 (Summer)Iran +31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates +32) UTC+04:30 Afghanistan +33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan +34) UTC+05:30 India, Sri Lanka +35) UTC+05:45 Nepal +36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast) +37) UTC+06:30 Cocos Islands, Myanmar +38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam +39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia +40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan +41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia)) +42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria) +43) UTC+10:30 Lord Howe Island +44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands +45) UTC+11:30 Norfolk Island +46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand +47) UTC+12:45 (Summer)New Zealand +48) UTC+13:00 Tonga +49) UTC+14:00 Kiribati (Line Islands) +*/ +void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx) +{ + tstamp seconds = 0; + uint8_t i=0; + for (i = 0; i < 4; i++) + { + seconds = (seconds << 8) | buf[idx + i]; + } + switch (time_zone) + { + case 0: + seconds -= 12*3600; + break; + case 1: + seconds -= 11*3600; + break; + case 2: + seconds -= 10*3600; + break; + case 3: + seconds -= (9*3600+30*60); + break; + case 4: + seconds -= 9*3600; + break; + case 5: + case 6: + seconds -= 8*3600; + break; + case 7: + case 8: + seconds -= 7*3600; + break; + case 9: + case 10: + seconds -= 6*3600; + break; + case 11: + case 12: + case 13: + seconds -= 5*3600; + break; + case 14: + seconds -= (4*3600+30*60); + break; + case 15: + case 16: + seconds -= 4*3600; + break; + case 17: + seconds -= (3*3600+30*60); + break; + case 18: + seconds -= 3*3600; + break; + case 19: + seconds -= 2*3600; + break; + case 20: + seconds -= 1*3600; + break; + case 21: //�? + case 22: + break; + case 23: + case 24: + case 25: + seconds += 1*3600; + break; + case 26: + case 27: + seconds += 2*3600; + break; + case 28: + case 29: + seconds += 3*3600; + break; + case 30: + seconds += (3*3600+30*60); + break; + case 31: + seconds += 4*3600; + break; + case 32: + seconds += (4*3600+30*60); + break; + case 33: + seconds += 5*3600; + break; + case 34: + seconds += (5*3600+30*60); + break; + case 35: + seconds += (5*3600+45*60); + break; + case 36: + seconds += 6*3600; + break; + case 37: + seconds += (6*3600+30*60); + break; + case 38: + seconds += 7*3600; + break; + case 39: + seconds += 8*3600; + break; + case 40: + seconds += 9*3600; + break; + case 41: + seconds += (9*3600+30*60); + break; + case 42: + seconds += 10*3600; + break; + case 43: + seconds += (10*3600+30*60); + break; + case 44: + seconds += 11*3600; + break; + case 45: + seconds += (11*3600+30*60); + break; + case 46: + seconds += 12*3600; + break; + case 47: + seconds += (12*3600+45*60); + break; + case 48: + seconds += 13*3600; + break; + case 49: + seconds += 14*3600; + break; + + } + + //calculation for date + calcdatetime(seconds); +} + +void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf) +{ + NTP_SOCKET = s; + + NTPformat.dstaddr[0] = ntp_server[0]; + NTPformat.dstaddr[1] = ntp_server[1]; + NTPformat.dstaddr[2] = ntp_server[2]; + NTPformat.dstaddr[3] = ntp_server[3]; + + time_zone = tz; + + data_buf = buf; + + uint8_t Flag; + NTPformat.leap = 0; /* leap indicator */ + NTPformat.version = 4; /* version number */ + NTPformat.mode = 3; /* mode */ + NTPformat.stratum = 0; /* stratum */ + NTPformat.poll = 0; /* poll interval */ + NTPformat.precision = 0; /* precision */ + NTPformat.rootdelay = 0; /* root delay */ + NTPformat.rootdisp = 0; /* root dispersion */ + NTPformat.refid = 0; /* reference ID */ + NTPformat.reftime = 0; /* reference time */ + NTPformat.org = 0; /* origin timestamp */ + NTPformat.rec = 0; /* receive timestamp */ + NTPformat.xmt = 1; /* transmit timestamp */ + + Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag + memcpy(ntpmessage,(void const*)(&Flag),1); +} + +int8_t SNTP_run(datetime *time) +{ + uint16_t RSR_len; + uint32_t destip = 0; + uint16_t destport; + uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40 + + switch(getSn_SR(NTP_SOCKET)) + { + case SOCK_UDP: + if ((RSR_len = getSn_RX_RSR(NTP_SOCKET)) > 0) + { + if (RSR_len > MAX_SNTP_BUF_SIZE) RSR_len = MAX_SNTP_BUF_SIZE; // if Rx data size is lager than TX_RX_MAX_BUF_SIZE + recvfrom(NTP_SOCKET, data_buf, RSR_len, (uint8_t *)&destip, &destport); + + get_seconds_from_ntp_server(data_buf,startindex); + time->yy = Nowdatetime.yy; + time->mo = Nowdatetime.mo; + time->dd = Nowdatetime.dd; + time->hh = Nowdatetime.hh; + time->mm = Nowdatetime.mm; + time->ss = Nowdatetime.ss; + + ntp_retry_cnt=0; + close(NTP_SOCKET); + + return 1; + } + + if(ntp_retry_cnt<0xFFFF) + { + if(ntp_retry_cnt==0)//first send request, no need to wait + { + sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port); + ntp_retry_cnt++; + } + else // send request again? it should wait for a while + { + if((ntp_retry_cnt % 0xFFF) == 0) //wait time + { + sendto(NTP_SOCKET,ntpmessage,sizeof(ntpmessage),NTPformat.dstaddr,ntp_port); +#ifdef _SNTP_DEBUG_ + printf("ntp retry: %d\r\n", ntp_retry_cnt); +#endif + ntp_retry_cnt++; + } + } + } + else //ntp retry fail + { + ntp_retry_cnt=0; +#ifdef _SNTP_DEBUG_ + printf("ntp retry failed!\r\n"); +#endif + close(NTP_SOCKET); + } + break; + case SOCK_CLOSED: + socket(NTP_SOCKET,Sn_MR_UDP,ntp_port,0); + break; + } + // Return value + // 0 - failed / 1 - success + return 0; +} + +void calcdatetime(tstamp seconds) +{ + uint8_t yf=0; + tstamp n=0,d=0,total_d=0,rz=0; + uint16_t y=0,r=0,yr=0; + signed long long yd=0; + + n = seconds; + total_d = seconds/(SECS_PERDAY); + d=0; + uint32_t p_year_total_sec=SECS_PERDAY*365; + uint32_t r_year_total_sec=SECS_PERDAY*366; + while(n>=p_year_total_sec) + { + if((EPOCH+r)%400==0 || ((EPOCH+r)%100!=0 && (EPOCH+r)%4==0)) + { + n = n -(r_year_total_sec); + d = d + 366; + } + else + { + n = n - (p_year_total_sec); + d = d + 365; + } + r+=1; + y+=1; + + } + + y += EPOCH; + + Nowdatetime.yy = y; + + yd=0; + yd = total_d - d; + + yf=1; + while(yd>=28) + { + + if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12) + { + yd -= 31; + if(yd<0)break; + rz += 31; + } + + if (yf==2) + { + if (y%400==0 || (y%100!=0 && y%4==0)) + { + yd -= 29; + if(yd<0)break; + rz += 29; + } + else + { + yd -= 28; + if(yd<0)break; + rz += 28; + } + } + if(yf==4 || yf==6 || yf==9 || yf==11 ) + { + yd -= 30; + if(yd<0)break; + rz += 30; + } + yf += 1; + + } + Nowdatetime.mo=yf; + yr = total_d-d-rz; + + yr += 1; + + Nowdatetime.dd=yr; + + //calculation for time + seconds = seconds%SECS_PERDAY; + Nowdatetime.hh = seconds/3600; + Nowdatetime.mm = (seconds%3600)/60; + Nowdatetime.ss = (seconds%3600)%60; + +} + +tstamp changedatetime_to_seconds(void) +{ + tstamp seconds=0; + uint32_t total_day=0; + uint16_t i=0,run_year_cnt=0,l=0; + + l = Nowdatetime.yy;//low + + + for(i=EPOCH;i + +/* + * @brief Define it for Debug & Monitor DNS processing. + * @note If defined, it dependens on + */ +//#define _SNTP_DEBUG_ + +#define MAX_SNTP_BUF_SIZE sizeof(ntpformat) ///< maximum size of DNS buffer. */ + +/* for ntpclient */ +typedef signed char s_char; +typedef unsigned long long tstamp; +typedef unsigned int tdist; + +typedef struct _ntpformat +{ + + uint8_t dstaddr[4]; /* destination (local) address */ + char version; /* version number */ + char leap; /* leap indicator */ + char mode; /* mode */ + char stratum; /* stratum */ + char poll; /* poll interval */ + s_char precision; /* precision */ + tdist rootdelay; /* root delay */ + tdist rootdisp; /* root dispersion */ + char refid; /* reference ID */ + tstamp reftime; /* reference time */ + tstamp org; /* origin timestamp */ + tstamp rec; /* receive timestamp */ + tstamp xmt; /* transmit timestamp */ + + +} ntpformat; + +typedef struct _datetime +{ + uint16_t yy; + uint8_t mo; + uint8_t dd; + uint8_t hh; + uint8_t mm; + uint8_t ss; +} datetime; + +#define ntp_port 123 //ntp server port number +#define SECS_PERDAY 86400UL // seconds in a day = 60*60*24 +#define UTC_ADJ_HRS 9 // SEOUL : GMT+9 +#define EPOCH 1900 // NTP start year + +void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx); +void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf); +int8_t SNTP_run(datetime *time); +tstamp changedatetime_to_seconds(void); +void calcdatetime(tstamp seconds); + +#ifdef __cplusplus +} +#endif + +#endif /* SNTP_H_ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.c new file mode 100755 index 00000000000..77b0992a0d6 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include "netutil.h" + +/** + * Convert a 32bit Address into a Dotted Decimal Format string. + * + * @param addr 32bit address. + * @return Dotted Decimal Format string. + */ +int8_t* inet_ntoa(uint32_t addr) +{ + static int8_t addr_str[16]; + memset(addr_str,0,16); + sprintf((char*)addr_str,"%d.%d.%d.%d",(int32_t)(addr>>24 & 0xFF),(int32_t)(addr>>16 & 0xFF),(int32_t)(addr>>8 & 0xFF),(int32_t)(addr & 0xFF)); + return addr_str; +} + +/** + * Convert a 32bit Address into a Dotted Decimal Format string. + * This is differ from inet_ntoa in fixed length. + * + * @param addr 32bit address. + * @return Dotted Decimal Format string. + */ +int8_t* inet_ntoa_pad(uint32_t addr) +{ + static int8_t addr_str[16]; + memset(addr_str,0,16); + sprintf((char*)addr_str,"%03d.%03d.%03d.%03d",(int32_t)(addr>>24 & 0xFF),(int32_t)(addr>>16 & 0xFF),(int32_t)(addr>>8 & 0xFF),(int32_t)(addr & 0xFF)); + return addr_str; +} + +/** + * Converts a string containing an (Ipv4) Internet Protocol decimal dotted address into a 32bit address. + * + * @param addr Dotted Decimal Format string. + * @return 32bit address. + */ +uint32_t inet_addr(uint8_t* addr) +{ + int8_t i; + uint32_t inetaddr = 0; + int8_t taddr[30]; + int8_t * nexttok; + int32_t num; + strcpy((char*)taddr,(char*)addr); + + nexttok = taddr; + for(i = 0; i < 4 ; i++) + { + nexttok = (int8_t*)strtok((char*)nexttok,"."); + if(nexttok[0] == '0' && nexttok[1] == 'x') num = strtol((char*)nexttok+2, NULL, 16); + else num = strtol((char*)nexttok, NULL, 10); + inetaddr = inetaddr << 8; + inetaddr |= (num & 0xFF); + nexttok = NULL; + } + return inetaddr; +} + +/** + * Swap the byte order of 16bit(short) wide variable. + * + * @param i 16bit value to swap + * @return Swapped value + */ +uint16_t swaps(uint16_t i) +{ + uint16_t ret=0; + ret = (i & 0xFF) << 8; + ret |= ((i >> 8)& 0xFF); + return ret; +} + +/** + * Swap the byte order of 32bit(long) wide variable. + * + * @param l 32bit value to convert + * @return Swapped value + */ +uint32_t swapl(uint32_t l) +{ + uint32_t ret=0; + ret = (l & 0xFF) << 24; + ret |= ((l >> 8) & 0xFF) << 16; + ret |= ((l >> 16) & 0xFF) << 8; + ret |= ((l >> 24) & 0xFF); + return ret; +} + +/** + * htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian). + * + * @param hostshort The value to convert. + * @return The value in TCP/IP network byte order. + */ +uint16_t htons(uint16_t hostshort) +{ +#ifdef SYSTEM_LITTLE_ENDIAN + return swaps(hostshort); +#else + return hostshort; +#endif +} + + +/** + * htonl function converts a unsigned long from host to TCP/IP network byte order (which is big-endian). + * + * @param hostlong The value to convert. + * @return The value in TCP/IP network byte order. + */ +uint32_t htonl(uint32_t hostlong) +{ +#ifdef SYSTEM_LITTLE_ENDIAN + return swapl(hostlong); +#else + return hostlong; +#endif +} + + +/** + * ntohs function converts a unsigned short from TCP/IP network byte order + * to host byte order (which is little-endian on Intel processors). + * + * @param netshort The value to convert. + * @return A 16-bit number in host byte order + */ +uint32_t ntohs(uint16_t netshort) +{ +#ifdef SYSTEM_LITTLE_ENDIAN + return htons(netshort); +#else + return netshort; +#endif +} + +/** + * converts a unsigned long from TCP/IP network byte order to host byte order + * (which is little-endian on Intel processors). + * + * @param netlong The value to convert. + * @return A 16-bit number in host byte order + */ +uint32_t ntohl(uint32_t netlong) +{ +#ifdef SYSTEM_LITTLE_ENDIAN + return swapl(netlong); +#else + return netlong; +#endif +} +/** + * @} + */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.h new file mode 100755 index 00000000000..08375a37477 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/netutil.h @@ -0,0 +1,27 @@ + +#ifndef __NETUTIL_H__ +#define __NETUTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define SYSTEM_LITTLE_ENDIAN + +int8_t* inet_ntoa(uint32_t addr); +int8_t* inet_ntoa_pad(uint32_t addr); +uint32_t inet_addr(uint8_t* addr); +uint16_t swaps(uint16_t i); +uint32_t swapl(uint32_t l); +uint16_t htons(uint16_t hostshort); +uint32_t htonl(uint32_t hostlong); +uint32_t ntohs(uint16_t netshort); +uint32_t ntohl(uint32_t netlong); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.c new file mode 100755 index 00000000000..2002ca48b4b --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.c @@ -0,0 +1,660 @@ +/** + * @file tftp.c + * @brief TFTP Source File. + * @version 0.1.0 + * @author Sang-sik Kim + */ + +/* Includes -----------------------------------------------------*/ +#include +#include "tftp.h" +#include "socket.h" +#include "netutil.h" + +/* define -------------------------------------------------------*/ + +/* typedef ------------------------------------------------------*/ + +/* Extern Variable ----------------------------------------------*/ + +/* Extern Functions ---------------------------------------------*/ +#ifdef F_STORAGE +extern void save_data(uint8_t *data, uint32_t data_len, uint16_t block_number); +#endif + +/* Global Variable ----------------------------------------------*/ +static int g_tftp_socket = -1; + +static uint8_t g_filename[FILE_NAME_SIZE]; + +static uint32_t g_server_ip = 0; +static uint16_t g_server_port = 0; +static uint16_t g_local_port = 0; + +static uint32_t g_tftp_state = STATE_NONE; +static uint16_t g_block_num = 0; + +static uint32_t g_timeout = 5; +static uint32_t g_resend_flag = 0; +static uint32_t tftp_time_cnt = 0; +static uint32_t tftp_retry_cnt = 0; + +static uint8_t *g_tftp_rcv_buf = NULL; + +static TFTP_OPTION default_tftp_opt = { + .code = (uint8_t *)"timeout", + .value = (uint8_t *)"5" +}; + +uint8_t g_progress_state = TFTP_PROGRESS; + +#ifdef __TFTP_DEBUG__ +int dbg_level = (INFO_DBG | ERROR_DBG | IPC_DBG); +#endif + +/* static function define ---------------------------------------*/ +static void set_filename(uint8_t *file, uint32_t file_size) +{ + memcpy(g_filename, file, file_size); +} + +static inline void set_server_ip(uint32_t ipaddr) +{ + g_server_ip = ipaddr; +} + +static inline uint32_t get_server_ip() +{ + return g_server_ip; +} + +static inline void set_server_port(uint16_t port) +{ + g_server_port = port; +} + +static inline uint16_t get_server_port() +{ + return g_server_port; +} + +static inline void set_local_port(uint16_t port) +{ + g_local_port = port; +} + +static inline uint16_t get_local_port() +{ + return g_local_port; +} + +static inline uint16_t genernate_port() +{ + /* TODO */ + return 0; +} + +static inline void set_tftp_state(uint32_t state) +{ + g_tftp_state = state; +} + +static inline uint32_t get_tftp_state() +{ + return g_tftp_state; +} + +static inline void set_tftp_timeout(uint32_t timeout) +{ + g_timeout = timeout; +} + +static inline uint32_t get_tftp_timeout() +{ + return g_timeout; +} + +static inline void set_block_number(uint16_t block_number) +{ + g_block_num = block_number; +} + +static inline uint16_t get_block_number() +{ + return g_block_num; +} + +static int open_tftp_socket(uint8_t sock) +{ + uint8_t sd, sck_state; + + sd = socket(sock, Sn_MR_UDP, 51000, SF_IO_NONBLOCK); + if(sd != sock) { + //DBG_PRINT(ERROR_DBG, "[%s] socket error\r\n", __func__); + return -1; + } + + do { + getsockopt(sd , SO_STATUS, &sck_state); + } while(sck_state != SOCK_UDP); + + return sd; +} + +static int send_udp_packet(int socket, uint8_t *packet, uint32_t len, uint32_t ip, uint16_t port) +{ + int snd_len; + + ip = htonl(ip); + + snd_len = sendto(socket, packet, len, (uint8_t *)&ip, port); + if(snd_len != len) { + //DBG_PRINT(ERROR_DBG, "[%s] sendto error\r\n", __func__); + return -1; + } + + return snd_len; +} + +static int recv_udp_packet(int socket, uint8_t *packet, uint32_t len, uint32_t *ip, uint16_t *port) +{ + int ret; + uint8_t sck_state; + uint16_t recv_len; + + /* Receive Packet Process */ + ret = getsockopt(socket, SO_STATUS, &sck_state); + if(ret != SOCK_OK) { + //DBG_PRINT(ERROR_DBG, "[%s] getsockopt SO_STATUS error\r\n", __func__); + return -1; + } + + if(sck_state == SOCK_UDP) { + ret = getsockopt(socket, SO_RECVBUF, &recv_len); + if(ret != SOCK_OK) { + //DBG_PRINT(ERROR_DBG, "[%s] getsockopt SO_RECVBUF error\r\n", __func__); + return -1; + } + + if(recv_len) { + recv_len = recvfrom(socket, packet, len, (uint8_t *)ip, port); + if(recv_len < 0) { + //DBG_PRINT(ERROR_DBG, "[%s] recvfrom error\r\n", __func__); + return -1; + } + + *ip = ntohl(*ip); + + return recv_len; + } + } + return -1; +} + +static void close_tftp_socket(int socket) +{ + close(socket); +} + + +static void init_tftp(void) +{ + g_filename[0] = 0; + + set_server_ip(0); + set_server_port(0); + set_local_port(0); + + set_tftp_state(STATE_NONE); + set_block_number(0); + + /* timeout flag */ + g_resend_flag = 0; + tftp_retry_cnt = tftp_time_cnt = 0; + + g_progress_state = TFTP_PROGRESS; +} + +static void tftp_cancel_timeout(void) +{ + if(g_resend_flag) { + g_resend_flag = 0; + tftp_retry_cnt = tftp_time_cnt = 0; + } +} + +static void tftp_reg_timeout() +{ + if(g_resend_flag == 0) { + g_resend_flag = 1; + tftp_retry_cnt = tftp_time_cnt = 0; + } +} + +static void process_tftp_option(uint8_t *msg, uint32_t msg_len) +{ + /* TODO Option Process */ +} + +static void send_tftp_rrq(uint8_t *filename, uint8_t *mode, TFTP_OPTION *opt, uint8_t opt_len) +{ + uint8_t snd_buf[MAX_MTU_SIZE]; + uint8_t *pkt = snd_buf; + uint32_t i, len; + + *((uint16_t *)pkt) = htons(TFTP_RRQ); + pkt += 2; + strcpy((char *)pkt, (const char *)filename); + pkt += strlen((char *)filename) + 1; + strcpy((char *)pkt, (const char *)mode); + pkt += strlen((char *)mode) + 1; + + for(i = 0 ; i < opt_len ; i++) { + strcpy((char *)pkt, (const char *)opt[i].code); + pkt += strlen((char *)opt[i].code) + 1; + strcpy((char *)pkt, (const char *)opt[i].value); + pkt += strlen((char *)opt[i].value) + 1; + } + + len = pkt - snd_buf; + + send_udp_packet(g_tftp_socket, snd_buf, len, get_server_ip(), TFTP_SERVER_PORT); + set_tftp_state(STATE_RRQ); + set_filename(filename, strlen((char *)filename) + 1); + tftp_reg_timeout(); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, ">> TFTP RRQ : FileName(%s), Mode(%s)\r\n", filename, mode); +#endif +} + +#if 0 // 2014.07.01 sskim +static void send_tftp_wrq(uint8_t *filename, uint8_t *mode, TFTP_OPTION *opt, uint8_t opt_len) +{ + uint8_t snd_buf[MAX_MTU_SIZE]; + uint8_t *pkt = snd_buf; + uint32_t i, len; + + *((uint16_t *)pkt) = htons((uint16_t)TFTP_WRQ); + pkt += 2; + strcpy((char *)pkt, (const char *)filename); + pkt += strlen((char *)filename) + 1; + strcpy((char *)pkt, (const char *)mode); + pkt += strlen((char *)mode) + 1; + + for(i = 0 ; i < opt_len ; i++) { + strcpy((char *)pkt, (const char *)opt[i].code); + pkt += strlen((char *)opt[i].code) + 1; + strcpy((char *)pkt, (const char *)opt[i].value); + pkt += strlen((char *)opt[i].value) + 1; + } + + len = pkt - snd_buf; + + send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), TFTP_SERVER_PORT); + set_tftp_state(STATE_WRQ); + set_filename(filename, strlen((char *)filename) + 1); + tftp_reg_timeout(); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, ">> TFTP WRQ : FileName(%s), Mode(%s)\r\n", filename, mode); +#endif +} +#endif + +#if 0 // 2014.07.01 sskim +static void send_tftp_data(uint16_t block_number, uint8_t *data, uint16_t data_len) +{ + uint8_t snd_buf[MAX_MTU_SIZE]; + uint8_t *pkt = snd_buf; + uint32_t len; + + *((uint16_t *)pkt) = htons((uint16_t)TFTP_DATA); + pkt += 2; + *((uint16_t *)pkt) = htons(block_number); + pkt += 2; + memcpy(pkt, data, data_len); + pkt += data_len; + + len = pkt - snd_buf; + + send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), get_server_port()); + tftp_reg_timeout(); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, ">> TFTP DATA : Block Number(%d), Data Length(%d)\r\n", block_number, data_len); +#endif +} +#endif + +static void send_tftp_ack(uint16_t block_number) +{ + uint8_t snd_buf[4]; + uint8_t *pkt = snd_buf; + + *((uint16_t *)pkt) = htons((uint16_t)TFTP_ACK); + pkt += 2; + *((uint16_t *)pkt) = htons(block_number); + pkt += 2; + + send_udp_packet(g_tftp_socket , snd_buf, 4, get_server_ip(), get_server_port()); + tftp_reg_timeout(); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, ">> TFTP ACK : Block Number(%d)\r\n", block_number); +#endif +} + +#if 0 // 2014.07.01 sskim +static void send_tftp_oack(TFTP_OPTION *opt, uint8_t opt_len) +{ + uint8_t snd_buf[MAX_MTU_SIZE]; + uint8_t *pkt = snd_buf; + uint32_t i, len; + + *((uint16_t *)pkt) = htons((uint16_t)TFTP_OACK); + pkt += 2; + + for(i = 0 ; i < opt_len ; i++) { + strcpy((char *)pkt, (const char *)opt[i].code); + pkt += strlen((char *)opt[i].code) + 1; + strcpy((char *)pkt, (const char *)opt[i].value); + pkt += strlen((char *)opt[i].value) + 1; + } + + len = pkt - snd_buf; + + send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), get_server_port()); + tftp_reg_timeout(); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, ">> TFTP OACK \r\n"); +#endif +} +#endif + +#if 0 // 2014.07.01 sskim +static void send_tftp_error(uint16_t error_number, uint8_t *error_message) +{ + uint8_t snd_buf[MAX_MTU_SIZE]; + uint8_t *pkt = snd_buf; + uint32_t len; + + *((uint16_t *)pkt) = htons((uint16_t)TFTP_ERROR); + pkt += 2; + *((uint16_t *)pkt) = htons(error_number); + pkt += 2; + strcpy((char *)pkt, (const char *)error_message); + pkt += strlen((char *)error_message) + 1; + + len = pkt - snd_buf; + + send_udp_packet(g_tftp_socket , snd_buf, len, get_server_ip(), get_server_port()); + tftp_reg_timeout(); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, ">> TFTP ERROR : Error Number(%d)\r\n", error_number); +#endif +} +#endif + +static void recv_tftp_rrq(uint8_t *msg, uint32_t msg_len) +{ + /* When TFTP Server Mode */ +} + +static void recv_tftp_wrq(uint8_t *msg, uint32_t msg_len) +{ + /* When TFTP Server Mode */ +} + +static void recv_tftp_data(uint8_t *msg, uint32_t msg_len) +{ + TFTP_DATA_T *data = (TFTP_DATA_T *)msg; + + data->opcode = ntohs(data->opcode); + data->block_num = ntohs(data->block_num); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, "<< TFTP_DATA : opcode(%d), block_num(%d)\r\n", data->opcode, data->block_num); +#endif + + switch(get_tftp_state()) + { + case STATE_RRQ : + case STATE_OACK : + if(data->block_num == 1) { + set_tftp_state(STATE_DATA); + set_block_number(data->block_num); +#ifdef F_STORAGE + save_data(data->data, msg_len - 4, data->block_num); +#endif + tftp_cancel_timeout(); + } + send_tftp_ack(data->block_num); + + if((msg_len - 4) < TFTP_BLK_SIZE) { + init_tftp(); + g_progress_state = TFTP_SUCCESS; + } + + break; + + case STATE_DATA : + if(data->block_num == (get_block_number() + 1)) { + set_block_number(data->block_num); +#ifdef F_STORAGE + save_data(data->data, msg_len - 4, data->block_num); +#endif + tftp_cancel_timeout(); + } + send_tftp_ack(data->block_num); + + if((msg_len - 4) < TFTP_BLK_SIZE) { + init_tftp(); + g_progress_state = TFTP_SUCCESS; + } + + break; + + default : + /* invalid message */ + break; + } +} + +static void recv_tftp_ack(uint8_t *msg, uint32_t msg_len) +{ +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, "<< TFTP_ACK : \r\n"); +#endif + + switch(get_tftp_state()) + { + case STATE_WRQ : + break; + + case STATE_ACK : + break; + + default : + /* invalid message */ + break; + } +} + +static void recv_tftp_oack(uint8_t *msg, uint32_t msg_len) +{ +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, "<< TFTP_OACK : \r\n"); +#endif + + switch(get_tftp_state()) + { + case STATE_RRQ : + process_tftp_option(msg, msg_len); + set_tftp_state(STATE_OACK); + tftp_cancel_timeout(); + send_tftp_ack(0); + break; + + case STATE_WRQ : + process_tftp_option(msg, msg_len); + set_tftp_state(STATE_ACK); + tftp_cancel_timeout(); + + /* TODO DATA Transfer */ + //send_tftp_data(...); + break; + + default : + /* invalid message */ + break; + } +} + +static void recv_tftp_error(uint8_t *msg, uint32_t msg_len) +{ + TFTP_ERROR_T *data= (TFTP_ERROR_T *)msg; + + data->opcode = ntohs(data->opcode); + data->error_code = ntohs(data->error_code); + +#ifdef __TFTP_DEBUG__ + DBG_PRINT(IPC_DBG, "<< TFTP_ERROR : %d (%s)\r\n", data->error_code, data->error_msg); + DBG_PRINT(ERROR_DBG, "[%s] Error Code : %d (%s)\r\n", __func__, data->error_code, data->error_msg); +#endif + init_tftp(); + g_progress_state = TFTP_FAIL; +} + +static void recv_tftp_packet(uint8_t *packet, uint32_t packet_len, uint32_t from_ip, uint16_t from_port) +{ + uint16_t opcode; + + /* Verify Server IP */ + if(from_ip != get_server_ip()) { +#ifdef __TFTP_DEBUG__ + DBG_PRINT(ERROR_DBG, "[%s] Server IP faults\r\n", __func__); + DBG_PRINT(ERROR_DBG, "from IP : %08x, Server IP : %08x\r\n", from_ip, get_server_ip()); +#endif + return; + } + + opcode = ntohs(*((uint16_t *)packet)); + + /* Set Server Port */ + if((get_tftp_state() == STATE_WRQ) || (get_tftp_state() == STATE_RRQ)) { + set_server_port(from_port); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(INFO_DBG, "[%s] Set Server Port : %d\r\n", __func__, from_port); +#endif + } + + switch(opcode) + { + case TFTP_RRQ : /* When Server */ + recv_tftp_rrq(packet, packet_len); + break; + case TFTP_WRQ : /* When Server */ + recv_tftp_wrq(packet, packet_len); + break; + case TFTP_DATA : + recv_tftp_data(packet, packet_len); + break; + case TFTP_ACK : + recv_tftp_ack(packet, packet_len); + break; + case TFTP_OACK : + recv_tftp_oack(packet, packet_len); + break; + case TFTP_ERROR : + recv_tftp_error(packet, packet_len); + break; + + default : + // Unknown Mesage + break; + } +} + +/* Functions ----------------------------------------------------*/ +void TFTP_init(uint8_t socket, uint8_t *buf) +{ + init_tftp(); + + g_tftp_socket = open_tftp_socket(socket); + g_tftp_rcv_buf = buf; +} + +void TFTP_exit(void) +{ + init_tftp(); + + close_tftp_socket(g_tftp_socket); + g_tftp_socket = -1; + + g_tftp_rcv_buf = NULL; +} + +int TFTP_run(void) +{ + uint16_t len, from_port; + uint32_t from_ip; + + /* Timeout Process */ + if(g_resend_flag) { + if(tftp_time_cnt >= g_timeout) { + switch(get_tftp_state()) { + case STATE_WRQ: // 미구현 + break; + + case STATE_RRQ: + send_tftp_rrq(g_filename, (uint8_t *)TRANS_BINARY, &default_tftp_opt, 1); + break; + + case STATE_OACK: + case STATE_DATA: + send_tftp_ack(get_block_number()); + break; + + case STATE_ACK: // 미구현 + break; + + default: + break; + } + + tftp_time_cnt = 0; + tftp_retry_cnt++; + + if(tftp_retry_cnt >= 5) { + init_tftp(); + g_progress_state = TFTP_FAIL; + } + } + } + + /* Receive Packet Process */ + len = recv_udp_packet(g_tftp_socket, g_tftp_rcv_buf, MAX_MTU_SIZE, &from_ip, &from_port); + if(len < 0) { +#ifdef __TFTP_DEBUG__ + DBG_PRINT(ERROR_DBG, "[%s] recv_udp_packet error\r\n", __func__); +#endif + return g_progress_state; + } + + recv_tftp_packet(g_tftp_rcv_buf, len, from_ip, from_port); + + return g_progress_state; +} + +void TFTP_read_request(uint32_t server_ip, uint8_t *filename) +{ + set_server_ip(server_ip); +#ifdef __TFTP_DEBUG__ + DBG_PRINT(INFO_DBG, "[%s] Set Tftp Server : %x\r\n", __func__, server_ip); +#endif + + g_progress_state = TFTP_PROGRESS; + send_tftp_rrq(filename, (uint8_t *)TRANS_BINARY, &default_tftp_opt, 1); +} + +void tftp_timeout_handler(void) +{ + if(g_resend_flag) + tftp_time_cnt++; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.h new file mode 100755 index 00000000000..b8f3b4dc3c1 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/TFTP/tftp.h @@ -0,0 +1,101 @@ +/** + * @file tftp.h + * @brief TFTP Header File. + * @version 0.1.0 + * @author Sang-sik Kim + */ +#ifndef __TFTP_H__ +#define __TFTP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define F_APP_TFTP +#define __TFTP_DEBUG__ + +#define F_STORAGE // If your target support a storage, you have to activate this feature and implement. + +#define SOCK_TFTP 1 + +#define INFO_DBG 0x01 +#define ERROR_DBG 0x02 +#define DEBUG_DBG 0x04 +#define IPC_DBG 0x08 + +#define DBG_PRINT(level, format, args...) { \ + if(dbg_level & level) \ + printf(format, ##args); \ + } + +#define NORMAL_MODE 0 +#define TFTP_MODE 1 + +extern int dbg_level; + +/* tftp message */ +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 +#define TFTP_OACK 6 + +/* tftp state */ +#define STATE_NONE 0 +#define STATE_RRQ 1 +#define STATE_WRQ 2 +#define STATE_DATA 3 +#define STATE_ACK 4 +#define STATE_OACK 5 + +/* tftp transfer mode */ +#define TRANS_ASCII "netascii" +#define TRANS_BINARY "octet" + +/* tftp progress state */ +#define TFTP_PROGRESS 0 +#define TFTP_FAIL 1 +#define TFTP_SUCCESS 2 + +/* define */ +#define TFTP_SERVER_PORT 69 +#define TFTP_TEMP_PORT 51000 +#define TFTP_BLK_SIZE 512 +#define MAX_MTU_SIZE 1514 +#define FILE_NAME_SIZE 20 + +//#define __TFTP_DEBUG__ + +/* typedef */ +typedef struct tftp_data { + uint16_t opcode; + uint16_t block_num; + uint8_t data[0]; +} TFTP_DATA_T; + +typedef struct tftp_error { + uint16_t opcode; + uint16_t error_code; + uint8_t error_msg[0]; +} TFTP_ERROR_T; + +typedef struct tftp_option { + uint8_t *code; + uint8_t *value; +} TFTP_OPTION; + +/* Functions */ +void TFTP_init(uint8_t socket, uint8_t *buf); +void TFTP_exit(void); +int TFTP_run(void); +void TFTP_read_request(uint32_t server_ip, uint8_t *filename); +void tftp_timeout_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__TFTP_H__ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.c new file mode 100755 index 00000000000..3d353e3bb31 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.c @@ -0,0 +1,402 @@ +/** + @file httpd.c + @brief functions associated http processing + */ + +#include +#include +#include "socket.h" +#include "httpParser.h" + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ +//uint8_t BUFPUB[2048]; +uint8_t BUFPUB[256]; + +/***************************************************************************** + * Private functions + ****************************************************************************/ +static void replacetochar(uint8_t * str, uint8_t oldchar, uint8_t newchar); /* Replace old character with new character in the string */ +static uint8_t C2D(uint8_t c); /* Convert a character to HEX */ + +/** + @brief convert escape characters(%XX) to ASCII character + */ +void unescape_http_url( + char * url /**< pointer to be converted ( escape characters )*/ + ) +{ + int x, y; + + for (x = 0, y = 0; url[y]; ++x, ++y) { + if ((url[x] = url[y]) == '%') { + url[x] = C2D(url[y+1])*0x10+C2D(url[y+2]); + y+=2; + } + } + url[x] = '\0'; +} + + +/** + @brief make response header such as html, gif, jpeg,etc. + */ +void make_http_response_head( + char * buf, /**< pointer to response header to be made */ + char type, /**< response type */ + uint32_t len /**< size of response header */ + ) +{ + char * head; + char tmp[10]; + + /* file type*/ + if (type == PTYPE_HTML) head = RES_HTMLHEAD_OK; + else if (type == PTYPE_GIF) head = RES_GIFHEAD_OK; + else if (type == PTYPE_TEXT) head = RES_TEXTHEAD_OK; + else if (type == PTYPE_JPEG) head = RES_JPEGHEAD_OK; + else if (type == PTYPE_FLASH) head = RES_FLASHHEAD_OK; + else if (type == PTYPE_XML) head = RES_XMLHEAD_OK; + else if (type == PTYPE_CSS) head = RES_CSSHEAD_OK; + else if (type == PTYPE_JSON) head = RES_JSONHEAD_OK; + else if (type == PTYPE_JS) head = RES_JSHEAD_OK; + else if (type == PTYPE_CGI) head = RES_CGIHEAD_OK; + else if (type == PTYPE_PNG) head = RES_PNGHEAD_OK; + else if (type == PTYPE_ICO) head = RES_ICOHEAD_OK; + else if (type == PTYPE_TTF) head = RES_TTFHEAD_OK; + else if (type == PTYPE_OTF) head = RES_OTFHEAD_OK; + else if (type == PTYPE_WOFF) head = RES_WOFFHEAD_OK; + else if (type == PTYPE_EOT) head = RES_EOTHEAD_OK; + else if (type == PTYPE_SVG) head = RES_SVGHEAD_OK; +#ifdef _HTTPPARSER_DEBUG_ + else + { + head = NULL; + printf("\r\n\r\n-MAKE HEAD UNKNOWN-\r\n"); + } +#else + else head = NULL; +#endif + + sprintf(tmp, "%ld", len); + strcpy(buf, head); + strcat(buf, tmp); + strcat(buf, "\r\n\r\n"); +} + + +/** + @brief find MIME type of a file + */ +void find_http_uri_type( + uint8_t * type, /**< type to be returned */ + uint8_t * buff /**< file name */ + ) +{ + /* Decide type according to extension*/ + + char * buf; + buf = (char *)buff; + + if (strstr(buf, ".htm") || strstr(buf, ".html")) *type = PTYPE_HTML; + else if (strstr(buf, ".gif")) *type = PTYPE_GIF; + else if (strstr(buf, ".text") || strstr(buf,".txt")) *type = PTYPE_TEXT; + else if (strstr(buf, ".jpeg") || strstr(buf,".jpg")) *type = PTYPE_JPEG; + else if (strstr(buf, ".swf")) *type = PTYPE_FLASH; + else if (strstr(buf, ".cgi") || strstr(buf,".CGI")) *type = PTYPE_CGI; + else if (strstr(buf, ".json") || strstr(buf,".JSON")) *type = PTYPE_JSON; + else if (strstr(buf, ".js") || strstr(buf,".JS")) *type = PTYPE_JS; + else if (strstr(buf, ".CGI") || strstr(buf,".cgi")) *type = PTYPE_CGI; + else if (strstr(buf, ".xml") || strstr(buf,".XML")) *type = PTYPE_XML; + else if (strstr(buf, ".css") || strstr(buf,".CSS")) *type = PTYPE_CSS; + else if (strstr(buf, ".png") || strstr(buf,".PNG")) *type = PTYPE_PNG; + else if (strstr(buf, ".ico") || strstr(buf,".ICO")) *type = PTYPE_ICO; + else if (strstr(buf, ".ttf") || strstr(buf,".TTF")) *type = PTYPE_TTF; + else if (strstr(buf, ".otf") || strstr(buf,".OTF")) *type = PTYPE_OTF; + else if (strstr(buf, ".woff") || strstr(buf,".WOFF")) *type = PTYPE_WOFF; + else if (strstr(buf, ".eot") || strstr(buf,".EOT")) *type = PTYPE_EOT; + else if (strstr(buf, ".svg") || strstr(buf,".SVG")) *type = PTYPE_SVG; + else *type = PTYPE_ERR; +} + + +/** + @brief parse http request from a peer + */ +void parse_http_request( + st_http_request * request, /**< request to be returned */ + uint8_t * buf /**< pointer to be parsed */ + ) +{ + char * nexttok; + nexttok = strtok((char*)buf," "); + if(!nexttok) + { + request->METHOD = METHOD_ERR; + return; + } + if(!strcmp(nexttok, "GET") || !strcmp(nexttok,"get")) + { + request->METHOD = METHOD_GET; + nexttok = strtok(NULL," "); + + } + else if (!strcmp(nexttok, "HEAD") || !strcmp(nexttok,"head")) + { + request->METHOD = METHOD_HEAD; + nexttok = strtok(NULL," "); + + } + else if (!strcmp(nexttok, "POST") || !strcmp(nexttok,"post")) + { + nexttok = strtok(NULL,"\0"); + request->METHOD = METHOD_POST; + } + else + { + request->METHOD = METHOD_ERR; + } + + if(!nexttok) + { + request->METHOD = METHOD_ERR; + return; + } + strcpy((char *)request->URI, nexttok); +} + +#ifdef _OLD_ +/** + @brief get next parameter value in the request + */ +uint8_t * get_http_param_value( + char* uri, + char* param_name + ) +{ + char tempURI[MAX_URI_SIZE]; + uint8_t * name = 0; + + + if(!uri || !param_name) return 0; + + strcpy((char*)tempURI,uri); + if((name = (uint8_t*)strstr(tempURI, param_name))) + { + name += strlen(param_name) + 1; // strlen(para_name) + strlen("=") + if((name = (uint8_t*)strtok((char *)name,"& \r\n\t\0"))) + { + unescape_http_url((char *)name); + replacetochar(name, '+', ' '); + } + } +#ifdef _HTTPPARSER_DEBUG_ + printf(" %s=%s",param_name,name); +#endif + + return name; +} +#else +/** + @brief get next parameter value in the request + */ +uint8_t * get_http_param_value(char* uri, char* param_name) +{ + + uint8_t * name = 0; + uint8_t * ret = BUFPUB; + uint8_t * pos2; + uint16_t len = 0, content_len = 0; + uint8_t tmp_buf[10]={0x00, }; + + if(!uri || !param_name) return 0; + + /***************/ + mid(uri, "Content-Length: ", "\r\n", (char *)tmp_buf); + content_len = ATOI(tmp_buf, 10); + uri = strstr(uri, "\r\n\r\n"); + uri += 4; + uri[content_len] = 0; + /***************/ + + if((name = (uint8_t *)strstr(uri, param_name))) + { + name += strlen(param_name) + 1; + pos2 = (uint8_t*)strstr((char*)name, "&"); + if(!pos2) + { + pos2 = name + strlen((char*)name); + } + len = pos2 - name; + + if(len) + { + ret[len] = 0; + strncpy((char*)ret,(char*)name, len); + unescape_http_url((char *)ret); + replacetochar(ret, '+' ,' '); + //ret[len] = 0; + //ret[strlen((int8*)ret)] = 0; + //printf("len=%d\r\n",len); + } + else + { + ret[0] = 0; + } + } + else + { + return 0; + } +#ifdef _HTTPPARSER_DEBUG_ + printf(" %s=%s\r\n", param_name, ret); +#endif + return ret; +} +#endif + +#ifdef _OLD_ +uint8_t * get_http_uri_name(uint8_t * uri) +{ + char tempURI[MAX_URI_SIZE]; + uint8_t * uri_name; + + if(!uri) return 0; + + strcpy(tempURI, (char *)uri); + + uri_name = (uint8_t *)strtok(tempURI, " ?"); + + if(strcmp((char *)uri_name,"/")) uri_name++; + +#ifdef _HTTPPARSER_DEBUG_ + printf(" uri_name = %s\r\n", uri_name); +#endif + + return uri_name; +} +#else + +uint8_t get_http_uri_name(uint8_t * uri, uint8_t * uri_buf) +{ + uint8_t * uri_ptr; + if(!uri) return 0; + + strcpy((char *)uri_buf, (char *)uri); + + uri_ptr = (uint8_t *)strtok((char *)uri_buf, " ?"); + + if(strcmp((char *)uri_ptr,"/")) uri_ptr++; + strcpy((char *)uri_buf, (char *)uri_ptr); + +#ifdef _HTTPPARSER_DEBUG_ + printf(" uri_name = %s\r\n", uri_buf); +#endif + + return 1; +} + +#endif + +void inet_addr_(uint8_t * addr, uint8_t *ip) +{ + uint8_t i; + uint8_t taddr[30]; + uint8_t * nexttok; + uint8_t num; + + strcpy((char *)taddr, (char *)addr); + + nexttok = taddr; + for(i = 0; i < 4 ; i++) + { + nexttok = (uint8_t *)strtok((char *)nexttok, "."); + if(nexttok[0] == '0' && nexttok[1] == 'x') num = ATOI(nexttok+2,0x10); + else num = ATOI(nexttok,10); + ip[i] = num; + nexttok = NULL; + } +} + + +/** +@brief CONVERT STRING INTO INTEGER +@return a integer number +*/ +uint16_t ATOI( + uint8_t * str, /**< is a pointer to convert */ + uint8_t base /**< is a base value (must be in the range 2 - 16) */ + ) +{ + unsigned int num = 0; +// debug_2013_11_25 +// while (*str !=0) + while ((*str !=0) && (*str != 0x20)) // not include the space(0x020) + num = num * base + C2D(*str++); + return num; +} + +/** + * @brief Check strings and then execute callback function by each string. + * @param src The information of URI + * @param s1 The start string to be researched + * @param s2 The end string to be researched + * @param sub The string between s1 and s2 + * @return The length value atfer working + */ +void mid(char* src, char* s1, char* s2, char* sub) +{ + char* sub1; + char* sub2; + uint16_t n; + + sub1=strstr((char*)src,(char*)s1); + sub1+=strlen((char*)s1); + sub2=strstr((char*)sub1,(char*)s2); + + n=sub2-sub1; + strncpy((char*)sub,(char*)sub1,n); + sub[n]='\0'; +} + +//////////////////////////////////////////////////////////////////// +// Static functions +//////////////////////////////////////////////////////////////////// + +/** +@brief replace the specified character in a string with new character +*/ +static void replacetochar( + uint8_t * str, /**< pointer to be replaced */ + uint8_t oldchar, /**< old character */ + uint8_t newchar /**< new character */ + ) +{ + int x; + for (x = 0; str[x]; x++) + if (str[x] == oldchar) str[x] = newchar; +} + +/** +@brief CONVERT CHAR INTO HEX +@return HEX + +This function converts HEX(0-F) to a character +*/ +static uint8_t C2D( + uint8_t c /**< is a character('0'-'F') to convert to HEX */ + ) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return 10 + c -'a'; + if (c >= 'A' && c <= 'F') + return 10 + c -'A'; + + return (char)c; +} + + + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.h new file mode 100755 index 00000000000..b64be68a357 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpParser.h @@ -0,0 +1,158 @@ +/** + @file httpd.h + @brief Define Constants and fucntions associated with HTTP protocol. + */ + +#include + +#ifndef __HTTPPARSER_H__ +#define __HTTPPARSER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//#define _HTTPPARSER_DEBUG_ + +#define HTTP_SERVER_PORT 80 /**< HTTP server well-known port number */ + +/* HTTP Method */ +#define METHOD_ERR 0 /**< Error Method. */ +#define METHOD_GET 1 /**< GET Method. */ +#define METHOD_HEAD 2 /**< HEAD Method. */ +#define METHOD_POST 3 /**< POST Method. */ + +/* HTTP GET Method */ +#define PTYPE_ERR 0 /**< Error file. */ +#define PTYPE_HTML 1 /**< HTML file. */ +#define PTYPE_GIF 2 /**< GIF file. */ +#define PTYPE_TEXT 3 /**< TEXT file. */ +#define PTYPE_JPEG 4 /**< JPEG file. */ +#define PTYPE_FLASH 5 /**< FLASH file. */ +#define PTYPE_MPEG 6 /**< MPEG file. */ +#define PTYPE_PDF 7 /**< PDF file. */ +#define PTYPE_CGI 8 /**< CGI file. */ +#define PTYPE_XML 9 /**< XML file. */ +#define PTYPE_CSS 10 /**< CSS file. */ +#define PTYPE_JS 11 /**< JavaScript file. */ +#define PTYPE_JSON 12 /**< JSON (JavaScript Standard Object Notation) file. */ +#define PTYPE_PNG 13 /**< PNG file. */ +#define PTYPE_ICO 14 /**< ICON file. */ + +#define PTYPE_TTF 20 /**< Font type: TTF file. */ +#define PTYPE_OTF 21 /**< Font type: OTF file. */ +#define PTYPE_WOFF 22 /**< Font type: WOFF file. */ +#define PTYPE_EOT 23 /**< Font type: EOT file. */ +#define PTYPE_SVG 24 /**< Font type: SVG file. */ + + +/* HTTP response */ +#define STATUS_OK 200 +#define STATUS_CREATED 201 +#define STATUS_ACCEPTED 202 +#define STATUS_NO_CONTENT 204 +#define STATUS_MV_PERM 301 +#define STATUS_MV_TEMP 302 +#define STATUS_NOT_MODIF 304 +#define STATUS_BAD_REQ 400 +#define STATUS_UNAUTH 401 +#define STATUS_FORBIDDEN 403 +#define STATUS_NOT_FOUND 404 +#define STATUS_INT_SERR 500 +#define STATUS_NOT_IMPL 501 +#define STATUS_BAD_GATEWAY 502 +#define STATUS_SERV_UNAVAIL 503 + +/* HTML Doc. for ERROR */ +static const char ERROR_HTML_PAGE[] = "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\nContent-Length: 78\r\n\r\n\r\n\r\nSorry, the page you requested was not found.\r\n\r\n\r\n\0"; +static const char ERROR_REQUEST_PAGE[] = "HTTP/1.1 400 OK\r\nContent-Type: text/html\r\nContent-Length: 50\r\n\r\n\r\n\r\nInvalid request.\r\n\r\n\r\n\0"; + +/* HTML Doc. for CGI result */ +#define HTML_HEADER "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: " + +/* Response header for HTML*/ +#define RES_HTMLHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: keep-alive\r\nContent-Length: " + +/* Response head for TEXT */ +#define RES_TEXTHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: " + +/* Response head for GIF */ +#define RES_GIFHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: image/gif\r\nContent-Length: " + +/* Response head for JPEG */ +#define RES_JPEGHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\nContent-Length: " + +/* Response head for PNG */ +#define RES_PNGHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: image/png\r\nContent-Length: " + +/* Response head for FLASH */ +#define RES_FLASHHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/x-shockwave-flash\r\nContent-Length: " + +/* Response head for XML */ +#define RES_XMLHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\nConnection: keep-alive\r\nContent-Length: " + +/* Response head for CSS */ +#define RES_CSSHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: text/css\r\nContent-Length: " + +/* Response head for JavaScript */ +#define RES_JSHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/javascript\r\nContent-Length: " + +/* Response head for JSON */ +#define RES_JSONHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: " + +/* Response head for ICO */ +#define RES_ICOHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: image/x-icon\r\nContent-Length: " + +/* Response head for CGI */ +#define RES_CGIHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: " + +/* Response head for TTF, Font */ +#define RES_TTFHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/x-font-truetype\r\nContent-Length: " + +/* Response head for OTF, Font */ +#define RES_OTFHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/x-font-opentype\r\nContent-Length: " + +/* Response head for WOFF, Font */ +#define RES_WOFFHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/font-woff\r\nContent-Length: " + +/* Response head for EOT, Font */ +#define RES_EOTHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.ms-fontobject\r\nContent-Length: " + +/* Response head for SVG, Font */ +#define RES_SVGHEAD_OK "HTTP/1.1 200 OK\r\nContent-Type: image/svg+xml\r\nContent-Length: " + +/** + @brief Structure of HTTP REQUEST + */ + +//#define MAX_URI_SIZE 1461 +#define MAX_URI_SIZE 512 + +typedef struct _st_http_request +{ + uint8_t METHOD; /**< request method(METHOD_GET...). */ + uint8_t TYPE; /**< request type(PTYPE_HTML...). */ + uint8_t URI[MAX_URI_SIZE]; /**< request file name. */ +}st_http_request; + +// HTTP Parsing functions +void unescape_http_url(char * url); /* convert escape character to ascii */ +void parse_http_request(st_http_request *, uint8_t *); /* parse request from peer */ +void find_http_uri_type(uint8_t *, uint8_t *); /* find MIME type of a file */ +void make_http_response_head(char *, char, uint32_t); /* make response header */ +uint8_t * get_http_param_value(char* uri, char* param_name); /* get the user-specific parameter value */ +uint8_t get_http_uri_name(uint8_t * uri, uint8_t * uri_buf); /* get the requested URI name */ +#ifdef _OLD_ +uint8_t * get_http_uri_name(uint8_t * uri); +#endif + +// Utility functions +uint16_t ATOI(uint8_t * str, uint8_t base); +void mid(char* src, char* s1, char* s2, char* sub); +void inet_addr_(uint8_t * addr, uint8_t * ip); + +#ifdef __cplusplus +} +#endif + +#endif /* end of __HTTPPARSER_H__ */ diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.c new file mode 100755 index 00000000000..d98c4829926 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.c @@ -0,0 +1,749 @@ +#include +#include +#include + +#include "socket.h" +#include "wizchip_conf.h" + +#include "httpServer.h" +#include "httpParser.h" +#include "httpUtil.h" + +#ifdef _USE_SDCARD_ +#include "ff.h" // header file for FatFs library (FAT file system) +#endif + +#ifndef DATA_BUF_SIZE + #define DATA_BUF_SIZE 2048 +#endif + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ +static uint8_t HTTPSock_Num[_WIZCHIP_SOCK_NUM_] = {0, }; +static st_http_request * http_request; /**< Pointer to received HTTP request */ +static st_http_request * parsed_http_request; /**< Pointer to parsed HTTP request */ +static uint8_t * http_response; /**< Pointer to HTTP response */ + +// ## For Debugging +//static uint8_t uri_buf[128]; + +// Number of registered web content in code flash memory +static uint16_t total_content_cnt = 0; +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ +uint8_t * pHTTP_TX; +uint8_t * pHTTP_RX; + +volatile uint32_t httpServer_tick_1s = 0; +st_http_socket HTTPSock_Status[_WIZCHIP_SOCK_NUM_] = { {STATE_HTTP_IDLE, }, }; +httpServer_webContent web_content[MAX_CONTENT_CALLBACK]; + +#ifdef _USE_SDCARD_ +FIL fs; // FatFs: File object +FRESULT fr; // FatFs: File function return code +#endif + +/***************************************************************************** + * Private functions + ****************************************************************************/ +void httpServer_Sockinit(uint8_t cnt, uint8_t * socklist); +static uint8_t getHTTPSocketNum(uint8_t seqnum); +static int8_t getHTTPSequenceNum(uint8_t socket); +static int8_t http_disconnect(uint8_t sn); + +static void http_process_handler(uint8_t s, st_http_request * p_http_request); +static void send_http_response_header(uint8_t s, uint8_t content_type, uint32_t body_len, uint16_t http_status); +static void send_http_response_body(uint8_t s, uint8_t * uri_name, uint8_t * buf, uint32_t start_addr, uint32_t file_len); +static void send_http_response_cgi(uint8_t s, uint8_t * buf, uint8_t * http_body, uint16_t file_len); + +/***************************************************************************** + * Public functions + ****************************************************************************/ +// Callback functions definition: MCU Reset / WDT Reset +void default_mcu_reset(void) {;} +void default_wdt_reset(void) {;} +void (*HTTPServer_ReStart)(void) = default_mcu_reset; +void (*HTTPServer_WDT_Reset)(void) = default_wdt_reset; + +void httpServer_Sockinit(uint8_t cnt, uint8_t * socklist) +{ + uint8_t i; + + for(i = 0; i < cnt; i++) + { + // Mapping the H/W socket numbers to the sequential index numbers + HTTPSock_Num[i] = socklist[i]; + } +} + +static uint8_t getHTTPSocketNum(uint8_t seqnum) +{ + // Return the 'H/W socket number' corresponding to the index number + return HTTPSock_Num[seqnum]; +} + +static int8_t getHTTPSequenceNum(uint8_t socket) +{ + uint8_t i; + + for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++) + if(HTTPSock_Num[i] == socket) return i; + + return -1; +} + +void httpServer_init(uint8_t * tx_buf, uint8_t * rx_buf, uint8_t cnt, uint8_t * socklist) +{ + // User's shared buffer + pHTTP_TX = tx_buf; + pHTTP_RX = rx_buf; + + // H/W Socket number mapping + httpServer_Sockinit(cnt, socklist); +} + + +/* Register the call back functions for HTTP Server */ +void reg_httpServer_cbfunc(void(*mcu_reset)(void), void(*wdt_reset)(void)) +{ + // Callback: HW Reset and WDT reset function for each MCU platforms + if(mcu_reset) HTTPServer_ReStart = mcu_reset; + if(wdt_reset) HTTPServer_WDT_Reset = wdt_reset; +} + + +void httpServer_run(uint8_t seqnum) +{ + uint8_t s; // socket number + uint16_t len; + uint32_t gettime = 0; + +#ifdef _HTTPSERVER_DEBUG_ + uint8_t destip[4] = {0, }; + uint16_t destport = 0; +#endif + + http_request = (st_http_request *)pHTTP_RX; // Structure of HTTP Request + parsed_http_request = (st_http_request *)pHTTP_TX; + + // Get the H/W socket number + s = getHTTPSocketNum(seqnum); + + /* HTTP Service Start */ + switch(getSn_SR(s)) + { + case SOCK_ESTABLISHED: + // Interrupt clear + if(getSn_IR(s) & Sn_IR_CON) + { + setSn_IR(s, Sn_IR_CON); + } + + // HTTP Process states + switch(HTTPSock_Status[seqnum].sock_status) + { + + case STATE_HTTP_IDLE : + if ((len = getSn_RX_RSR(s)) > 0) + { + if (len > DATA_BUF_SIZE) len = DATA_BUF_SIZE; + len = recv(s, (uint8_t *)http_request, len); + + *(((uint8_t *)http_request) + len) = '\0'; + + parse_http_request(parsed_http_request, (uint8_t *)http_request); +#ifdef _HTTPSERVER_DEBUG_ + getSn_DIPR(s, destip); + destport = getSn_DPORT(s); + printf("\r\n"); + printf("> HTTPSocket[%d] : HTTP Request received ", s); + printf("from %d.%d.%d.%d : %d\r\n", destip[0], destip[1], destip[2], destip[3], destport); +#endif +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONE\r\n", s); +#endif + // HTTP 'response' handler; includes send_http_response_header / body function + http_process_handler(s, parsed_http_request); + + gettime = get_httpServer_timecount(); + // Check the TX socket buffer for End of HTTP response sends + while(getSn_TX_FSR(s) != (getSn_TxMAX(s))) + { + if((get_httpServer_timecount() - gettime) > 3) + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONE: TX Buffer clear timeout\r\n", s); +#endif + break; + } + } + + if(HTTPSock_Status[seqnum].file_len > 0) HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_INPROC; + else HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE; // Send the 'HTTP response' end + } + break; + + case STATE_HTTP_RES_INPROC : + /* Repeat: Send the remain parts of HTTP responses */ +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_INPROC\r\n", s); +#endif + // Repeatedly send remaining data to client + send_http_response_body(s, 0, http_response, 0, 0); + + if(HTTPSock_Status[seqnum].file_len == 0) HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE; + break; + + case STATE_HTTP_RES_DONE : +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_DONE\r\n", s); +#endif + // Socket file info structure re-initialize + HTTPSock_Status[seqnum].file_len = 0; + HTTPSock_Status[seqnum].file_offset = 0; + HTTPSock_Status[seqnum].file_start = 0; + HTTPSock_Status[seqnum].sock_status = STATE_HTTP_IDLE; + +//#ifdef _USE_SDCARD_ +// f_close(&fs); +//#endif +#ifdef _USE_WATCHDOG_ + HTTPServer_WDT_Reset(); +#endif + http_disconnect(s); + break; + + default : + break; + } + break; + + case SOCK_CLOSE_WAIT: +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : ClOSE_WAIT\r\n", s); // if a peer requests to close the current connection +#endif + disconnect(s); + break; + + case SOCK_CLOSED: +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : CLOSED\r\n", s); +#endif + if(socket(s, Sn_MR_TCP, HTTP_SERVER_PORT, 0x00) == s) /* Reinitialize the socket */ + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : OPEN\r\n", s); +#endif + } + break; + + case SOCK_INIT: + listen(s); + break; + + case SOCK_LISTEN: + break; + + default : + break; + + } // end of switch + +#ifdef _USE_WATCHDOG_ + HTTPServer_WDT_Reset(); +#endif +} + +//////////////////////////////////////////// +// Private Functions +//////////////////////////////////////////// +static void send_http_response_header(uint8_t s, uint8_t content_type, uint32_t body_len, uint16_t http_status) +{ + switch(http_status) + { + case STATUS_OK: // HTTP/1.1 200 OK + if((content_type != PTYPE_CGI) && (content_type != PTYPE_XML)) // CGI/XML type request does not respond HTTP header + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response Header - STATUS_OK\r\n", s); +#endif + make_http_response_head((char*)http_response, content_type, body_len); + } + else + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response Header - NONE / CGI or XML\r\n", s); +#endif + // CGI/XML type request does not respond HTTP header to client + http_status = 0; + } + break; + case STATUS_BAD_REQ: // HTTP/1.1 400 OK +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response Header - STATUS_BAD_REQ\r\n", s); +#endif + memcpy(http_response, ERROR_REQUEST_PAGE, sizeof(ERROR_REQUEST_PAGE)); + break; + case STATUS_NOT_FOUND: // HTTP/1.1 404 Not Found +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response Header - STATUS_NOT_FOUND\r\n", s); +#endif + memcpy(http_response, ERROR_HTML_PAGE, sizeof(ERROR_HTML_PAGE)); + break; + default: + break; + } + + // Send the HTTP Response 'header' + if(http_status) + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [Send] HTTP Response Header [ %d ]byte\r\n", s, (uint16_t)strlen((char *)http_response)); +#endif + send(s, http_response, strlen((char *)http_response)); + } +} + +static void send_http_response_body(uint8_t s, uint8_t * uri_name, uint8_t * buf, uint32_t start_addr, uint32_t file_len) +{ + int8_t get_seqnum; + uint32_t send_len; + + uint8_t flag_datasend_end = 0; + +#ifdef _USE_SDCARD_ + uint16_t blocklen; +#endif +#ifdef _USE_FLASH_ + uint32_t addr = 0; +#endif + + if((get_seqnum = getHTTPSequenceNum(s)) == -1) return; // exception handling; invalid number + + // Send the HTTP Response 'body'; requested file + if(!HTTPSock_Status[get_seqnum].file_len) // ### Send HTTP response body: First part ### + { + if (file_len > DATA_BUF_SIZE - 1) + { + HTTPSock_Status[get_seqnum].file_start = start_addr; + HTTPSock_Status[get_seqnum].file_len = file_len; + send_len = DATA_BUF_SIZE - 1; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// ## 20141219 Eric added, for 'File object structure' (fs) allocation reduced (8 -> 1) + memset(HTTPSock_Status[get_seqnum].file_name, 0x00, MAX_CONTENT_NAME_LEN); + strcpy((char *)HTTPSock_Status[get_seqnum].file_name, (char *)uri_name); +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response body - file name [ %s ]\r\n", s, HTTPSock_Status[get_seqnum].file_name); +#endif +///////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response body - file len [ %ld ]byte\r\n", s, file_len); +#endif + } + else + { + // Send process end + send_len = file_len; + +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response end - file len [ %ld ]byte\r\n", s, send_len); +#endif + } +#ifdef _USE_FLASH_ + if(HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH) addr = start_addr; +#endif + } + else // remained parts + { +#ifdef _USE_FLASH_ + if(HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH) + { + addr = HTTPSock_Status[get_seqnum].file_start + HTTPSock_Status[get_seqnum].file_offset; + } +#endif + send_len = HTTPSock_Status[get_seqnum].file_len - HTTPSock_Status[get_seqnum].file_offset; + + if(send_len > DATA_BUF_SIZE - 1) + { + send_len = DATA_BUF_SIZE - 1; + //HTTPSock_Status[get_seqnum]->file_offset += send_len; + } + else + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response end - file len [ %ld ]byte\r\n", s, HTTPSock_Status[get_seqnum].file_len); +#endif + // Send process end + flag_datasend_end = 1; + } +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response body - send len [ %ld ]byte\r\n", s, send_len); +#endif + } + +/*****************************************************/ + //HTTPSock_Status[get_seqnum]->storage_type == NONE + //HTTPSock_Status[get_seqnum]->storage_type == CODEFLASH + //HTTPSock_Status[get_seqnum]->storage_type == SDCARD + //HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH +/*****************************************************/ + + if(HTTPSock_Status[get_seqnum].storage_type == CODEFLASH) + { + if(HTTPSock_Status[get_seqnum].file_len) start_addr = HTTPSock_Status[get_seqnum].file_start; + read_userReg_webContent(start_addr, &buf[0], HTTPSock_Status[get_seqnum].file_offset, send_len); + } +#ifdef _USE_SDCARD_ + else if(HTTPSock_Status[get_seqnum].storage_type == SDCARD) + { + // Data read from SD Card + fr = f_read(&fs, &buf[0], send_len, (void *)&blocklen); + if(fr != FR_OK) + { + send_len = 0; +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [FatFs] Error code return: %d (File Read) / HTTP Send Failed - %s\r\n", s, fr, HTTPSock_Status[get_seqnum].file_name); +#endif + } + else + { + *(buf+send_len+1) = 0; // Insert '/0' for indicates the 'End of String' (null terminated) + } + } +#endif + +#ifdef _USE_FLASH_ + else if(HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH) + { + // Data read from external data flash memory + read_from_flashbuf(addr, &buf[0], send_len); + *(buf+send_len+1) = 0; // Insert '/0' for indicates the 'End of String' (null terminated) + } +#endif + else + { + send_len = 0; + } + // Requested content send to HTTP client +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [Send] HTTP Response body [ %ld ]byte\r\n", s, send_len); +#endif + + if(send_len) send(s, buf, send_len); + else flag_datasend_end = 1; + + if(flag_datasend_end) + { + HTTPSock_Status[get_seqnum].file_start = 0; + HTTPSock_Status[get_seqnum].file_len = 0; + HTTPSock_Status[get_seqnum].file_offset = 0; + flag_datasend_end = 0; + } + else + { + HTTPSock_Status[get_seqnum].file_offset += send_len; +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response body - offset [ %ld ]\r\n", s, HTTPSock_Status[get_seqnum].file_offset); +#endif + } + +// ## 20141219 Eric added, for 'File object structure' (fs) allocation reduced (8 -> 1) +#ifdef _USE_SDCARD_ + f_close(&fs); +#endif +// ## 20141219 added end +} + +static void send_http_response_cgi(uint8_t s, uint8_t * buf, uint8_t * http_body, uint16_t file_len) +{ + uint16_t send_len = 0; + +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response Header + Body - CGI\r\n", s); +#endif + send_len = sprintf((char *)buf, "%s%d\r\n\r\n%s", RES_CGIHEAD_OK, file_len, http_body); +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : HTTP Response Header + Body - send len [ %d ]byte\r\n", s, send_len); +#endif + + send(s, buf, send_len); +} + + +static int8_t http_disconnect(uint8_t sn) +{ + setSn_CR(sn,Sn_CR_DISCON); + /* wait to process the command... */ + while(getSn_CR(sn)); + + return SOCK_OK; +} + + +static void http_process_handler(uint8_t s, st_http_request * p_http_request) +{ + uint8_t * uri_name; + uint32_t content_addr = 0; + uint16_t content_num = 0; + uint32_t file_len = 0; + + uint8_t uri_buf[MAX_URI_SIZE]={0x00, }; + + uint16_t http_status; + int8_t get_seqnum; + uint8_t content_found; + + if((get_seqnum = getHTTPSequenceNum(s)) == -1) return; // exception handling; invalid number + + http_status = 0; + http_response = pHTTP_RX; + file_len = 0; + + //method Analyze + switch (p_http_request->METHOD) + { + case METHOD_ERR : + http_status = STATUS_BAD_REQ; + send_http_response_header(s, 0, 0, http_status); + break; + + case METHOD_HEAD : + case METHOD_GET : + get_http_uri_name(p_http_request->URI, uri_buf); + uri_name = uri_buf; + + if (!strcmp((char *)uri_name, "/")) strcpy((char *)uri_name, INITIAL_WEBPAGE); // If URI is "/", respond by index.html + if (!strcmp((char *)uri_name, "m")) strcpy((char *)uri_name, M_INITIAL_WEBPAGE); + if (!strcmp((char *)uri_name, "mobile")) strcpy((char *)uri_name, MOBILE_INITIAL_WEBPAGE); + find_http_uri_type(&p_http_request->TYPE, uri_name); // Checking requested file types (HTML, TEXT, GIF, JPEG and Etc. are included) + +#ifdef _HTTPSERVER_DEBUG_ + printf("\r\n> HTTPSocket[%d] : HTTP Method GET\r\n", s); + printf("> HTTPSocket[%d] : Request Type = %d\r\n", s, p_http_request->TYPE); + printf("> HTTPSocket[%d] : Request URI = %s\r\n", s, uri_name); +#endif + + if(p_http_request->TYPE == PTYPE_CGI) + { + content_found = http_get_cgi_handler(uri_name, pHTTP_TX, &file_len); + if(content_found && (file_len <= (DATA_BUF_SIZE-(strlen(RES_CGIHEAD_OK)+8)))) + { + send_http_response_cgi(s, http_response, pHTTP_TX, (uint16_t)file_len); + } + else + { + send_http_response_header(s, PTYPE_CGI, 0, STATUS_NOT_FOUND); + } + } + else + { + // Find the User registered index for web content + if(find_userReg_webContent(uri_buf, &content_num, &file_len)) + { + content_found = 1; // Web content found in code flash memory + content_addr = (uint32_t)content_num; + HTTPSock_Status[get_seqnum].storage_type = CODEFLASH; + } + // Not CGI request, Web content in 'SD card' or 'Data flash' requested +#ifdef _USE_SDCARD_ +#ifdef _HTTPSERVER_DEBUG_ + printf("\r\n> HTTPSocket[%d] : Searching the requested content\r\n", s); +#endif + if((fr = f_open(&fs, (const char *)uri_name, FA_READ)) == 0) + { + content_found = 1; // file open succeed + + file_len = fs.fsize; + content_addr = fs.sclust; + HTTPSock_Status[get_seqnum].storage_type = SDCARD; + } +#elif _USE_FLASH_ + else if(/* Read content from Dataflash */) + { + content_found = 1; + HTTPSock_Status[get_seqnum]->storage_type = DATAFLASH; + ; // To do + } +#endif + else + { + content_found = 0; // fail to find content + } + + if(!content_found) + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : Unknown Page Request\r\n", s); +#endif + http_status = STATUS_NOT_FOUND; + } + else + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : Find Content [%s] ok - Start [%ld] len [ %ld ]byte\r\n", s, uri_name, content_addr, file_len); +#endif + http_status = STATUS_OK; + } + + // Send HTTP header + if(http_status) + { +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : Requested content len = [ %ld ]byte\r\n", s, file_len); +#endif + send_http_response_header(s, p_http_request->TYPE, file_len, http_status); + } + + // Send HTTP body (content) + if(http_status == STATUS_OK) + { + send_http_response_body(s, uri_name, http_response, content_addr, file_len); + } + } + break; + + case METHOD_POST : + mid((char *)p_http_request->URI, "/", " HTTP", (char *)uri_buf); + uri_name = uri_buf; + find_http_uri_type(&p_http_request->TYPE, uri_name); // Check file type (HTML, TEXT, GIF, JPEG are included) + +#ifdef _HTTPSERVER_DEBUG_ + printf("\r\n> HTTPSocket[%d] : HTTP Method POST\r\n", s); + printf("> HTTPSocket[%d] : Request URI = %s ", s, uri_name); + printf("Type = %d\r\n", p_http_request->TYPE); +#endif + + if(p_http_request->TYPE == PTYPE_CGI) // HTTP POST Method; CGI Process + { + content_found = http_post_cgi_handler(uri_name, p_http_request, http_response, &file_len); +#ifdef _HTTPSERVER_DEBUG_ + printf("> HTTPSocket[%d] : [CGI: %s] / Response len [ %ld ]byte\r\n", s, content_found?"Content found":"Content not found", file_len); +#endif + if(content_found && (file_len <= (DATA_BUF_SIZE-(strlen(RES_CGIHEAD_OK)+8)))) + { + send_http_response_cgi(s, pHTTP_TX, http_response, (uint16_t)file_len); + + // Reset the H/W for apply to the change configuration information + if(content_found == HTTP_RESET) HTTPServer_ReStart(); + } + else + { + send_http_response_header(s, PTYPE_CGI, 0, STATUS_NOT_FOUND); + } + } + else // HTTP POST Method; Content not found + { + send_http_response_header(s, 0, 0, STATUS_NOT_FOUND); + } + break; + + default : + http_status = STATUS_BAD_REQ; + send_http_response_header(s, 0, 0, http_status); + break; + } +} + +void httpServer_time_handler(void) +{ + httpServer_tick_1s++; +} + +uint32_t get_httpServer_timecount(void) +{ + return httpServer_tick_1s; +} + +void reg_httpServer_webContent(uint8_t * content_name, uint8_t * content) +{ + uint16_t name_len; + uint32_t content_len; + + if(content_name == NULL || content == NULL) + { + return; + } + else if(total_content_cnt >= MAX_CONTENT_CALLBACK) + { + return; + } + + name_len = strlen((char *)content_name); + content_len = strlen((char *)content); + + web_content[total_content_cnt].content_name = malloc(name_len+1); + strcpy((char *)web_content[total_content_cnt].content_name, (const char *)content_name); + web_content[total_content_cnt].content_len = content_len; + web_content[total_content_cnt].content = content; + + total_content_cnt++; +} + +uint8_t display_reg_webContent_list(void) +{ + uint16_t i; + uint8_t ret; + + if(total_content_cnt == 0) + { + printf(">> Web content file not found\r\n"); + ret = 0; + } + else + { + printf("\r\n=== List of Web content in code flash ===\r\n"); + for(i = 0; i < total_content_cnt; i++) + { + printf(" [%d] ", i+1); + printf("%s, ", web_content[i].content_name); + printf("%ld byte, ", web_content[i].content_len); + + if(web_content[i].content_len < 30) printf("[%s]\r\n", web_content[i].content); + else printf("[ ... ]\r\n"); + } + printf("=========================================\r\n\r\n"); + ret = 1; + } + + return ret; +} + +uint8_t find_userReg_webContent(uint8_t * content_name, uint16_t * content_num, uint32_t * file_len) +{ + uint16_t i; + uint8_t ret = 0; // '0' means 'File Not Found' + + for(i = 0; i < total_content_cnt; i++) + { + if(!strcmp((char *)content_name, (char *)web_content[i].content_name)) + { + *file_len = web_content[i].content_len; + *content_num = i; + ret = 1; // If the requested content found, ret set to '1' (Found) + break; + } + } + return ret; +} + + +uint16_t read_userReg_webContent(uint16_t content_num, uint8_t * buf, uint32_t offset, uint16_t size) +{ + uint16_t ret = 0; + uint8_t * ptr; + + if(content_num > total_content_cnt) return 0; + + ptr = web_content[content_num].content; + if(offset) ptr += offset; + + strncpy((char *)buf, (char *)ptr, size); + *(buf+size) = 0; // Insert '/0' for indicates the 'End of String' (null terminated) + + ret = strlen((void *)buf); + return ret; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.h new file mode 100755 index 00000000000..dcd0b00f928 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpServer.h @@ -0,0 +1,111 @@ +/** + @file httpServer.h + @brief Define constants and functions related HTTP Web server. + */ + +#include + +#ifndef __HTTPSERVER_H__ +#define __HTTPSERVER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// HTTP Server debug message enable +#define _HTTPSERVER_DEBUG_ + +#define INITIAL_WEBPAGE "index.html" +#define M_INITIAL_WEBPAGE "m/index.html" +#define MOBILE_INITIAL_WEBPAGE "mobile/index.html" + +/* Web Server Content Storage Select */ +//#define _USE_SDCARD_ +#ifndef _USE_SDCARD_ +//#define _USE_FLASH_ +#endif + +#if !defined(_USE_SDCARD_) && !defined(_USE_FLASH_) +#define _NOTUSED_STORAGE_ +#endif + + +/* Watchdog timer */ +//#define _USE_WATCHDOG_ + +/********************************************* +* HTTP Process states list +*********************************************/ +#define STATE_HTTP_IDLE 0 /* IDLE, Waiting for data received (TCP established) */ +#define STATE_HTTP_REQ_INPROC 1 /* Received HTTP request from HTTP client */ +#define STATE_HTTP_REQ_DONE 2 /* The end of HTTP request parse */ +#define STATE_HTTP_RES_INPROC 3 /* Sending the HTTP response to HTTP client (in progress) */ +#define STATE_HTTP_RES_DONE 4 /* The end of HTTP response send (HTTP transaction ended) */ + +/********************************************* +* HTTP Simple Return Value +*********************************************/ +#define HTTP_FAILED 0 +#define HTTP_OK 1 +#define HTTP_RESET 2 + +/********************************************* +* HTTP Content NAME length +*********************************************/ +#define MAX_CONTENT_NAME_LEN 128 + +/********************************************* +* HTTP Timeout +*********************************************/ +#define HTTP_MAX_TIMEOUT_SEC 3 // Sec. + +typedef enum +{ + NONE, ///< Web storage none + CODEFLASH, ///< Code flash memory + SDCARD, ///< SD card + DATAFLASH ///< External data flash memory +}StorageType; + +typedef struct _st_http_socket +{ + uint8_t sock_status; + uint8_t file_name[MAX_CONTENT_NAME_LEN]; + uint32_t file_start; + uint32_t file_len; + uint32_t file_offset; // (start addr + sent size...) + uint8_t storage_type; // Storage type; Code flash, SDcard, Data flash ... +}st_http_socket; + +// Web content structure for file in code flash memory +#define MAX_CONTENT_CALLBACK 20 + +typedef struct _httpServer_webContent +{ + uint8_t * content_name; + uint32_t content_len; + uint8_t * content; +}httpServer_webContent; + + +void httpServer_init(uint8_t * tx_buf, uint8_t * rx_buf, uint8_t cnt, uint8_t * socklist); +void reg_httpServer_cbfunc(void(*mcu_reset)(void), void(*wdt_reset)(void)); +void httpServer_run(uint8_t seqnum); + +void reg_httpServer_webContent(uint8_t * content_name, uint8_t * content); +uint8_t find_userReg_webContent(uint8_t * content_name, uint16_t * content_num, uint32_t * file_len); +uint16_t read_userReg_webContent(uint16_t content_num, uint8_t * buf, uint32_t offset, uint16_t size); +uint8_t display_reg_webContent_list(void); + +/* + * @brief HTTP Server 1sec Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void httpServer_time_handler(void); +uint32_t get_httpServer_timecount(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.c new file mode 100755 index 00000000000..1c8cbf25c2f --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.c @@ -0,0 +1,75 @@ +/** + * @file httpUtil.c + * @brief HTTP Server Utilities + * @version 1.0 + * @date 2014/07/15 + * @par Revision + * 2014/07/15 - 1.0 Release + * @author + * \n\n @par Copyright (C) 1998 - 2014 WIZnet. All rights reserved. + */ + +#include +#include +#include +#include "httpUtil.h" + +uint8_t http_get_cgi_handler(uint8_t * uri_name, uint8_t * buf, uint32_t * file_len) +{ + uint8_t ret = HTTP_OK; + uint16_t len = 0; + + if(predefined_get_cgi_processor(uri_name, buf, &len)) + { + ; + } + else if(strcmp((const char *)uri_name, "example.cgi") == 0) + { + // To do + ; + } + else + { + // CGI file not found + ret = HTTP_FAILED; + } + + if(ret) *file_len = len; + return ret; +} + +uint8_t http_post_cgi_handler(uint8_t * uri_name, st_http_request * p_http_request, uint8_t * buf, uint32_t * file_len) +{ + uint8_t ret = HTTP_OK; + uint16_t len = 0; + uint8_t val = 0; + + if(predefined_set_cgi_processor(uri_name, p_http_request->URI, buf, &len)) + { + ; + } + else if(strcmp((const char *)uri_name, "example.cgi") == 0) + { + // To do + val = 1; + len = sprintf((char *)buf, "%d", val); + } + else + { + // CGI file not found + ret = HTTP_FAILED; + } + + if(ret) *file_len = len; + return ret; +} + +uint8_t predefined_get_cgi_processor(uint8_t * uri_name, uint8_t * buf, uint16_t * len) +{ + ; +} + +uint8_t predefined_set_cgi_processor(uint8_t * uri_name, uint8_t * uri, uint8_t * buf, uint16_t * en) +{ + ; +} diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.h new file mode 100755 index 00000000000..f2c384a995a --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Internet/httpServer/httpUtil.h @@ -0,0 +1,32 @@ +/** + * @file httpUtil.h + * @brief Header File for HTTP Server Utilities + * @version 1.0 + * @date 2014/07/15 + * @par Revision + * 2014/07/15 - 1.0 Release + * @author + * \n\n @par Copyright (C) 1998 - 2014 WIZnet. All rights reserved. + */ + +#ifndef __HTTPUTIL_H__ +#define __HTTPUTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "httpServer.h" +#include "httpParser.h" + +uint8_t http_get_cgi_handler(uint8_t * uri_name, uint8_t * buf, uint32_t * file_len); +uint8_t http_post_cgi_handler(uint8_t * uri_name, st_http_request * p_http_request, uint8_t * buf, uint32_t * file_len); + +uint8_t predefined_get_cgi_processor(uint8_t * uri_name, uint8_t * buf, uint16_t * len); +uint8_t predefined_set_cgi_processor(uint8_t * uri_name, uint8_t * uri, uint8_t * buf, uint16_t * len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/README.md b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/README.md new file mode 100755 index 00000000000..3847c3aedbf --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/README.md @@ -0,0 +1,58 @@ +# ioLibrary Driver +The ioLibrary means “Internet Offload Library” for WIZnet chip. It includes drivers and application protocols. +The driver (ioLibrary) can be used for the application design of WIZnet TCP/IP chips as [W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start), W5300, W5200, W5100 [W5100S](http://wizwiki.net/wiki/doku.php?id=products:w5100s:start). + +## ioLibrary +This driver provides the Berkeley Socket type APIs. +- Directory Structure + +![ioLibrary](http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:iolibrary_bsd.jpg "ioLibrary") + +- Ethernet : SOCKET APIs like BSD & WIZCHIP([W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start) / W5300 / W5200 / W5100 / [W5100S](http://wizwiki.net/wiki/doku.php?id=products:w5100s:start)) Driver +- Internet : + - DHCP client + - DNS client + - FTP client + - FTP server + - SNMP agent/trap + - SNTP client + - TFTP client + - HTTP server + - MQTT Client + - Others will be added. + +## How to add an ioLibrary in project through github site. + - Example, refer to https://www.youtube.com/watch?v=mt815RBGdsA + - [ioLibrary Doxygen doument](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/Socket_APIs_V3.0.3.chm) : Refer to **TODO** in this document + - Define what chip is used in **wizchip_conf.h** + - Define what Host I/F mode is used in **wizchip_conf.h** + +## Revision History + * ioLibrary V4.0.0 Released : 29, MAR, 2018 + * New features added: Library for W5100S added. + * ioLibrary V3.1.1 Released : 14, Dec, 2016 + * Bug fixed : In Socket.c Fixed MACraw & IPraw sendto function. + * ioLibrary V3.1.0 Released : 05, Dec, 2016 + * Internet application protocol add to MQTT Client (using paho MQTT 3.11) + * ioLibrary V3.0.3 Released : 03, May, 2016 + * In W5300, Fixed some compile errors in close(). Refer to M20160503 + * In close(), replace socket() with some command sequences. + * ioLibrary V3.0.2 Released : 26, April, 2016 + * Applied the erratum #1 in close() of socket.c (Refer to A20160426) + * ioLibrary V3.0.1 Released : 15, July, 2015 + * Bug fixed : In W5100, Fixed CS control problem in read/write buffer with SPI. Refer to M20150715. + * ioLibrary V3.0 Released : 01, June, 2015 + * Add to W5300 + * Typing Error in comments + * Refer to 20150601 in sources. + + * Type casting error Fixed : 09, April. 2015 + In socket.c, send() : Refer to M20150409 + + * ioLibrary V2.0 released : April. 2015 + * Added to W5100, W5200 + * Correct to some typing error + * Fixed the warning of type casting. + + * Last release : Nov. 2014 + diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/iolibrary.chm b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/iolibrary.chm new file mode 100755 index 0000000000000000000000000000000000000000..22ed4b035835460d42e84baa02c5e1fdb965850c GIT binary patch literal 4728334 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 z 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�NxHX114pJzJPD;&Y4Q{Sv8YIDq4;|BTb18 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�&h-1l`@Ge(+BT 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�t%(IF~%v* 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

q%dX&)~`UQ&PQ>nwUgWQKC*(FhckyDZ}vrx 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 EAH!wI8vp +#include +#include +#include + +#define TAG "EthSave" + +#define STORAGE_FILE_BUF_LEN 50 + +// fuction spizzhena from archive_favorites.c +static bool storage_read_line(File* file, FuriString* str_result) { + furi_string_reset(str_result); + uint8_t buffer[STORAGE_FILE_BUF_LEN]; + bool result = false; + + do { + uint16_t read_count = storage_file_read(file, buffer, STORAGE_FILE_BUF_LEN); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + for(uint16_t i = 0; i < read_count; i++) { + if(buffer[i] == '\n') { + uint32_t position = storage_file_tell(file); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + position = position - read_count + i + 1; + + storage_file_seek(file, position, true); + if(storage_file_get_error(file) != FSE_OK) { + return false; + } + + result = true; + break; + } else { + furi_string_push_back(str_result, buffer[i]); + } + } + + if(result || read_count == 0) { + break; + } + } while(true); + + return result; +} + +static bool storage_printf(File* file, const char* format, ...) { + va_list args; + va_start(args, format); + FuriString* fstring = furi_string_alloc_vprintf(format, args); + va_end(args); + if(storage_file_write(file, furi_string_get_cstr(fstring), furi_string_size(fstring)) && + storage_file_write(file, "\n", 1)) { + furi_string_free(fstring); + return true; + } + furi_string_free(fstring); + return false; +} + +static bool storage_write_config(File* file, const EthernetSaveConfig* cfg) { + storage_file_seek(file, 0, true); + storage_file_truncate(file); + + bool result = true; + result = result ? storage_printf( + file, + "mac: %02X-%02X-%02X-%02X-%02X-%02X", + cfg->mac[0], + cfg->mac[1], + cfg->mac[2], + cfg->mac[3], + cfg->mac[4], + cfg->mac[5]) : + result; + result = result ? + storage_printf( + file, "ip: %d.%d.%d.%d", cfg->ip[0], cfg->ip[1], cfg->ip[2], cfg->ip[3]) : + result; + result = + result ? + storage_printf( + file, "mask: %d.%d.%d.%d", cfg->mask[0], cfg->mask[1], cfg->mask[2], cfg->mask[3]) : + result; + result = result ? storage_printf( + file, + "gateway: %d.%d.%d.%d", + cfg->gateway[0], + cfg->gateway[1], + cfg->gateway[2], + cfg->gateway[3]) : + result; + result = + result ? + storage_printf( + file, "dns: %d.%d.%d.%d", cfg->dns[0], cfg->dns[1], cfg->dns[2], cfg->dns[3]) : + result; + result = result ? storage_printf( + file, + "ping_ip: %d.%d.%d.%d", + cfg->ping_ip[0], + cfg->ping_ip[1], + cfg->ping_ip[2], + cfg->ping_ip[3]) : + result; + return result; +} + +static void read_02X(const char* str, uint8_t* byte) { + uint8_t b[2] = {str[0], str[1]}; + + for(int i = 0; i < 2; ++i) { + if('0' <= b[i] && b[i] <= '9') { + b[i] -= '0'; + } else if('A' <= b[i] && b[i] <= 'F') { + b[i] -= 'A' - 0x0A; + } else { + b[i] = 0; + } + } + + *byte = b[1] + (b[0] << 4); +} + +static void read_ip(const char* str, uint8_t* ip) { + uint8_t ip_i = 0; + uint8_t i = 0; + uint16_t tmp = 0; + for(;;) { + if('0' <= str[i] && str[i] <= '9') { + tmp = tmp * 10 + str[i] - '0'; + } else if(str[i] == '.' || str[i] != '\n' || str[i] != '\0') { + if(tmp <= 0xFF && ip_i < 4) { + ip[ip_i] = tmp; + ip_i += 1; + tmp = 0; + } else { + break; + } + if(str[i] != '\n' && ip_i == 4) { + return; + } + } else { + break; + } + i += 1; + } + FURI_LOG_E(TAG, "cannot parse as ip string [%s]", str); + ip[0] = ip[1] = ip[2] = ip[3] = 0; + return; +} + +static void set_default_config(EthernetSaveConfig* cfg) { + const uint8_t def_mac[6] = ETHERNET_SAVE_DEFAULT_MAC; + const uint8_t def_ip[4] = ETHERNET_SAVE_DEFAULT_IP; + const uint8_t def_mask[4] = ETHERNET_SAVE_DEFAULT_MASK; + const uint8_t def_gateway[4] = ETHERNET_SAVE_DEFAULT_GATEWAY; + const uint8_t def_dns[4] = ETHERNET_SAVE_DEFAULT_DNS; + const uint8_t def_ping_ip[4] = ETHERNET_SAVE_DEFAULT_PING_IP; + + memcpy(cfg->mac, def_mac, 6); + memcpy(cfg->ip, def_ip, 4); + memcpy(cfg->mask, def_mask, 4); + memcpy(cfg->gateway, def_gateway, 4); + memcpy(cfg->dns, def_dns, 4); + memcpy(cfg->ping_ip, def_ping_ip, 4); +} + +bool storage_read_config(File* file, EthernetSaveConfig* cfg) { + FuriString* fstring = furi_string_alloc(); + + while(storage_read_line(file, fstring)) { + const char* str = furi_string_get_cstr(fstring); + if(!strncmp(str, "mac: ", 5)) { + read_02X(str + strlen("mac: "), &cfg->mac[0]); + read_02X(str + strlen("mac: XX-"), &cfg->mac[1]); + read_02X(str + strlen("mac: XX-XX-"), &cfg->mac[2]); + read_02X(str + strlen("mac: XX-XX-XX-"), &cfg->mac[3]); + read_02X(str + strlen("mac: XX-XX-XX-XX-"), &cfg->mac[4]); + read_02X(str + strlen("mac: XX-XX-XX-XX-XX-"), &cfg->mac[5]); + } else if(!strncmp(str, "ip: ", 4)) { + read_ip(str + strlen("ip: "), cfg->ip); + } else if(!strncmp(str, "mask: ", 6)) { + read_ip(str + strlen("mask: "), cfg->mask); + } else if(!strncmp(str, "gateway: ", 9)) { + read_ip(str + strlen("gateway: "), cfg->gateway); + } else if(!strncmp(str, "dns: ", 5)) { + read_ip(str + strlen("dns: "), cfg->dns); + } else if(!strncmp(str, "ping_ip: ", 9)) { + read_ip(str + strlen("ping_ip: "), cfg->ping_ip); + } + } + + furi_string_free(fstring); + return true; +} + +void ethernet_save_process_write(const EthernetSaveConfig* config) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + File* file = storage_file_alloc(storage); + + if(!storage_file_open(file, APP_DATA_PATH("config.txt"), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + FURI_LOG_E(TAG, "Failed to open file"); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + + if(!storage_write_config(file, config)) { + FURI_LOG_E(TAG, "Failed to write cpnfig to file"); + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); +} + +void ethernet_save_process_read(EthernetSaveConfig* config) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + File* file = storage_file_alloc(storage); + + if(!storage_file_open(file, APP_DATA_PATH("config.txt"), FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Failed to open file or file not exists"); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + if(!storage_read_config(file, config)) { + FURI_LOG_E(TAG, "Failed to read config from file"); + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return; + } + storage_file_close(file); + + storage_file_free(file); + + furi_record_close(RECORD_STORAGE); +} + +EthernetSaveConfig* ethernet_save_process_malloc() { + EthernetSaveConfig* config = malloc(sizeof(EthernetSaveConfig)); + + set_default_config(config); + + ethernet_save_process_read(config); + + Storage* storage = furi_record_open(RECORD_STORAGE); + + FURI_LOG_E(TAG, "ethernet_save_process_malloc"); + + File* file = storage_file_alloc(storage); + + if(!storage_file_open(file, APP_DATA_PATH("log.txt"), FSAM_WRITE, FSOM_OPEN_APPEND)) { + FURI_LOG_E(TAG, "Failed to open file or file not exists"); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + return NULL; + } + + config->log_file = file; + + return config; +} + +void ethernet_save_process_print(EthernetSaveConfig* config, const char* str) { + furi_assert(config); + DateTime datetime = {0}; + furi_hal_rtc_get_datetime(&datetime); + storage_printf( + config->log_file, + "%4d.%02d.%02d-%02d:%2d:%02d || %s", + datetime.year, + datetime.month, + datetime.day, + datetime.hour, + datetime.minute, + datetime.second, + str); +} + +void ethernet_save_process_free(EthernetSaveConfig* config) { + FURI_LOG_E(TAG, "ethernet_save_process_free"); + ethernet_save_process_write(config); + storage_file_close(config->log_file); + storage_file_free(config->log_file); + furi_record_close(RECORD_STORAGE); + free(config); +} \ No newline at end of file diff --git a/non_catalog_apps/eth_troubleshooter/eth_save_process.h b/non_catalog_apps/eth_troubleshooter/eth_save_process.h new file mode 100644 index 00000000000..ac29eb94b1a --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_save_process.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +typedef struct EthernetSaveConfig { + uint8_t mac[6]; + uint8_t ip[4]; + uint8_t mask[4]; + uint8_t gateway[4]; + uint8_t dns[4]; + uint8_t ping_ip[4]; + File* log_file; +} EthernetSaveConfig; + +#define ETHERNET_SAVE_DEFAULT_MAC \ + { 0x10, 0x08, 0xDC, 0x47, 0x47, 0x54 } +#define ETHERNET_SAVE_DEFAULT_IP \ + { 192, 168, 0, 101 } +#define ETHERNET_SAVE_DEFAULT_MASK \ + { 255, 255, 255, 0 } +#define ETHERNET_SAVE_DEFAULT_GATEWAY \ + { 192, 168, 0, 1 } +#define ETHERNET_SAVE_DEFAULT_DNS \ + { 192, 168, 0, 1 } +#define ETHERNET_SAVE_DEFAULT_PING_IP \ + { 8, 8, 8, 8 } + +EthernetSaveConfig* ethernet_save_process_malloc(); +void ethernet_save_process_free(EthernetSaveConfig* config); +void ethernet_save_process_print(EthernetSaveConfig* config, const char* str); diff --git a/non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.c b/non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.c new file mode 100644 index 00000000000..c89232779f7 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.c @@ -0,0 +1,212 @@ + +#include "eth_troubleshooter_app.h" + +#include +#include +#include +#include +#include +#include + +#include "eth_worker.h" +#include "eth_worker_i.h" +#include "eth_view_process.h" + +#define TAG "EthTroubleshooterApp" + +static void draw_process_selector(Canvas* canvas, DrawProcess selector, CursorPosition cursor) { + uint8_t y = 0; + if(selector == PROCESS_INIT) y = 11; + if(selector == PROCESS_DHCP) y = 22; + if(selector == PROCESS_STATIC) y = 34; + if(selector == PROCESS_PING) y = 44; + if(selector == PROCESS_RESET) y = 55; + + if(cursor == CURSOR_INSIDE_PROCESS) { + canvas_invert_color(canvas); + canvas_draw_line(canvas, 25, y + 1, 25, y + 7); + canvas_invert_color(canvas); + canvas_draw_line(canvas, 0, y + 1, 0, y + 7); + canvas_draw_line(canvas, 1, y, 25, y); + canvas_draw_line(canvas, 1, y + 8, 25, y + 8); + } else { + canvas_draw_line(canvas, 0, y + 1, 0, y + 7); + canvas_draw_line(canvas, 23, y + 1, 23, y + 7); + canvas_draw_line(canvas, 1, y, 22, y); + canvas_draw_line(canvas, 1, y + 8, 22, y + 8); + } + + if(cursor == CURSOR_CLICK_PROCESS) { + canvas_draw_box(canvas, 1, y, 22, 9); + } +} + +static void draw_battery_cunsumption(Canvas* canvas, double cons) { + FuriString* string = furi_string_alloc_set("aaaaaaaa"); + if(cons >= 0) { + furi_string_printf(string, "--"); + } else if(cons < -1) { + furi_string_printf(string, "%1.1fk", -cons); + } else { + furi_string_printf(string, "%3.f", -(cons * 1000)); + } + + canvas_draw_str(canvas, 112, 7, furi_string_get_cstr(string)); + furi_string_free(string); +} + +static void eth_troubleshooter_app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + EthTroubleshooterApp* app = ctx; + + canvas_clear(canvas); + + DrawProcess process = app->draw_process; + CursorPosition cursor = app->cursor_position; + float consumption = app->info.current_gauge; + + canvas_set_font(canvas, FontSecondary); + + if(cursor == CURSOR_EXIT_ICON) { + canvas_draw_icon(canvas, 0, 0, &I_exit_128x64px); + } else { + canvas_draw_icon(canvas, 0, 0, &I_main_128x64px); + draw_process_selector(canvas, process, cursor); + draw_battery_cunsumption(canvas, (double)consumption); + ethernet_view_process_draw(app->eth_worker->active_process, canvas); + if(furi_hal_power_is_otg_enabled()) { + canvas_draw_str(canvas, 22, 6, "+"); + } else { + canvas_draw_str(canvas, 22, 6, "-"); + } + } +} + +static void eth_troubleshooter_battery_info_update_model(void* ctx) { + furi_assert(ctx); + EthTroubleshooterApp* app = ctx; + power_get_info(app->power, &app->info); +} + +static void eth_troubleshooter_app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +EthTroubleshooterApp* eth_troubleshooter_app_alloc() { + EthTroubleshooterApp* app = malloc(sizeof(EthTroubleshooterApp)); + + app->view_port = view_port_alloc(); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + app->eth_worker = eth_worker_alloc(); + + view_port_draw_callback_set(app->view_port, eth_troubleshooter_app_draw_callback, app); + view_port_input_callback_set(app->view_port, eth_troubleshooter_app_input_callback, app->event_queue); + + app->gui = furi_record_open(RECORD_GUI); + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + + app->notifications = furi_record_open(RECORD_NOTIFICATION); + + app->power = furi_record_open(RECORD_POWER); + + return app; +} + +void eth_troubleshooter_app_free(EthTroubleshooterApp* app) { + furi_assert(app); + + view_port_enabled_set(app->view_port, false); + gui_remove_view_port(app->gui, app->view_port); + view_port_free(app->view_port); + + furi_message_queue_free(app->event_queue); + eth_worker_free(app->eth_worker); + + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_POWER); +} + +void eth_troubleshooter_app_key_handler(EthTroubleshooterApp* app, InputKey key) { + if(app->cursor_position == CURSOR_CHOOSE_PROCESS) { + if(key == InputKeyUp || key == InputKeyDown) { + app->draw_process = + (app->draw_process + PROCESS_RESET + (key == InputKeyDown ? 2 : 0)) % + (PROCESS_RESET + 1); + eth_worker_set_active_process(app->eth_worker, (EthWorkerProcess)app->draw_process); + } else if(key == InputKeyOk) { + ethernet_view_process_move(app->eth_worker->active_process, 0); + app->cursor_position = CURSOR_CLICK_PROCESS; + view_port_update(app->view_port); + furi_delay_ms(150); + eth_run(app->eth_worker, (EthWorkerProcess)app->draw_process); + app->cursor_position = CURSOR_CHOOSE_PROCESS; + } else if(key == InputKeyRight) { + eth_worker_set_active_process(app->eth_worker, (EthWorkerProcess)app->draw_process); + app->cursor_position = CURSOR_INSIDE_PROCESS; + } else if(key == InputKeyBack) { + app->cursor_position = CURSOR_EXIT_ICON; + } + } else if(app->cursor_position == CURSOR_INSIDE_PROCESS) { + if(app->eth_worker->active_process->editing) { + ethernet_view_process_keyevent(app->eth_worker->active_process, key); + } else if(key == InputKeyLeft) { + app->eth_worker->active_process->editing = 0; + app->cursor_position = CURSOR_CHOOSE_PROCESS; + } else if(key == InputKeyBack) { + ethernet_view_process_move(app->eth_worker->active_process, 0); + app->eth_worker->active_process->editing = 0; + app->cursor_position = CURSOR_CHOOSE_PROCESS; + } else if(key == InputKeyUp) { + ethernet_view_process_move(app->eth_worker->active_process, -1); + } else if(key == InputKeyDown) { + ethernet_view_process_move(app->eth_worker->active_process, 1); + } else if(key == InputKeyOk || key == InputKeyRight) { + app->eth_worker->active_process->editing = 1; + } + } else if(app->cursor_position == CURSOR_EXIT_ICON) { + if(key == InputKeyBack) { + app->cursor_position = CURSOR_EXIT; + } else if(key == InputKeyOk) { + app->cursor_position = CURSOR_CHOOSE_PROCESS; + } + } +} + +int32_t eth_troubleshooter_app(void* p) { + UNUSED(p); + EthTroubleshooterApp* app = eth_troubleshooter_app_alloc(); + + InputEvent event; + uint8_t long_press = 0; + InputKey long_press_key = 0; + + while(1) { + eth_troubleshooter_battery_info_update_model(app); + if(furi_message_queue_get(app->event_queue, &event, 200) == FuriStatusOk) { + if(event.type == InputTypePress) { + eth_troubleshooter_app_key_handler(app, event.key); + } else if(event.type == InputTypeLong) { + long_press = 1; + long_press_key = event.key; + } else if(event.type == InputTypeRelease) { + long_press = 0; + long_press_key = 0; + } + } + if(long_press && long_press_key != InputKeyBack) { + eth_troubleshooter_app_key_handler(app, long_press_key); + } + if(app->cursor_position == CURSOR_EXIT) { + eth_run(app->eth_worker, EthWorkerProcessExit); + break; + } + view_port_update(app->view_port); + } + + eth_troubleshooter_app_free(app); + return 0; +} diff --git a/non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.h b/non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.h new file mode 100644 index 00000000000..cf649f926c5 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_troubleshooter_app.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include + +#include "eth_worker.h" +#include "eth_troubleshooter_icons.h" + +typedef enum { + DRAW_ALL, + DRAW_ONLY_TEXT, + DRAW_ONLY_PICTURES, + TOTAL_DRAW_MODES = 3, +} DrawMode; + +typedef enum { + PROCESS_INIT, + PROCESS_DHCP, + PROCESS_STATIC, + PROCESS_PING, + PROCESS_RESET, +} DrawProcess; + +typedef enum { + CURSOR_CHOOSE_PROCESS, + CURSOR_CLICK_PROCESS, + CURSOR_INSIDE_PROCESS, + CURSOR_EXIT_ICON, + CURSOR_EXIT, +} CursorPosition; + +struct EthTroubleshooterApp { + Gui* gui; + ViewPort* view_port; + FuriMessageQueue* event_queue; + NotificationApp* notifications; + EthWorker* eth_worker; + + Power* power; + PowerInfo info; + + DrawMode draw_mode; + DrawProcess draw_process; + CursorPosition cursor_position; +}; + +typedef struct EthTroubleshooterApp EthTroubleshooterApp; diff --git a/non_catalog_apps/eth_troubleshooter/eth_view_process.c b/non_catalog_apps/eth_troubleshooter/eth_view_process.c new file mode 100644 index 00000000000..749a870bbb0 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_view_process.c @@ -0,0 +1,422 @@ +#include "eth_view_process.h" + +#include "eth_worker.h" +#include "eth_worker_i.h" +#include "eth_troubleshooter_icons.h" + +#include + +#include +#include +#include +#include + +#define TAG "EthView" + +EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type, EthernetSaveConfig* config) { + EthViewProcess* evp = malloc(sizeof(EthViewProcess)); + evp->type = type; + evp->autofill = 1; + evp->carriage = 0; + evp->position = 0; + evp->x = 27; + evp->y = 6; + evp->strings_cnt = 10; + + if(type == EthWorkerProcessInit) { + evp->y += 22; + EthViewDrawInit* init = malloc(sizeof(EthViewDrawInit)); + memset(init, 0, sizeof(EthViewDrawInit)); + init->mac = (uint8_t*)config->mac; + evp->draw_struct = init; + } else if(type == EthWorkerProcessStatic) { + evp->y += 22; + EthViewDrawStatic* stat = malloc(sizeof(EthViewDrawStatic)); + memset(stat, 0, sizeof(EthViewDrawStatic)); + stat->ip = config->ip; + stat->mask = config->mask; + stat->gateway = config->gateway; + stat->dns = config->dns; + evp->draw_struct = stat; + evp->strings_cnt = 20; + } else if(type == EthWorkerProcessDHCP) { + evp->strings_cnt = 20; + } else if(type == EthWorkerProcessPing) { + evp->y += 11; + EthViewDrawPing* ping = malloc(sizeof(EthViewDrawPing)); + memset(ping, 0, sizeof(EthViewDrawPing)); + ping->ip = config->ping_ip; + evp->draw_struct = ping; + evp->strings_cnt = 20; + } + + evp->fifo = malloc(sizeof(EthViewProcessLine) * evp->strings_cnt); + return evp; +} + +void ethernet_view_process_free(EthViewProcess* evp) { + free(evp->fifo); + if(evp->type == EthWorkerProcessInit || evp->type == EthWorkerProcessStatic || + evp->type == EthWorkerProcessPing) { + free(evp->draw_struct); + } + free(evp); +} + +static void draw_hex_digit(Canvas* canvas, uint8_t x, uint8_t y, uint8_t digit) { + char digit_str[] = "0"; + if(digit < 0xA) { + digit_str[0] += digit; + } else if(digit < 0x10) { + digit_str[0] = 'A'; + digit_str[0] += digit - 0xA; + } else { + return; + } + + canvas_draw_str(canvas, x, y, digit_str); +} + +static void draw_dec_number(Canvas* canvas, uint8_t x, uint8_t y, uint8_t num) { + char num_str[] = "0"; + { + num_str[0] = '0' + num % 10; + canvas_draw_str(canvas, x + 6 + 6, y, num_str); + } + if(num >= 10) { + num_str[0] = '0' + num / 10 - (num / 100) * 10; + canvas_draw_str(canvas, x + 6, y, num_str); + } + if(num >= 100) { + num_str[0] = '0' + num / 100; + canvas_draw_str(canvas, x, y, num_str); + } +} + +static void draw_static_mode(Canvas* canvas, uint8_t mode) { + const uint8_t s1 = 13; + const uint8_t s2 = 31; + const uint8_t s3 = 19; + const uint8_t s4 = 21; + const uint8_t s = 35; + const uint8_t h = 7; + const uint8_t y = 10; + const uint8_t y1 = 15; + + if(mode == EthViewDrawStaticModeIp) { + canvas_invert_color(canvas); + canvas_draw_box(canvas, s, y, s1, h); + canvas_invert_color(canvas); + canvas_draw_str(canvas, 38, y1, "ip"); + } + if(mode == EthViewDrawStaticModeMask) { + canvas_invert_color(canvas); + canvas_draw_box(canvas, s + s1, y, s2, h); + canvas_invert_color(canvas); + canvas_draw_str(canvas, 53, y1, "mask"); + } + if(mode == EthViewDrawStaticModeGateway) { + canvas_invert_color(canvas); + canvas_draw_box(canvas, s + s1 + s2, y, s3, h); + canvas_invert_color(canvas); + canvas_draw_str(canvas, 82, y1, "gw"); + } + if(mode == EthViewDrawStaticModeDNS) { + canvas_invert_color(canvas); + canvas_draw_box(canvas, s + s1 + s2 + s3, y, s4, h); + canvas_invert_color(canvas); + canvas_draw_str(canvas, 102, y1, "dns"); + } +} + +static uint8_t* draw_static_get_current_adress(EthViewDrawStatic* evds) { + furi_assert(evds); + if(evds->current_mode == EthViewDrawStaticModeIp) return evds->ip; + if(evds->current_mode == EthViewDrawStaticModeMask) return evds->mask; + if(evds->current_mode == EthViewDrawStaticModeGateway) return evds->gateway; + if(evds->current_mode == EthViewDrawStaticModeDNS) return evds->dns; + return evds->ip; +} + +void ethernet_view_process_draw(EthViewProcess* process, Canvas* canvas) { + furi_assert(canvas); + furi_assert(process); + canvas_set_font(canvas, FontSecondary); + + const uint8_t x = process->x; + const uint8_t y = process->y; + const uint8_t str_height = 11; + const uint8_t str_count = (64 - y) / str_height; + uint8_t carriage = process->carriage; + uint8_t position = process->position; + + if(process->autofill) { + position = (carriage + process->strings_cnt - str_count) % process->strings_cnt; + process->position = position; + } + + for(uint8_t i = 0; i < str_count; ++i) { + uint8_t y1 = y + (i + 1) * str_height; + canvas_draw_str(canvas, x, y1, process->fifo[(position + i) % process->strings_cnt].data); + } + + if(process->type == EthWorkerProcessInit) { + uint8_t editing = process->editing; + canvas_draw_icon(canvas, 27, 10, &I_init_100x19px); + uint8_t octet = ((EthViewDrawInit*)process->draw_struct)->current_octet; + uint8_t* mac = ((EthViewDrawInit*)process->draw_struct)->mac; + for(uint8_t i = 0; i < 6; ++i) { + uint8_t x1 = 29 + i * 17; + uint8_t x2 = x1 + 6; + draw_hex_digit(canvas, x1, 25, (mac[i] & 0xF0) >> 4); + draw_hex_digit(canvas, x2, 25, (mac[i] & 0x0F)); + if(editing && (octet / 2 == i)) { + uint8_t x = octet & 1 ? x2 : x1; + canvas_draw_line(canvas, x, 26, x + 4, 26); + canvas_draw_line(canvas, x, 27, x + 4, 27); + } + } + } else if(process->type == EthWorkerProcessStatic) { + canvas_draw_frame(canvas, 31, 18, 21, 13); + canvas_draw_frame(canvas, 55, 18, 21, 13); + canvas_draw_frame(canvas, 79, 18, 21, 13); + canvas_draw_frame(canvas, 103, 18, 21, 13); + canvas_draw_box(canvas, 29, 10, 97, 7); + uint8_t mode = ((EthViewDrawStatic*)process->draw_struct)->current_mode; + uint8_t current_digit = ((EthViewDrawStatic*)process->draw_struct)->current_digit; + uint8_t* adress = draw_static_get_current_adress((EthViewDrawStatic*)process->draw_struct); + uint8_t editing = ((EthViewDrawStatic*)process->draw_struct)->editing; + for(uint8_t i = 0; i < 4; ++i) { + if(i == mode && process->editing) { + draw_static_mode(canvas, mode); + } else { + canvas_invert_color(canvas); + draw_static_mode(canvas, i); + canvas_invert_color(canvas); + } + } + for(uint8_t i = 0; i < 4; ++i) { + uint8_t x = 33 + i * 24; + draw_dec_number(canvas, x, 27, adress[i]); + if(editing && (current_digit / 3 == i)) { + uint8_t x1 = x + 6 * (current_digit % 3); + canvas_draw_line(canvas, x1, 28, x1 + 4, 28); + canvas_draw_line(canvas, x1, 29, x1 + 4, 29); + } + } + } else if(process->type == EthWorkerProcessPing) { + canvas_draw_frame(canvas, 35, 8, 21, 13); + canvas_draw_frame(canvas, 59, 8, 21, 13); + canvas_draw_frame(canvas, 83, 8, 21, 13); + canvas_draw_frame(canvas, 107, 8, 21, 13); + uint8_t current_digit = ((EthViewDrawPing*)process->draw_struct)->current_digit; + uint8_t* adress = ((EthViewDrawPing*)process->draw_struct)->ip; + for(uint8_t i = 0; i < 4; ++i) { + uint8_t x = 37 + i * 24; + draw_dec_number(canvas, x, 17, adress[i]); + if(process->editing && (current_digit / 3 == i)) { + uint8_t x1 = x + 6 * (current_digit % 3); + canvas_draw_line(canvas, x1, 18, x1 + 4, 18); + canvas_draw_line(canvas, x1, 19, x1 + 4, 19); + } + } + } else if(process->type == EthWorkerProcessReset) { + process->editing = 0; + } +} + +static void mac_change_hex_digit(uint8_t* mac, uint8_t octet, int8_t diff) { + uint8_t digit = (octet & 1) ? (mac[octet / 2] & 0x0F) : (mac[octet / 2] >> 4); + digit = (digit + diff) & 0xF; + if(octet & 1) { + mac[octet / 2] = (mac[octet / 2] & 0xF0) | digit; + } else { + mac[octet / 2] = (digit << 4) | (mac[octet / 2] & 0x0F); + } +} + +static void adress_change_dec_digit(uint8_t* ip, uint8_t digit, int8_t diff) { + { + uint8_t k = 0; + k = (digit % 3 == 0) ? 100 : k; + k = (digit % 3 == 1) ? 10 : k; + k = (digit % 3 == 2) ? 1 : k; + diff *= k; + } + { + int16_t ip1 = ip[digit / 3]; + if(diff > 0 && ((0x100 - ip1) > diff)) ip1 += diff; + if(diff < 0 && (ip1 + diff >= 0)) ip1 += diff; + ip[digit / 3] = ip1; + } +} + +void ethernet_view_process_keyevent(EthViewProcess* process, InputKey key) { + furi_assert(process); + if(process->type == EthWorkerProcessInit) { + uint8_t octet = ((EthViewDrawInit*)process->draw_struct)->current_octet; + uint8_t* mac = ((EthViewDrawInit*)process->draw_struct)->mac; + if(key == InputKeyLeft) { + if(octet > 0) octet -= 1; + } else if(key == InputKeyRight) { + if(octet < 11) octet += 1; + } else if(key == InputKeyUp) { + mac_change_hex_digit(mac, octet, 1); + } else if(key == InputKeyDown) { + mac_change_hex_digit(mac, octet, -1); + } else if(key == InputKeyOk || key == InputKeyBack) { + process->editing = 0; + } + ((EthViewDrawInit*)process->draw_struct)->current_octet = octet; + } else if(process->type == EthWorkerProcessDHCP) { + process->editing = 0; + if(key == InputKeyUp || key == InputKeyDown) { + ethernet_view_process_move(process, (key == InputKeyDown) ? 1 : -1); + } + } else if(process->type == EthWorkerProcessStatic) { + uint8_t digit = ((EthViewDrawStatic*)process->draw_struct)->current_digit; + uint8_t mode = ((EthViewDrawStatic*)process->draw_struct)->current_mode; + uint8_t* adress = draw_static_get_current_adress((EthViewDrawStatic*)process->draw_struct); + uint8_t editing = ((EthViewDrawStatic*)process->draw_struct)->editing; + if(editing) { + if(key == InputKeyLeft) { + if(digit > 0) { + digit -= 1; + } else { + ((EthViewDrawStatic*)process->draw_struct)->editing = 0; + } + } else if(key == InputKeyRight) { + if(digit < 11) digit += 1; + } else if(key == InputKeyUp) { + adress_change_dec_digit(adress, digit, 1); + } else if(key == InputKeyDown) { + adress_change_dec_digit(adress, digit, -1); + } else if(key == InputKeyOk || key == InputKeyBack) { + ((EthViewDrawStatic*)process->draw_struct)->editing = 0; + } + } else { + if(key == InputKeyLeft) { + if(mode > 0) { + mode -= 1; + } else { + process->editing = 0; + } + } else if(key == InputKeyRight) { + if(mode < 3) { + mode += 1; + } + } else if(key == InputKeyUp || key == InputKeyDown) { + ethernet_view_process_move(process, (key == InputKeyDown) ? 1 : -1); + } else if(key == InputKeyOk) { + ((EthViewDrawStatic*)process->draw_struct)->editing = 1; + } else if(key == InputKeyBack) { + mode = 0; + process->editing = 0; + } + } + ((EthViewDrawStatic*)process->draw_struct)->current_mode = mode; + ((EthViewDrawStatic*)process->draw_struct)->current_digit = digit; + } else if(process->type == EthWorkerProcessPing) { + uint8_t digit = ((EthViewDrawPing*)process->draw_struct)->current_digit; + uint8_t* adress = ((EthViewDrawPing*)process->draw_struct)->ip; + if(key == InputKeyLeft) { + if(digit > 0) { + digit -= 1; + } else { + process->editing = 0; + } + } else if(key == InputKeyRight) { + if(digit < 11) digit += 1; + } else if(key == InputKeyUp) { + adress_change_dec_digit(adress, digit, 1); + } else if(key == InputKeyDown) { + adress_change_dec_digit(adress, digit, -1); + } else if(key == InputKeyOk || key == InputKeyBack) { + process->editing = 0; + } + ((EthViewDrawPing*)process->draw_struct)->current_digit = digit; + } else { + if(key == InputKeyBack || key == InputKeyLeft) { + process->editing = 0; + } + } +} + +void ethernet_view_process_move(EthViewProcess* process, int8_t shift) { + furi_assert(process); + uint8_t position = process->position; + if(shift <= -process->strings_cnt) { + position = 0; + } else if(shift >= process->strings_cnt) { + position = process->carriage - 1; + } else { + position = (position + (process->strings_cnt + shift)) % process->strings_cnt; + } + process->position = position; + process->autofill = !shift; +} + +void ethernet_view_process_autofill(EthViewProcess* process, uint8_t state) { + furi_assert(process); + process->autofill = state; +} + +static uint16_t get_string_with_width(const char* str, uint16_t width) { + u8g2_t canvas_memory; + Canvas* canvas = (Canvas*)&canvas_memory; // grazniy hack + canvas_set_font(canvas, FontSecondary); + + uint8_t end = 0; + char copy[SCREEN_SYMBOLS_WIDTH + 1] = {0}; + + for(;;) { + if(str[end] == '\n') { + break; + } + if(str[end] == '\0') { + break; + } + if(end == SCREEN_SYMBOLS_WIDTH) { + break; + } + copy[end] = str[end]; + if(canvas_string_width(canvas, copy) > width) { + end -= 1; + break; + } + end += 1; + } + + return end; +} + +void evp_printf(EthViewProcess* process, const char* format, ...) { + va_list args; + va_start(args, format); + FuriString* fstring = furi_string_alloc_vprintf(format, args); + va_end(args); + ethernet_view_process_print(process, furi_string_get_cstr(fstring)); + furi_string_free(fstring); +} + +void ethernet_view_process_print(EthViewProcess* process, const char* str) { + furi_assert(process); + + uint16_t max_width = 126 - process->x; + uint16_t ptr = 0; + uint16_t len = strlen(str); + + while(ptr < len) { + if(str[ptr] == '\n') ptr += 1; + uint16_t start = ptr; + ptr += get_string_with_width(str + ptr, max_width); + uint8_t carriage = process->carriage; + uint8_t carriage1 = (carriage + 1) % process->strings_cnt; + uint8_t carriage2 = (carriage + 2) % process->strings_cnt; + memset(process->fifo[carriage].data, 0, SCREEN_SYMBOLS_WIDTH); + memset(process->fifo[carriage1].data, 0, SCREEN_SYMBOLS_WIDTH); + memset(process->fifo[carriage2].data, 0, SCREEN_SYMBOLS_WIDTH); + memcpy(process->fifo[carriage].data, str + start, ptr - start); + process->carriage = carriage1; + } +} diff --git a/non_catalog_apps/eth_troubleshooter/eth_view_process.h b/non_catalog_apps/eth_troubleshooter/eth_view_process.h new file mode 100644 index 00000000000..3d2cdbcf8a8 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_view_process.h @@ -0,0 +1,59 @@ +#pragma once + +#include "eth_worker.h" +#include "eth_save_process.h" +#include + +#define SCREEN_SYMBOLS_WIDTH 30 + +EthViewProcess* ethernet_view_process_malloc(EthWorkerProcess type, EthernetSaveConfig* config); +void ethernet_view_process_free(EthViewProcess* evp); + +void ethernet_view_process_draw(EthViewProcess* process, Canvas* canvas); +void ethernet_view_process_keyevent(EthViewProcess* process, InputKey key); +void ethernet_view_process_print(EthViewProcess* process, const char* str); +void ethernet_view_process_move(EthViewProcess* process, int8_t shift); +void evp_printf(EthViewProcess* process, const char* format, ...); + +typedef struct EthViewProcessLine { + char data[SCREEN_SYMBOLS_WIDTH]; +} EthViewProcessLine; + +struct EthViewProcess { + EthViewProcessLine* fifo; + EthWorkerProcess type; + uint8_t strings_cnt; + uint8_t carriage; + uint8_t position; + uint8_t autofill; + uint8_t editing; + uint8_t x; + uint8_t y; + void* draw_struct; +}; + +typedef struct EthViewDrawInit { + uint8_t* mac; + uint8_t current_octet; +} EthViewDrawInit; + +typedef enum { + EthViewDrawStaticModeIp, + EthViewDrawStaticModeMask, + EthViewDrawStaticModeGateway, + EthViewDrawStaticModeDNS +} EthViewDrawStaticMode; +typedef struct EthViewDrawStatic { + EthViewDrawStaticMode current_mode; + uint8_t* ip; + uint8_t* mask; + uint8_t* gateway; + uint8_t* dns; + uint8_t current_digit; + uint8_t editing; +} EthViewDrawStatic; + +typedef struct EthViewDrawPing { + uint8_t current_digit; + uint8_t* ip; +} EthViewDrawPing; \ No newline at end of file diff --git a/non_catalog_apps/eth_troubleshooter/eth_worker.c b/non_catalog_apps/eth_troubleshooter/eth_worker.c new file mode 100644 index 00000000000..6496a69c172 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_worker.c @@ -0,0 +1,582 @@ +#include "eth_worker_i.h" +#include "eth_worker.h" +#include "eth_save_process.h" + +#include +#include "dhcp.h" +#include "socket.h" +#include + +#define TAG "EthWorker" + +static EthWorker* static_worker = NULL; + +EthWorker* eth_worker_alloc() { + EthWorker* worker = malloc(sizeof(EthWorker)); + + worker->config = ethernet_save_process_malloc(); + furi_assert(worker->config); + + worker->init_process = ethernet_view_process_malloc(EthWorkerProcessInit, worker->config); + worker->dhcp_process = ethernet_view_process_malloc(EthWorkerProcessDHCP, worker->config); + worker->stat_process = ethernet_view_process_malloc(EthWorkerProcessStatic, worker->config); + worker->ping_process = ethernet_view_process_malloc(EthWorkerProcessPing, worker->config); + worker->reset_process = ethernet_view_process_malloc(EthWorkerProcessReset, worker->config); + worker->active_process = worker->init_process; + + static_worker = worker; + + worker->state = worker->next_state = EthWorkerStateNotAllocated; + + worker->timer = furi_timer_alloc(dhcp_timer_callback, FuriTimerTypePeriodic, NULL); + furi_timer_start(worker->timer, 1000); + + eth_log(EthWorkerProcessReset, "Finik Ethernet [START]"); + + return worker; +} + +void eth_worker_free(EthWorker* worker) { + eth_log(EthWorkerProcessReset, "Finik Ethernet [STOP]"); + + eth_run(worker, EthWorkerProcessExit); + + static_worker = NULL; + furi_assert(worker); + + ethernet_view_process_free(worker->init_process); + ethernet_view_process_free(worker->dhcp_process); + ethernet_view_process_free(worker->stat_process); + ethernet_view_process_free(worker->ping_process); + ethernet_view_process_free(worker->reset_process); + ethernet_save_process_free(worker->config); + + furi_timer_stop(worker->timer); + furi_timer_free(worker->timer); + + free(worker); +} + +void eth_worker_change_state(EthWorker* worker, EthWorkerState state) { + furi_assert(worker); + worker->state = state; +} + +void eth_worker_set_active_process(EthWorker* worker, EthWorkerProcess state) { + furi_assert(worker); + switch(state) { + case EthWorkerProcessInit: + worker->active_process = worker->init_process; + break; + case EthWorkerProcessDHCP: + worker->active_process = worker->dhcp_process; + break; + case EthWorkerProcessStatic: + worker->active_process = worker->stat_process; + break; + case EthWorkerProcessPing: + worker->active_process = worker->ping_process; + break; + case EthWorkerProcessReset: + worker->active_process = worker->reset_process; + break; + default: + break; + } +} + +void eth_worker_log(EthWorker* worker, const char* str) { + furi_assert(worker); + ethernet_save_process_print(worker->config, str); +} + +static EthViewProcess* get_process(EthWorker* worker, EthWorkerProcess process) { + furi_assert(worker); + switch(process) { + case EthWorkerProcessInit: + return worker->init_process; + case EthWorkerProcessDHCP: + return worker->dhcp_process; + case EthWorkerProcessStatic: + return worker->stat_process; + case EthWorkerProcessPing: + return worker->ping_process; + case EthWorkerProcessReset: + return worker->reset_process; + case EthWorkerProcessActive: + return worker->active_process; + default: + return NULL; + } +} + +void eth_log(EthWorkerProcess process, const char* format, ...) { + furi_assert(static_worker); + va_list args; + va_start(args, format); + FuriString* fstring = furi_string_alloc_vprintf(format, args); + const char* string = furi_string_get_cstr(fstring); + va_end(args); + + FURI_LOG_I(TAG, "%s", string); + ethernet_save_process_print(static_worker->config, string); + ethernet_view_process_print(get_process(static_worker, process), string); + if(process != EthWorkerProcessReset) { + ethernet_view_process_print(get_process(static_worker, EthWorkerProcessReset), string); + } + furi_string_free(fstring); +} + +void eth_printf(const char* format, ...) { + furi_assert(static_worker); + va_list args; + va_start(args, format); + FuriString* fstring = furi_string_alloc_vprintf(format, args); + const char* string = furi_string_get_cstr(fstring); + va_end(args); + + FURI_LOG_I(TAG, "%s", string); + //ehternet_save_process_print(static_worker->config, string); + furi_string_free(fstring); +} + +static void eth_set_force_state(EthWorkerState state) { + EthWorker* worker = static_worker; + furi_assert(worker); + worker->next_state = EthWorkerStateDefaultNext; + if(worker->state == EthWorkerStateNotAllocated) { + return; + } + worker->state = state; +} + +void eth_set_state() { +} + +void eth_set_next_state(EthWorkerState state) { + EthWorker* worker = static_worker; + furi_assert(worker); + if(state == EthWorkerStateReset || state == EthWorkerStateStop) { + eth_set_force_state(state); + return; + } + if(worker->state == EthWorkerStateNotInited) { + if(state == EthWorkerStateInit) { + worker->next_state = state; + } + } + if(worker->state == EthWorkerStateInited) { + if(state == EthWorkerStateDHCP || state == EthWorkerStateStaticIp) { + worker->next_state = state; + } + } + if(worker->state == EthWorkerStateOnline) { + if(state == EthWorkerStatePing) { + worker->next_state = state; + } + } +} + +void eth_run(EthWorker* worker, EthWorkerProcess process) { + furi_assert(worker); + switch(process) { + case EthWorkerProcessInit: + if(worker->state == EthWorkerStateNotAllocated) { + worker->thread = furi_thread_alloc(); + furi_thread_set_name(worker->thread, "EthWorker"); + furi_thread_set_stack_size(worker->thread, 8192); + furi_thread_set_callback(worker->thread, eth_worker_task); + furi_thread_set_context(worker->thread, worker); + worker->state = EthWorkerStateNotInited; + furi_thread_start(worker->thread); + } + eth_set_next_state(EthWorkerStateInit); + break; + case EthWorkerProcessDHCP: + eth_set_next_state(EthWorkerStateDHCP); + break; + case EthWorkerProcessStatic: + eth_set_next_state(EthWorkerStateStaticIp); + break; + case EthWorkerProcessPing: + eth_set_next_state(EthWorkerStatePing); + break; + case EthWorkerProcessReset: + eth_set_next_state(EthWorkerStateReset); + eth_log(EthWorkerProcessInit, "reset module"); + eth_log(EthWorkerProcessDHCP, "reset module"); + eth_log(EthWorkerProcessStatic, "reset module"); + eth_log(EthWorkerProcessPing, "reset module"); + eth_log(EthWorkerProcessReset, "reset module"); + break; + case EthWorkerProcessExit: + if(worker->state != EthWorkerStateNotAllocated) { + eth_set_force_state(EthWorkerStateStop); + furi_thread_join(worker->thread); + furi_thread_free(worker->thread); + worker->state = EthWorkerStateNotAllocated; + } + break; + default: + break; + } +} + +/************************** Ethernet Worker Thread *****************************/ + +static uint8_t ip_assigned = 0; +static GpioPin cspin = {.port = GPIOA, .pin = LL_GPIO_PIN_4}; +static GpioPin resetpin = {.port = GPIOC, .pin = LL_GPIO_PIN_3}; + +static void W5500_Select(void) { + furi_hal_gpio_write(&cspin, false); +} + +static void W5500_Unselect(void) { + furi_hal_gpio_write(&cspin, true); +} + +static void Callback_IPAssigned(void) { + eth_log( + EthWorkerProcessDHCP, "Callback: IP assigned! Leased time: %d sec", getDHCPLeasetime()); + ip_assigned = 1; +} + +static void Callback_IPConflict(void) { + eth_log(EthWorkerProcessDHCP, "Callback: IP conflict!"); +} + +static void W5500_ReadBuff(uint8_t* buff, uint16_t len) { + furi_hal_spi_bus_rx(&furi_hal_spi_bus_handle_external, buff, len, 1000); +} + +static void W5500_WriteBuff(uint8_t* buff, uint16_t len) { + furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_external, buff, len, 1000); +} + +static uint8_t W5500_ReadByte(void) { + uint8_t byte; + W5500_ReadBuff(&byte, sizeof(byte)); + return byte; +} + +static void W5500_WriteByte(uint8_t byte) { + W5500_WriteBuff(&byte, sizeof(byte)); +} + +static wiz_NetInfo gWIZNETINFO; +void update_WIZNETINFO(uint8_t is_dhcp) { + furi_assert(static_worker); + memcpy(gWIZNETINFO.mac, static_worker->config->mac, 6); + if(is_dhcp) { + memset(gWIZNETINFO.ip, 0, 4); + memset(gWIZNETINFO.sn, 0, 4); + memset(gWIZNETINFO.gw, 0, 4); + memset(gWIZNETINFO.dns, 0, 4); + gWIZNETINFO.dhcp = NETINFO_DHCP; + } else { + memcpy(gWIZNETINFO.ip, static_worker->config->ip, 4); + memcpy(gWIZNETINFO.sn, static_worker->config->mask, 4); + memcpy(gWIZNETINFO.gw, static_worker->config->gateway, 4); + memcpy(gWIZNETINFO.dns, static_worker->config->dns, 4); + gWIZNETINFO.dhcp = NETINFO_STATIC; + } +} + +int check_phylink(EthWorker* worker, EthWorkerState state, EthWorkerProcess proc, int timeout) { + uint32_t start_time = furi_get_tick(); + uint32_t last_log_time = start_time; + eth_log(proc, "phy link check 0"); + for(;;) { + if(furi_get_tick() > start_time + timeout) { + eth_log(proc, "phy link timeout"); + break; + } + if(worker->state != state) { + eth_log(proc, "state changed"); + break; + } + uint8_t link = PHY_LINK_OFF; + if(ctlwizchip(CW_GET_PHYLINK, (void*)&link) == -1) { + eth_log(proc, "Unknown PHY link status"); + break; + } + if(link != PHY_LINK_OFF) { + eth_log(proc, "phy link on"); + return 1; + } + furi_delay_ms(20); + if(furi_get_tick() > last_log_time + 1000) { + eth_log(proc, "phy link check %d", (last_log_time - start_time) / 1000); + last_log_time = furi_get_tick(); + } + } + return 0; +} + +#define DHCP_SOCKET 0 +uint8_t ping_auto(uint8_t s, uint8_t* addr); + +static void load_net_parameters(const EthernetSaveConfig* cfg) { + gWIZNETINFO.gw[0] = cfg->gateway[0]; + gWIZNETINFO.gw[1] = cfg->gateway[1]; + gWIZNETINFO.gw[2] = cfg->gateway[2]; + gWIZNETINFO.gw[3] = cfg->gateway[3]; + + gWIZNETINFO.sn[0] = cfg->mask[0]; + gWIZNETINFO.sn[1] = cfg->mask[1]; + gWIZNETINFO.sn[2] = cfg->mask[2]; + gWIZNETINFO.sn[3] = cfg->mask[3]; + + gWIZNETINFO.mac[0] = cfg->mac[0]; + gWIZNETINFO.mac[1] = cfg->mac[1]; + gWIZNETINFO.mac[2] = cfg->mac[2]; + gWIZNETINFO.mac[3] = cfg->mac[3]; + gWIZNETINFO.mac[4] = cfg->mac[4]; + gWIZNETINFO.mac[5] = cfg->mac[5]; + + gWIZNETINFO.ip[0] = cfg->ip[0]; + gWIZNETINFO.ip[1] = cfg->ip[1]; + gWIZNETINFO.ip[2] = cfg->ip[2]; + gWIZNETINFO.ip[3] = cfg->ip[3]; + + gWIZNETINFO.dns[0] = cfg->dns[0]; + gWIZNETINFO.dns[1] = cfg->dns[1]; + gWIZNETINFO.dns[2] = cfg->dns[2]; + gWIZNETINFO.dns[3] = cfg->dns[3]; + + gWIZNETINFO.dhcp = NETINFO_STATIC; +} + +int32_t eth_worker_task(void* context) { + furi_assert(context); + EthWorker* worker = (EthWorker*)context; + furi_hal_power_insomnia_enter(); + + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_external); + uint8_t W5500FifoSize[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; + uint8_t dhcp_buffer[2048]; + + reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte); + reg_wizchip_spiburst_cbfunc(W5500_ReadBuff, W5500_WriteBuff); + reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect); + + furi_hal_gpio_write(&resetpin, true); + furi_hal_gpio_write(&cspin, true); + furi_hal_gpio_init(&resetpin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_init(&cspin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedVeryHigh); + + while(worker->state != EthWorkerStateStop) { + if(worker->state == EthWorkerStateNotInited) { + if(worker->next_state == EthWorkerStateInit) { + worker->state = worker->next_state; + } + } else if(worker->state == EthWorkerStateInited) { + if(worker->next_state == EthWorkerStateDHCP || + worker->next_state == EthWorkerStateStaticIp) { + worker->state = worker->next_state; + } + } else if(worker->state == EthWorkerStateOnline) { + if(worker->next_state == EthWorkerStatePing) { + worker->state = worker->next_state; + } + } else if(worker->state == EthWorkerStateReset) { + worker->state = EthWorkerStateNotInited; + } + + if(worker->state == EthWorkerStateInit) { + furi_hal_power_enable_otg(); + furi_delay_ms(300); + furi_hal_gpio_write(&resetpin, false); + furi_delay_ms(50); + furi_hal_gpio_write(&resetpin, true); + if(ctlwizchip(CW_INIT_WIZCHIP, (void*)W5500FifoSize) == -1) { + eth_log(EthWorkerProcessInit, "[error] W5500 init fail"); + eth_set_force_state(EthWorkerStateNotInited); + continue; + } + eth_log(EthWorkerProcessInit, "W5500 inited"); + furi_delay_ms(50); + update_WIZNETINFO(false); + wizchip_setnetinfo(&gWIZNETINFO); + wiz_NetInfo readed_net_info; + wizchip_getnetinfo(&readed_net_info); + if(memcmp(&readed_net_info, &gWIZNETINFO, sizeof(wiz_NetInfo))) { + eth_log(EthWorkerProcessInit, "[error] module not detected"); + eth_set_force_state(EthWorkerStateNotInited); + continue; + } + setSHAR(gWIZNETINFO.mac); + wiz_PhyConf conf; + wizphy_getphyconf(&conf); + eth_log( + EthWorkerProcessInit, + "conf %d %d %d %d", + conf.by, + conf.mode, + conf.speed, + conf.duplex); + eth_log(EthWorkerProcessInit, "net info setted"); + eth_log( + EthWorkerProcessInit, + "mac: %02X-%02X-%02X-%02X-%02X-%02X", + gWIZNETINFO.mac[0], + gWIZNETINFO.mac[1], + gWIZNETINFO.mac[2], + gWIZNETINFO.mac[3], + gWIZNETINFO.mac[4], + gWIZNETINFO.mac[5]); + eth_set_force_state(EthWorkerStateInited); + } else if(worker->state == EthWorkerStateDHCP) { + if(!check_phylink(worker, EthWorkerStateDHCP, EthWorkerProcessDHCP, 5000)) { + worker->state = EthWorkerStateInited; + continue; + } + reg_dhcp_cbfunc(Callback_IPAssigned, Callback_IPAssigned, Callback_IPConflict); + DHCP_init(DHCP_SOCKET, dhcp_buffer); + { + // DHCP_run(); + // eth_log(EthWorkerProcessDHCP, "DHCP Send Discover"); + // furi_delay_ms(1000); + // DHCP_stop(); + } + uint8_t next_cycle = 1; + uint16_t divider = 0; + while(next_cycle && worker->state == EthWorkerStateDHCP) { + uint8_t dhcp_ret = DHCP_run(); + switch(dhcp_ret) { + case DHCP_IP_ASSIGN: + case DHCP_IP_CHANGED: + case DHCP_IP_LEASED: + getIPfromDHCP(gWIZNETINFO.ip); + getGWfromDHCP(gWIZNETINFO.gw); + getSNfromDHCP(gWIZNETINFO.sn); + getDNSfromDHCP(gWIZNETINFO.dns); + gWIZNETINFO.dhcp = NETINFO_DHCP; + ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO); + eth_log( + EthWorkerProcessDHCP, "DHCP IP Leased Time : %ld Sec", getDHCPLeasetime()); + break; + case DHCP_FAILED: + eth_log(EthWorkerProcessDHCP, "DHCP Failed"); + break; + } + furi_delay_ms(10); + if(divider++ % 100 == 0) { + eth_log(EthWorkerProcessDHCP, "DHCP process %d", divider / 100); + if(divider > 2000) { + DHCP_stop(); + eth_log(EthWorkerProcessDHCP, "DHCP Stop by timer"); + eth_set_force_state(EthWorkerStateInited); + break; + } + } + next_cycle = (dhcp_ret == DHCP_RUNNING); + } + if(worker->state != EthWorkerStateDHCP) { + continue; + } + eth_log( + EthWorkerProcessDHCP, + "IP address:\n %d.%d.%d.%d", + gWIZNETINFO.ip[0], + gWIZNETINFO.ip[1], + gWIZNETINFO.ip[2], + gWIZNETINFO.ip[3]); + eth_log( + EthWorkerProcessDHCP, + "SM Mask:\n %d.%d.%d.%d", + gWIZNETINFO.sn[0], + gWIZNETINFO.sn[1], + gWIZNETINFO.sn[2], + gWIZNETINFO.sn[3]); + eth_log( + EthWorkerProcessDHCP, + "Gate way:\n %d.%d.%d.%d", + gWIZNETINFO.gw[0], + gWIZNETINFO.gw[1], + gWIZNETINFO.gw[2], + gWIZNETINFO.gw[3]); + eth_log( + EthWorkerProcessDHCP, + "DNS Server:\n %d.%d.%d.%d", + gWIZNETINFO.dns[0], + gWIZNETINFO.dns[1], + gWIZNETINFO.dns[2], + gWIZNETINFO.dns[3]); + eth_set_force_state(EthWorkerStateOnline); + } else if(worker->state == EthWorkerStateStaticIp) { + if(!check_phylink(worker, EthWorkerStateStaticIp, EthWorkerProcessStatic, 5000)) { + worker->state = EthWorkerStateInited; + continue; + } + eth_log(EthWorkerProcessStatic, "set static ip"); + load_net_parameters(worker->config); + eth_log( + EthWorkerProcessStatic, + "IP address:\n %d.%d.%d.%d", + gWIZNETINFO.ip[0], + gWIZNETINFO.ip[1], + gWIZNETINFO.ip[2], + gWIZNETINFO.ip[3]); + eth_log( + EthWorkerProcessStatic, + "SM Mask:\n %d.%d.%d.%d", + gWIZNETINFO.sn[0], + gWIZNETINFO.sn[1], + gWIZNETINFO.sn[2], + gWIZNETINFO.sn[3]); + eth_log( + EthWorkerProcessStatic, + "Gate way:\n %d.%d.%d.%d", + gWIZNETINFO.gw[0], + gWIZNETINFO.gw[1], + gWIZNETINFO.gw[2], + gWIZNETINFO.gw[3]); + eth_log( + EthWorkerProcessStatic, + "DNS Server:\n %d.%d.%d.%d", + gWIZNETINFO.dns[0], + gWIZNETINFO.dns[1], + gWIZNETINFO.dns[2], + gWIZNETINFO.dns[3]); + ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO); + eth_set_force_state(EthWorkerStateOnline); + } else if(worker->state == EthWorkerStatePing) { + uint8_t* adress = worker->config->ping_ip; + eth_log( + EthWorkerProcessPing, + "ping %d.%d.%d.%d", + adress[0], + adress[1], + adress[2], + adress[3]); + const uint8_t tryes = 4; + uint8_t try = 0; + while(try < tryes && worker->state == EthWorkerStatePing) { + try++; + uint32_t start_time = furi_get_tick(); + uint8_t res = ping_auto_interface(adress); + uint32_t res_time = furi_get_tick(); + if(res == 3) { + eth_log(EthWorkerProcessPing, "%d success %d ms", try, res_time - start_time); + } else { + eth_log( + EthWorkerProcessPing, "%d error %d, %d", try, res, res_time - start_time); + break; + } + } + if(worker->state != EthWorkerStatePing) { + break; + } + eth_set_force_state(EthWorkerStateOnline); + } + furi_delay_ms(5); + } + + furi_hal_spi_release(&furi_hal_spi_bus_handle_external); + furi_hal_power_disable_otg(); + furi_hal_power_insomnia_exit(); + + return 0; +} diff --git a/non_catalog_apps/eth_troubleshooter/eth_worker.h b/non_catalog_apps/eth_troubleshooter/eth_worker.h new file mode 100644 index 00000000000..58e420e5598 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_worker.h @@ -0,0 +1,78 @@ +#pragma once + +#include + +typedef struct EthWorker EthWorker; +typedef struct EthViewProcess EthViewProcess; + +typedef enum { + EthWorkerStateNotAllocated = 0, + EthWorkerStateNotInited, + EthWorkerStateDefaultNext, + EthWorkerStateInited, + EthWorkerStateInit, + EthWorkerStateModulePowerOn, + EthWorkerStateModuleConnect, + EthWorkerStateMACInit, + EthWorkerStateStaticIp, + EthWorkerStateDHCP, + EthWorkerStateOnline, + EthWorkerStatePing, + EthWorkerStateStop, + EthWorkerStateReset, +} EthWorkerState; + +typedef enum { + EthWorkerProcessInit, + EthWorkerProcessDHCP, + EthWorkerProcessStatic, + EthWorkerProcessPing, + EthWorkerProcessReset, + EthWorkerProcessActive, + EthWorkerProcessExit, +} EthWorkerProcess; + +typedef enum { + EthWorkerSubstateInProcess = 0, + EthWorkerSubStateSuccess, + EthWorkerSubStateError, +} EthWorkerSubState; + +typedef enum { + EthCustomEventUpdate = 0, + EthCustomEventModuleInit, + EthCustomEventModuleError, + EthCustomEventModulePowerOn, + EthCustomEventModuleConnect, + EthCustomEventMACInit, + EthCustomEventStaticIp, + EthCustomEventDHCP, + EthCustomEventPing, + EthCustomEventTCP2UART, + EthCustomEventTCP2CLI, + EthCustomEventSaved, +} EthCustomEvent; + +typedef void (*EthWorkerCallback)(EthCustomEvent event, void* context); + +EthWorker* eth_worker_alloc(); + +EthWorkerState eth_worker_get_state(EthWorker* eth_worker); +void eth_worker_set_active_process(EthWorker* eth_worker, EthWorkerProcess state); + +void eth_worker_free(EthWorker* eth_worker); + +void eth_worker_start( + EthWorker* eth_worker, + EthWorkerState state, + EthWorkerCallback callback, + void* context); + +void eth_worker_stop(EthWorker* eth_worker); +void eth_worker_dhcp(EthWorker* eth_worker); +void eth_worker_w5500(EthWorker* eth_worker); +void eth_worker_init_process(EthWorker* eth_worker); + +#define PING_SOCKET 1 +uint8_t ping_auto_interface(uint8_t* adress); +void dhcp_timer_callback(void* context); diff --git a/non_catalog_apps/eth_troubleshooter/eth_worker_dhcp.c b/non_catalog_apps/eth_troubleshooter/eth_worker_dhcp.c new file mode 100644 index 00000000000..405df67ab54 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_worker_dhcp.c @@ -0,0 +1,8 @@ +#include "eth_worker.h" +#include +#include + +void dhcp_timer_callback(void* context) { + UNUSED(context); + DHCP_time_handler(); +} \ No newline at end of file diff --git a/non_catalog_apps/eth_troubleshooter/eth_worker_i.h b/non_catalog_apps/eth_troubleshooter/eth_worker_i.h new file mode 100644 index 00000000000..1ece88730c9 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_worker_i.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "eth_worker.h" +#include "eth_view_process.h" +#include "eth_save_process.h" + +struct EthWorker { + FuriThread* thread; + void* context; + EthernetSaveConfig* config; + EthViewProcess* init_process; + EthViewProcess* dhcp_process; + EthViewProcess* stat_process; + EthViewProcess* ping_process; + EthViewProcess* reset_process; + EthViewProcess* active_process; + + EthWorkerState state; + EthWorkerState next_state; + EthWorkerSubState sub_state; + EthWorkerCallback callback; + FuriTimer* timer; +}; + +void eth_worker_change_state(EthWorker* eth_worker, EthWorkerState state); +void eth_worker_log(EthWorker* eth_worker, const char* str); +void eth_run(EthWorker* worker, EthWorkerProcess process); +void eth_log(EthWorkerProcess process, const char* format, ...); + +int32_t eth_worker_task(void* context); diff --git a/non_catalog_apps/eth_troubleshooter/eth_worker_ping.c b/non_catalog_apps/eth_troubleshooter/eth_worker_ping.c new file mode 100644 index 00000000000..1b9aad740cd --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/eth_worker_ping.c @@ -0,0 +1,11 @@ +#include "eth_worker.h" +#include +#include + +void ping_wait_ms(int ms) { + furi_delay_ms(ms); +} + +uint8_t ping_auto_interface(uint8_t* adress) { + return ping_auto(PING_SOCKET, adress); +} \ No newline at end of file diff --git a/non_catalog_apps/eth_troubleshooter/images/ethernet_icon_10x10px.png b/non_catalog_apps/eth_troubleshooter/images/ethernet_icon_10x10px.png new file mode 100644 index 0000000000000000000000000000000000000000..1f967f14a6687183a9911f5e8a6a25a9562ad659 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>vG8Px&H%UZ6RCr$PoZ*)0APj`J@Bh$s>k&_kAtWu(Nap_YiV!j%L+GO0zVG`V{-w>p z1_07(|C~4g$gO`&0Jd%Wk_9`}7*azyKoMRNTYGOzYI5`%27p6g%PP0F%OT(OS%v_B zi`o)ddcXAng2z5DjYGO~R*04!EN0|1)z^Z?MJtk|^nf7HskpwerpPl36vf83G7b$i)07;@IE)|Qe zP7MODom=42_HVkPk9fI@NO1!IBLKB3-m(g<*4G079;ek6tTFylJM$J$CRJP6#co@x zioP#dw3fWq%Jys}JWf6@oC1gvqb;zu4R9DV_P(0Y08B`72nWzam0ST3^n-610A@k4+C`Du0pJNOY)g0bs2gb4 z%=)d5@1ACXHgXOhwUwm?pjEl|DmJ%p>24z-L@+L zt(D3_p|33f@D-|kQN(&J-2!h7D6iQ3`9=g6=nBA0001N z0m&Hv0001|fXocQ0WzzPA~3o70001B3rNlY0000u1!QIb4v<-W6oJXr|DXN?cC#RT T2Tt%300000NkvXXu0mjfvHg!% literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/images/init_100x19px.png b/non_catalog_apps/eth_troubleshooter/images/init_100x19px.png new file mode 100644 index 0000000000000000000000000000000000000000..b683adf540196a62617f74a772eb5d256703be3d GIT binary patch literal 270 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 literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/images/screenshot_dhcp.png b/non_catalog_apps/eth_troubleshooter/images/screenshot_dhcp.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a59c7be368874c725f4f5dce8e9f79948e28de GIT binary patch literal 2221 zcmZ8i4OEg@8op@xH>lCQLV{YrFCk!YtC{P3=X~e>J@0$( z^StkS?-zN8_eDk|L;wIHbN27~7=WNa7X!jpngjnW*%4^MPwg*Z0uc4h%8wDGL~Q^d ztRiR6ZwqUMPiOL*9&USk?LD!m1-p20?_GBlp{w4REB#eX66VA#;?Vu=tqr92Nca=A z-lAuI1<$|Ky2<}i=hUNf)J>AEKF_jEuJ{(Ey^X$1BB0Bb)_n5;$J~>*z-)XFc=vo@ zC)ab|KKe#xOTyy_-MzU9y3t$iI_71ZdxZFV&Hle@C(CnQls5v99S-<;0UOP@Jz8%P znLpzgIv5(}REqOxtZi8zGZwq~6=22bJMV|)ea(?qx74H^euQ9Ywr678erVlwG^*28 zvVfR7OS3X)hfcAk?IR?VIXRwCR610j+BG&buFc_m-w*JI0r)fqfJ^0eo+vBm`yD|b z?AJdYW@WE8!_-M%@F!_MtOt}0eEdJvMt7c-m!55|jR^Zc-xW9)&&6!L*0!P6kN)++ z!aH>f_`5AiH%xLqQQ4SqvRhq19~X=X4KT*g6E8KHtR zE%9asVa%0YY9$aOD0i=V%^yaiv%{kQ_TFHvOA*9e|vd|CrxREY9KSI_#a%1k95vud*iuv>eb zI2F;sD8lJP-eB@M5=vcVny3URn$PzUHfMPxDIEt7b?k&3Te@u})TgntTcEiEul0XT z{U<|J1NcDPzqwFfarH{bzeViiryZIWWQjzlvOSWaW=_6t`-&yJ%^;vh{)fG2W{V4nd+0g!V1LAXiT@a>#7@?;-NSd z9^c-HxaS^FIS8Rc?z`J=6K=i6Jo%M*^q71r)}3Z4S0j~uajp%cj;ksHWT*)Q*t*Na zG5%7NIOWjyG?JUmmKPbG(YZEk$}raBAv3Cjk)vzCx;Knv4}VcBHE_?x?=lI@xME56 zjDJRK-+B2rP+Cg^UUQ`X%3m}d;mV|Hgp<*minZl*2YL^tCak`}CHdtj2=A)%S8Cd_ zy0ng*>1Z(f9;AEk&d|$WHXEZst2*pep{^vZoUB7$K%2 zKxB*Bf<<`VOuTWHXY_WP z+CYt|M%ZUUa09!073Q4Bl|c}jqq(yeotlqG4HMkkBTm#uKh|yIg}{I)%0K$h7_u%c zL5kcLvB|o+`zHIO^dOJgzj#XmNv)~$V4VG_f4JWOK<@j{4Or&E3@23_?=iQQEd_($ zpM``moZjBqM^;cB7z^wvP(>=2Q!o@siG?M)gMwn&jdJnQc90Cg3!RBd5%~-~gXUC5 z{A9j>Yz|L;dSqk8h3Yt|B71R!xRE(;@eLz7VPwybZv{WEg$W3BgHv-p@E%!S=vhV; ztEpFKD)~||B^o(foZ{SA1wTFAC?F10V=cHvgh_DK*UVq=_Vlv}%2ij)c`2VvS9L7} zzrZ3)zmaDDopKw@N0sARlk!>HiAAhWFm@ODk4V_(GRkE7IwRu2S|qDd&(-$z z`j^&SUTQu2_H*kk^dMYaEL^B^Nb~vR4vRc=x*gKE?aKOf{T~f%%7iPdBaW3hS2S|4 RYUPd0*?V};U^eBC{{!c)k9q(A literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/images/screenshot_init.png b/non_catalog_apps/eth_troubleshooter/images/screenshot_init.png new file mode 100644 index 0000000000000000000000000000000000000000..ef70d3329d47562ac91fba7f7b21f3e64d9a5b1f GIT binary patch literal 2304 zcmZ8i3s6&M7XEKhq*$OWWw&4<-I+>tp-`Hlh7eF{MXd6Y(DJrL6G{wHQ<621h+6E} zrmNQNLJ)#3%fp0(;Smrp35vo3p@ESkA||mSB%}}m{ro^OiW@6Dt9CcclfEu25US9(q$Q+>wnDi(J3oco86KCPD{ zL^gG(Xk|q`jE`(o(S|OiPApBgi2AenKZKm^74K>1r4%%NED|aJQ2q&ks8>O8ysFCn zHaDA<=)@hq=pEO#WN0c6v9t?*2(gce?P&)h$A8v$l|kUUHvzc03GA((vkRXWaZFn! zMfN<7>B#4r!JUjH#hdg$A|1|N0q_3Jk-S%v^YDa$s@f?z{^WjHOYW?m8+s6CH}?2+ zYci*pwBhQii~|4LVKX9RvIIFr;Ig^qV2qQSkfHM|i&Ya^T}4|Ec6Y%4pzy;^m6(!pdak9?4r|cwA)SEB zi_C^vim9fH?c$l;a~&)`19|)-nDOYGQyI!!Ys6?rBDZB+@V3pcRd4M1(HrdD0fE;K zIci>reY*L897WD*(Y9z;@^{0)JK=WhoTsWL+>-a(fT6~pc5C{3{DsVuTR`wSMLP)K zN30SZN&0Jis3q~5aCEdtJHa#9GWzI31 zw7zl-*>D1fu;dhy?X!x}QY`Ti#vivv|7w2P!YNuydn(rR9WJts*QoEB(F~>${Lqi} z$yvBu6`EJ|&Cx7!>z9L_gA1oNJ$1DDf1ASCLjvu(yNxHmMNmt^rt+kgGL!1lNq&8T zm!+BQhGtz4fkC9)qCf9i(4SB}n_jT%v&j(D0}T`Ti#$AbdXT+qCSu}W8%#$X;X(~z zbKCDuXE#qQS3K-{o{afDsBW3;Wl6m0He`(;zYh+*v7WyK3jgQnO2Y?rjQ*WQU0gMh zw;ZAMw4NRaW5VFqraB0^Tw@#?@kx>3DHRFGZ1WN-E>&9Un%!LOR%aKEw%T6f{q_ea zfAa>Y3|#`zTcPUAJ#~`5h)-5(+bBaw{Ha_iTZZ{7<5@1l+mkr2wSg$ zDt?8P;@jbz|7>XnNZ}(l<(L-KD97-G($}>q`ON7C^25?{Lrtxx^(*JKc3EX!nD;nZ zWL*Lh1lSEn5;h~N^ByhqxbZ+)R7{66$__0)j#R&e`s8b64kCaNQ?g4R^is=#g0n6s zV8PlNpzstsH=eL^@{>W0QqPjK@v`{u)372c!$j+&==|(V6#-X7rAL3n+)$4l5-3o1 zw1+4yiH<~DFvtVrGSZM3pGHm>z=aGm`;<+6XZi$x?&AAfpPve8 z2}(S(9MJv~3Ffxmfl!X^TeF{ z)8Wv{7sI^DPB|XB%NU`cTEmy_JYbuWG;+;SYMp`8#}*0x?n+C40BZtbic>x=wwBeY z)u?)Pq8jY%Em>n+yNOev@MTFm1HwQfxs*ZCz*mr)n;F=nn#t8_*4Sl zlw?X)sL;K31dL2+y3-d}f**INlJ4Js7(>GalL?1$y0i{fmo>0-#MEFxi;RqNtc|*W zy6_#c1g3aNauVQ}E=h{iI%;}zd+t^A3LPhI#Y>qeFYP__%!+`@8ymU!@N6(F-ehHW zAbKl3iEsIuZ>p%jrxITypz7dSDFf~wl4MKbLKm_;KcHf|m5q^FjMFlDhy;cTZK#6N zVhykIC0@VU7X9|^>o63`sfcck5u-wqelkPA0CyhE+WaxK)(u3$KMsW!4;T#tM5jF^ zFfU;XsA5kpRkCkTXGSo5h?glJbT7ioH~4hxIu~=?XtjC5w32y91{d`a0zkLQykZ+E z=2j8D@~Le8oag`b=;0yCRHa~b=h?(aD2|oA_?#KV>Aj1JjK2oULrZl(hC54 zV;0Wxj+jSP6#4xC`B(tML+=5@mOmMIgGtikWlqZGT*X&?czi?WoNgXkffLSmYz(a6 zc3n_I<{gRVjE%narB##K<~)2fIJ2PEE*2=83lX-wuJQPrm#_4~vA-oSkuu%#Jz=q5 eY`PcnzI!BkOLkdLl4N!7#(WyPpBHuP{C@znQ_7bB literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/images/screenshot_static.png b/non_catalog_apps/eth_troubleshooter/images/screenshot_static.png new file mode 100644 index 0000000000000000000000000000000000000000..4715b403da08f01a44d41320deb37109d28a7cc3 GIT binary patch literal 2033 zcmZuyX;4#F6ux0;6a`!g$|~bbs{=zp5G3l0)KXb&5tLooq>?rPLK+z$B#=6G7#)b6 z7Azbl!3{?Rf*2EJNpO%n*%Bm;fv`0hVZ3(w)q?wOEa ze{(ZiGXQ{jV1VCY0F3mX7_iFl3Yv~~*S}V$2Sif=uy|;AFvTtwb^u^GfqvhHWtB}1 zhO#(5Uz+v=x;z`zXtpLZTG`L(Z}Sg7ITPD>Pr+74ZZJu|+)NWCI4*_FsO0i3O|u%5 z{G#pgB!PUJ)0^e!aC297&4C>X^qmdb>&;;mE2J;Cfp#ww;JY0I){SM)b9m?Y2Q5$j zPJKsF;8gesBqpz)vsta8EjHaz9{qEwl?%ZB)qojd1f0Zb_1AND8NzfCD)Js{8?~xC zv8iKTwxMm4)yH^20GvKsV$5yG5t9EVcqkv1coLOURk#4iuk*n6(A=mZMo;Y=D`w-d zEgz7i415w^!j;jwv>sz~%_-$~4zkSJM^=)g%zwAE-YMSZ?!rtSpg%Im*{OKb`km)3lv2okk{ZCL#`_|KZs1~PlXEmV|DlEJ6Uo8L`6ocWrCQ7M@X-akViC63GZfI z3vH{bb@ve|p4e6AnHL$kAdh;}mjlHu$~2Pu{V1aF+TL=hY|5l(WBhFFn%cR>H0m`^ zq2Og*YcX^}sWJ0n|3X}bA{6tHT?1k&*jU?m{y7nSz?*jr`Q+f{;}cp#Nvv)1JcPJV zD)7LoY$~)DeuTvX{ezGww~)* zf!mxx)|4(p469{CDX(v);MUv>i~`5}y&&en72dwMzFaX{aGc(eyEri(lS)6pe*ym( zCbe(p%BRln;gv-|q7%D%dT0$&O5Lgp@gL-)>(1+C|Q2yG}4aFQLRG(vxd0 ziRT^r&hj4=7w$%_>S7_0RVhHT3>W>XiBLGv+a~xYQM8ljI^Fw0a1K?H_~IzON>8Qi zMo$p5=PVU?Ap*86;!r#<`68Q6q6$O%SyNCpQ-Dr@oq%I^a5TM74aF5sT3b7 zOBCCBU1enE$&QO>Y8tJ3xGItut?|Zl21d0Uqfb3?v>Q{CzBG~I(jw0oX^7S5PwzHE z-G^f$Hdok0II3+S(TA5A-yLHVdp$0H{|$z@6ZUBAeM$0`H^p*j0+h-4JY#x|Gvx&V&bS z70sfOC*3#fNn(wZcK{89<$nl<=+`5y?6uuPsN>6ZaTp*w0<~?O7IP;pUX4TgOY8vm zIz(tV6;wyR;hQiA|1-Kqa&=G9FY4DoV4%Ycsr3EoS{ceBnPoSE09dB_tHdyNS0?!* z6a=XT5$C}@a&@;%!thU3l>({qux;ncs$KpGkV literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitattributes b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitattributes new file mode 100755 index 00000000000..412eeda78dc --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitignore b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitignore new file mode 100755 index 00000000000..a505ec0a7f8 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/.gitignore @@ -0,0 +1,1940 @@ +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +man/man3/wizchip_conf.h.3 +man/man3/wizchip_conf.c.3 +man/man3/wiz_PhyConf_t.3 +man/man3/wiz_NetTimeout_t.3 +man/man3/wiz_NetInfo_t.3 +man/man3/w5500.jpg.3 +man/man3/w5500.h.3 +man/man3/w5500.c.3 +man/man3/w5300.h.3 +man/man3/w5300.c.3 +man/man3/w5200_w5500.jpg.3 +man/man3/w5200.h.3 +man/man3/ftpc.h.3 +man/man3/ftpc.c.3 +man/man3/ftpc.3 +man/man3/extra_functions.3 +man/man3/doxygen_log.txt.3 +man/man3/dns.h.3 +man/man3/dns.c.3 +man/man3/dhdr.3 +man/man3/dhcp.h.3 +man/man3/dhcp.c.3 +man/man3/dataEntryType.3 +man/man3/_un_l2cval.3 +man/man3/_st_http_socket.3 +man/man3/_st_http_request.3 +man/man3/_ntpformat.3 +man/man3/_httpServer_webContent.3 +man/man3/W5100.3 +man/man3/Timer.3 +man/man3/StackTrace.h.3 +man/man3/Special_function_W5100S.3 +man/man3/Socket_register_group_W5300.3 +man/man3/Socket_register_group_W5200.3 +man/man3/Socket_register_group_W5100S.3 +man/man3/Socket_register_group_W5100.3 +man/man3/Socket_register_group.3 +man/man3/Socket_register_access_function_W5300.3 +man/man3/Socket_register_access_function_W5200.3 +man/man3/Socket_register_access_function_W5100S.3 +man/man3/Socket_register_access_function_W5100.3 +man/man3/Socket_register_access_function.3 +man/man3/Readme.txt.3 +man/man3/RIP_MSG.3 +man/man3/README.md.3 +man/man3/Network.3 +man/man3/MessageData.3 +man/man3/Main_page.txt.3 +man/man3/MQTTUnsubscribeServer.c.3 +man/man3/MQTTUnsubscribeClient.c.3 +man/man3/MQTTUnsubscribe.h.3 +man/man3/MQTTTransport.3 +man/man3/MQTTSubscribeServer.c.3 +man/man3/MQTTSubscribeClient.c.3 +man/man3/MQTTSubscribe.h.3 +man/man3/MQTTString.3 +man/man3/MQTTSerializePublish.c.3 +man/man3/MQTTPublish.h.3 +man/man3/MQTTPacket_willOptions.3 +man/man3/MQTTPacket_connectData.3 +man/man3/MQTTPacket.h.3 +man/man3/MQTTPacket.c.3 +man/man3/MQTTMessage.3 +man/man3/MQTTLenString.3 +man/man3/MQTTHeader.3 +man/man3/MQTTFormat.h.3 +man/man3/MQTTFormat.c.3 +man/man3/MQTTDeserializePublish.c.3 +man/man3/MQTTConnectServer.c.3 +man/man3/MQTTConnectFlags.3 +man/man3/MQTTConnectClient.c.3 +man/man3/MQTTConnect.h.3 +man/man3/MQTTConnackFlags.3 +man/man3/MQTTClient_MessageHandlers.3 +man/man3/MQTTClient.h.3 +man/man3/MQTTClient.c.3 +man/man3/MQTTClient.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_img_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_image_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_httpServer_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_TFTP_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_SNTP_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_SNMP_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_MQTT_MQTTPacket_src_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_MQTT_MQTTPacket_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_MQTT_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_FTPServer_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_FTPClient_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_DNS_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_DHCP_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Internet_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Ethernet_W5500_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Ethernet_W5300_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Ethernet_W5200_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Ethernet_W5100_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Ethernet_W5100S_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Ethernet_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Application_loopback_.3 +man/man3/D__workspace_CoIDE WorkSpace_ioLibrary_Driver_Application_.3 +man/man3/DATA_TYPE.3 +man/man3/Common_register_group_W5300.3 +man/man3/Common_register_group_W5200.3 +man/man3/Common_register_group_W5100S.3 +man/man3/Common_register_group_W5100.3 +man/man3/Common_register_group.3 +man/man3/Common_register_access_function_W5300.3 +man/man3/Common_register_access_function_W5200.3 +man/man3/Common_register_access_function_W5100S.3 +man/man3/Common_register_access_function_W5100.3 +man/man3/Common_register_access_function.3 +man/man3/Command.3 +man/man3/Berkeley_SOCKET.jpg.3 +man/man3/Basic_IO_function_W5300.3 +man/man3/Basic_IO_function_W5200.3 +man/man3/Basic_IO_function_W5100S.3 +man/man3/Basic_IO_function_W5100.3 +man/man3/Basic_IO_function.3 +latex/wizchip__conf_8h__incl.pdf +latex/wizchip__conf_8h__incl.md5 +latex/wizchip__conf_8h__dep__incl.pdf +latex/wizchip__conf_8h__dep__incl.md5 +latex/wizchip__conf_8h.tex +latex/wizchip__conf_8c__incl.pdf +latex/wizchip__conf_8c__incl.md5 +latex/wizchip__conf_8c.tex +latex/w5500_8jpg.tex +latex/w5500_8h__incl.pdf +latex/w5500_8h__incl.md5 +latex/w5500_8h__dep__incl.pdf +latex/w5500_8h__dep__incl.md5 +latex/w5500_8h.tex +latex/w5500_8c__incl.pdf +latex/w5500_8c__incl.md5 +latex/w5500_8c.tex +latex/w5300_8h__incl.pdf +latex/w5300_8h__incl.md5 +latex/w5300_8h.tex +latex/w5300_8c__incl.pdf +latex/w5300_8c__incl.md5 +latex/w5300_8c.tex +latex/w5200__w5500_8jpg.tex +latex/w5200_8h__incl.pdf +latex/w5200_8h__incl.md5 +latex/w5200_8h__dep__incl.pdf +latex/w5200_8h__dep__incl.md5 +latex/w5200_8h.tex +latex/w5200_8c__incl.pdf +latex/w5200_8c__incl.md5 +latex/w5200_8c.tex +latex/w5100s_8h__incl.pdf +latex/w5100s_8h__incl.md5 +latex/w5100s_8h__dep__incl.pdf +latex/w5100s_8h__dep__incl.md5 +latex/w5100s_8h.tex +latex/w5100s_8c__incl.pdf +latex/w5100s_8c__incl.md5 +latex/w5100s_8c.tex +latex/w5100_8h__incl.pdf +latex/w5100_8h__incl.md5 +latex/w5100_8h__dep__incl.pdf +latex/w5100_8h__dep__incl.md5 +latex/w5100_8h.tex +latex/w5100_8c__incl.pdf +latex/w5100_8c__incl.md5 +latex/w5100_8c.tex +latex/union_m_q_t_t_header.tex +latex/union_m_q_t_t_connect_flags.tex +latex/union_m_q_t_t_connack_flags.tex +latex/union__un__l2cval.tex +latex/union_____w_i_z_c_h_i_p_1_1___i_f.tex +latex/todo.tex +latex/tftp_8h__incl.pdf +latex/tftp_8h__incl.md5 +latex/tftp_8h__dep__incl.pdf +latex/tftp_8h__dep__incl.md5 +latex/tftp_8h.tex +latex/tftp_8c__incl.pdf +latex/tftp_8c__incl.md5 +latex/tftp_8c.tex +latex/structwiz___phy_conf__t.tex +latex/structwiz___net_timeout__t.tex +latex/structwiz___net_info__t.tex +latex/structtlv_struct_type.tex +latex/structtftp__option.tex +latex/structtftp__error.tex +latex/structtftp__data.tex +latex/structmessage_struct.tex +latex/structftpd.tex +latex/structftpc.tex +latex/structdhdr.tex +latex/structdata_entry_type.tex +latex/struct_timer.tex +latex/struct_r_i_p___m_s_g.tex +latex/struct_network.tex +latex/struct_message_data__coll__graph.pdf +latex/struct_message_data__coll__graph.md5 +latex/struct_message_data.tex +latex/struct_m_q_t_t_transport.tex +latex/struct_m_q_t_t_string__coll__graph.pdf +latex/struct_m_q_t_t_string__coll__graph.md5 +latex/struct_m_q_t_t_string.tex +latex/struct_m_q_t_t_packet__will_options__coll__graph.pdf +latex/struct_m_q_t_t_packet__will_options__coll__graph.md5 +latex/struct_m_q_t_t_packet__will_options.tex +latex/struct_m_q_t_t_packet__connect_data__coll__graph.pdf +latex/struct_m_q_t_t_packet__connect_data__coll__graph.md5 +latex/struct_m_q_t_t_packet__connect_data.tex +latex/struct_m_q_t_t_message.tex +latex/struct_m_q_t_t_len_string.tex +latex/struct_m_q_t_t_client__coll__graph.pdf +latex/struct_m_q_t_t_client__coll__graph.md5 +latex/struct_m_q_t_t_client_1_1_message_handlers.tex +latex/struct_m_q_t_t_client.tex +latex/struct_command.tex +latex/struct__st__http__socket.tex +latex/struct__st__http__request.tex +latex/struct__ntpformat.tex +latex/struct__http_server__web_content.tex +latex/struct__datetime.tex +latex/struct____file.tex +latex/struct_____w_i_z_c_h_i_p__coll__graph.pdf +latex/struct_____w_i_z_c_h_i_p__coll__graph.md5 +latex/struct_____w_i_z_c_h_i_p_1_1___c_s.tex +latex/struct_____w_i_z_c_h_i_p_1_1___c_r_i_s.tex +latex/struct_____w_i_z_c_h_i_p.tex +latex/socket_8h__incl.pdf +latex/socket_8h__incl.md5 +latex/socket_8h__dep__incl.pdf +latex/socket_8h__dep__incl.md5 +latex/socket_8h.tex +latex/socket_8c__incl.pdf +latex/socket_8c__incl.md5 +latex/socket_8c.tex +latex/sntp_8h__incl.pdf +latex/sntp_8h__incl.md5 +latex/sntp_8h__dep__incl.pdf +latex/sntp_8h__dep__incl.md5 +latex/sntp_8h.tex +latex/sntp_8c__incl.pdf +latex/sntp_8c__incl.md5 +latex/sntp_8c.tex +latex/snmp__custom_8h__incl.pdf +latex/snmp__custom_8h__incl.md5 +latex/snmp__custom_8h__dep__incl.pdf +latex/snmp__custom_8h__dep__incl.md5 +latex/snmp__custom_8h.tex +latex/snmp__custom_8c__incl.pdf +latex/snmp__custom_8c__incl.md5 +latex/snmp__custom_8c.tex +latex/snmp_8h__dep__incl.pdf +latex/snmp_8h__dep__incl.md5 +latex/snmp_8h.tex +latex/snmp_8c__incl.pdf +latex/snmp_8c__incl.md5 +latex/snmp_8c.tex +latex/refman.tex +latex/netutil_8h__incl.pdf +latex/netutil_8h__incl.md5 +latex/netutil_8h__dep__incl.pdf +latex/netutil_8h__dep__incl.md5 +latex/netutil_8h.tex +latex/netutil_8c__incl.pdf +latex/netutil_8c__incl.md5 +latex/netutil_8c.tex +latex/mqtt__interface_8h__dep__incl.pdf +latex/mqtt__interface_8h__dep__incl.md5 +latex/mqtt__interface_8h.tex +latex/mqtt__interface_8c__incl.pdf +latex/mqtt__interface_8c__incl.md5 +latex/mqtt__interface_8c.tex +latex/modules.tex +latex/md__r_e_a_d_m_e.tex +latex/make.bat +latex/loopback_8h__incl.pdf +latex/loopback_8h__incl.md5 +latex/loopback_8h__dep__incl.pdf +latex/loopback_8h__dep__incl.md5 +latex/loopback_8h.tex +latex/loopback_8c__incl.pdf +latex/loopback_8c__incl.md5 +latex/loopback_8c.tex.tmp +latex/loopback_8c.tex +latex/license_8txt.tex +latex/index.tex +latex/http_util_8h__incl.pdf +latex/http_util_8h__incl.md5 +latex/http_util_8h__dep__incl.pdf +latex/http_util_8h__dep__incl.md5 +latex/http_util_8h.tex +latex/http_util_8c__incl.pdf +latex/http_util_8c__incl.md5 +latex/http_util_8c.tex +latex/http_server_8h__incl.pdf +latex/http_server_8h__incl.md5 +latex/http_server_8h__dep__incl.pdf +latex/http_server_8h__dep__incl.md5 +latex/http_server_8h.tex +latex/http_server_8c__incl.pdf +latex/http_server_8c__incl.md5 +latex/http_server_8c.tex +latex/http_parser_8h__incl.pdf +latex/http_parser_8h__incl.md5 +latex/http_parser_8h__dep__incl.pdf +latex/http_parser_8h__dep__incl.md5 +latex/http_parser_8h.tex +latex/http_parser_8c__incl.pdf +latex/http_parser_8c__incl.md5 +latex/http_parser_8c.tex +latex/group__snmp__module.tex +latex/group__extra__functions.tex +latex/group___w_i_znet__socket___a_p_is.tex +latex/group___w_i_z_c_h_i_p__register___w5300.tex +latex/group___w_i_z_c_h_i_p__register___w5300.pdf +latex/group___w_i_z_c_h_i_p__register___w5300.md5 +latex/group___w_i_z_c_h_i_p__register___w5200.tex +latex/group___w_i_z_c_h_i_p__register___w5200.pdf +latex/group___w_i_z_c_h_i_p__register___w5200.md5 +latex/group___w_i_z_c_h_i_p__register___w5100_s.tex +latex/group___w_i_z_c_h_i_p__register___w5100_s.pdf +latex/group___w_i_z_c_h_i_p__register___w5100_s.md5 +latex/group___w_i_z_c_h_i_p__register___w5100.tex +latex/group___w_i_z_c_h_i_p__register___w5100.pdf +latex/group___w_i_z_c_h_i_p__register___w5100.md5 +latex/group___w_i_z_c_h_i_p__register.tex +latex/group___w_i_z_c_h_i_p__register.pdf +latex/group___w_i_z_c_h_i_p__register.md5 +latex/group___w_i_z_c_h_i_p___i_o___functions___w5300.tex +latex/group___w_i_z_c_h_i_p___i_o___functions___w5300.pdf +latex/group___w_i_z_c_h_i_p___i_o___functions___w5300.md5 +latex/group___w_i_z_c_h_i_p___i_o___functions___w5200.tex +latex/group___w_i_z_c_h_i_p___i_o___functions___w5200.pdf +latex/group___w_i_z_c_h_i_p___i_o___functions___w5200.md5 +latex/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.tex +latex/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.pdf +latex/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.md5 +latex/group___w_i_z_c_h_i_p___i_o___functions___w5100.tex +latex/group___w_i_z_c_h_i_p___i_o___functions___w5100.pdf +latex/group___w_i_z_c_h_i_p___i_o___functions___w5100.md5 +latex/group___w_i_z_c_h_i_p___i_o___functions.tex +latex/group___w_i_z_c_h_i_p___i_o___functions.pdf +latex/group___w_i_z_c_h_i_p___i_o___functions.md5 +latex/group___w5500.tex +latex/group___w5500.pdf +latex/group___w5500.md5 +latex/group___w5300.tex +latex/group___w5300.pdf +latex/group___w5300.md5 +latex/group___w5200.tex +latex/group___w5200.pdf +latex/group___w5200.md5 +latex/group___w5100_s.tex +latex/group___w5100_s.pdf +latex/group___w5100_s.md5 +latex/group___w5100.tex +latex/group___w5100.pdf +latex/group___w5100.md5 +latex/group___special__function___w5100_s.tex +latex/group___special__function___w5100_s.pdf +latex/group___special__function___w5100_s.md5 +latex/group___socket__register__group___w5300.tex +latex/group___socket__register__group___w5300.pdf +latex/group___socket__register__group___w5300.md5 +latex/group___socket__register__group___w5200.tex +latex/group___socket__register__group___w5200.pdf +latex/group___socket__register__group___w5200.md5 +latex/group___socket__register__group___w5100_s.tex +latex/group___socket__register__group___w5100_s.pdf +latex/group___socket__register__group___w5100_s.md5 +latex/group___socket__register__group___w5100.tex +latex/group___socket__register__group___w5100.pdf +latex/group___socket__register__group___w5100.md5 +latex/group___socket__register__group.tex +latex/group___socket__register__group.pdf +latex/group___socket__register__group.md5 +latex/group___socket__register__access__function___w5300.tex +latex/group___socket__register__access__function___w5300.pdf +latex/group___socket__register__access__function___w5300.md5 +latex/group___socket__register__access__function___w5200.tex +latex/group___socket__register__access__function___w5200.pdf +latex/group___socket__register__access__function___w5200.md5 +latex/group___socket__register__access__function___w5100_s.tex +latex/group___socket__register__access__function___w5100_s.pdf +latex/group___socket__register__access__function___w5100_s.md5 +latex/group___socket__register__access__function___w5100.tex +latex/group___socket__register__access__function___w5100.pdf +latex/group___socket__register__access__function___w5100.md5 +latex/group___socket__register__access__function.tex +latex/group___socket__register__access__function.pdf +latex/group___socket__register__access__function.md5 +latex/group___d_a_t_a___t_y_p_e.tex +latex/group___common__register__group___w5300.tex +latex/group___common__register__group___w5300.pdf +latex/group___common__register__group___w5300.md5 +latex/group___common__register__group___w5200.tex +latex/group___common__register__group___w5200.pdf +latex/group___common__register__group___w5200.md5 +latex/group___common__register__group___w5100_s.tex +latex/group___common__register__group___w5100_s.pdf +latex/group___common__register__group___w5100_s.md5 +latex/group___common__register__group___w5100.tex +latex/group___common__register__group___w5100.pdf +latex/group___common__register__group___w5100.md5 +latex/group___common__register__group.tex +latex/group___common__register__group.pdf +latex/group___common__register__group.md5 +latex/group___common__register__access__function___w5300.tex +latex/group___common__register__access__function___w5300.pdf +latex/group___common__register__access__function___w5300.md5 +latex/group___common__register__access__function___w5200.tex +latex/group___common__register__access__function___w5200.pdf +latex/group___common__register__access__function___w5200.md5 +latex/group___common__register__access__function___w5100_s.tex +latex/group___common__register__access__function___w5100_s.pdf +latex/group___common__register__access__function___w5100_s.md5 +latex/group___common__register__access__function___w5100.tex +latex/group___common__register__access__function___w5100.pdf +latex/group___common__register__access__function___w5100.md5 +latex/group___common__register__access__function.tex +latex/group___common__register__access__function.pdf +latex/group___common__register__access__function.md5 +latex/group___basic___i_o__function___w5300.tex +latex/group___basic___i_o__function___w5300.pdf +latex/group___basic___i_o__function___w5300.md5 +latex/group___basic___i_o__function___w5200.tex +latex/group___basic___i_o__function___w5200.pdf +latex/group___basic___i_o__function___w5200.md5 +latex/group___basic___i_o__function___w5100_s.tex +latex/group___basic___i_o__function___w5100_s.pdf +latex/group___basic___i_o__function___w5100_s.md5 +latex/group___basic___i_o__function___w5100.tex +latex/group___basic___i_o__function___w5100.pdf +latex/group___basic___i_o__function___w5100.md5 +latex/group___basic___i_o__function.tex +latex/group___basic___i_o__function.pdf +latex/group___basic___i_o__function.md5 +latex/ftpd_8h__incl.pdf +latex/ftpd_8h__incl.md5 +latex/ftpd_8h__dep__incl.pdf +latex/ftpd_8h__dep__incl.md5 +latex/ftpd_8h.tex +latex/ftpd_8c__incl.pdf +latex/ftpd_8c__incl.md5 +latex/ftpd_8c.tex +latex/ftpc_8h__incl.pdf +latex/ftpc_8h__incl.md5 +latex/ftpc_8h__dep__incl.pdf +latex/ftpc_8h__dep__incl.md5 +latex/ftpc_8h.tex +latex/ftpc_8c__incl.pdf +latex/ftpc_8c__incl.md5 +latex/ftpc_8c.tex +latex/files.tex +latex/doxygen__log_8txt.tex +latex/doxygen.sty +latex/dns_8h__incl.pdf +latex/dns_8h__incl.md5 +latex/dns_8h__dep__incl.pdf +latex/dns_8h__dep__incl.md5 +latex/dns_8h.tex +latex/dns_8c__incl.pdf +latex/dns_8c__incl.md5 +latex/dns_8c.tex +latex/dir_fe682d1d76c251404f71241aa833642c_dep.pdf +latex/dir_fe682d1d76c251404f71241aa833642c_dep.md5 +latex/dir_fe682d1d76c251404f71241aa833642c.tex +latex/dir_fca0adf6655fb1759a15e5776097c124_dep.pdf +latex/dir_fca0adf6655fb1759a15e5776097c124_dep.md5 +latex/dir_fca0adf6655fb1759a15e5776097c124.tex +latex/dir_f841453af36a2df9a2123f87589fe4f8_dep.pdf +latex/dir_f841453af36a2df9a2123f87589fe4f8_dep.md5 +latex/dir_f841453af36a2df9a2123f87589fe4f8.tex +latex/dir_f10a527ab5b3936e2edf95a019a13ec7_dep.pdf +latex/dir_f10a527ab5b3936e2edf95a019a13ec7_dep.md5 +latex/dir_f10a527ab5b3936e2edf95a019a13ec7.tex +latex/dir_eb1463819d84903762eb6f59cc0c4383_dep.pdf +latex/dir_eb1463819d84903762eb6f59cc0c4383_dep.md5 +latex/dir_eb1463819d84903762eb6f59cc0c4383.tex +latex/dir_e5121bff4754a4ad570fa548a998f0c5_dep.pdf +latex/dir_e5121bff4754a4ad570fa548a998f0c5_dep.md5 +latex/dir_e5121bff4754a4ad570fa548a998f0c5.tex +latex/dir_b88037d6581d528000057b4eaec3e673_dep.pdf +latex/dir_b88037d6581d528000057b4eaec3e673_dep.md5 +latex/dir_b88037d6581d528000057b4eaec3e673.tex +latex/dir_a5a06f90a751e77147778694c516f622_dep.pdf +latex/dir_a5a06f90a751e77147778694c516f622_dep.md5 +latex/dir_a5a06f90a751e77147778694c516f622.tex +latex/dir_a483286db9c12f74c7364bdaa9e78c36_dep.pdf +latex/dir_a483286db9c12f74c7364bdaa9e78c36_dep.md5 +latex/dir_a483286db9c12f74c7364bdaa9e78c36.tex +latex/dir_a138ed074e64356ad02dbb8d94382c4f_dep.pdf +latex/dir_a138ed074e64356ad02dbb8d94382c4f_dep.md5 +latex/dir_a138ed074e64356ad02dbb8d94382c4f.tex +latex/dir_97b8cbb23222306012bd2d84398746c9_dep.pdf +latex/dir_97b8cbb23222306012bd2d84398746c9_dep.md5 +latex/dir_97b8cbb23222306012bd2d84398746c9.tex +latex/dir_6e6e4d5e89221ed61dd87b2954f72a78_dep.pdf +latex/dir_6e6e4d5e89221ed61dd87b2954f72a78_dep.md5 +latex/dir_6e6e4d5e89221ed61dd87b2954f72a78.tex +latex/dir_6de1940466803d61d2f9d1259cb01031.tex +latex/dir_5a912e51f6f9520965e8671f07512599_dep.pdf +latex/dir_5a912e51f6f9520965e8671f07512599_dep.md5 +latex/dir_5a912e51f6f9520965e8671f07512599.tex +latex/dir_4c7002aef9ece892c0aedd728ed93eff.tex +latex/dir_498fbcdef69ea105b96b8673d051b2e3_dep.pdf +latex/dir_498fbcdef69ea105b96b8673d051b2e3_dep.md5 +latex/dir_498fbcdef69ea105b96b8673d051b2e3.tex +latex/dir_46819ec1095f3903911c103f5ebbb29f_dep.pdf +latex/dir_46819ec1095f3903911c103f5ebbb29f_dep.md5 +latex/dir_46819ec1095f3903911c103f5ebbb29f.tex +latex/dir_4396dcc0e095a5bc10b1affe087807cf_dep.pdf +latex/dir_4396dcc0e095a5bc10b1affe087807cf_dep.md5 +latex/dir_4396dcc0e095a5bc10b1affe087807cf.tex +latex/dir_337e147d8ae2958ef29ccaa8e2f968db_dep.pdf +latex/dir_337e147d8ae2958ef29ccaa8e2f968db_dep.md5 +latex/dir_337e147d8ae2958ef29ccaa8e2f968db.tex +latex/dir_2c7bb40a7e5a6685f00216dd2909cd99_dep.pdf +latex/dir_2c7bb40a7e5a6685f00216dd2909cd99_dep.md5 +latex/dir_2c7bb40a7e5a6685f00216dd2909cd99.tex +latex/dir_2c1dd796c287ab9a5cf44281d8a3cbeb.tex +latex/dir_072fcb7a67163ce1d8f22ad4144c7e08.tex +latex/dhcp_8h__dep__incl.pdf +latex/dhcp_8h__dep__incl.md5 +latex/dhcp_8h.tex +latex/dhcp_8c__incl.pdf +latex/dhcp_8c__incl.md5 +latex/dhcp_8c.tex +latex/annotated.tex +latex/_w_i_znet___s_o_c_k_e_t_8jpg.tex +latex/_stack_trace_8h__incl.pdf +latex/_stack_trace_8h__incl.md5 +latex/_stack_trace_8h__dep__incl.pdf +latex/_stack_trace_8h__dep__incl.md5 +latex/_stack_trace_8h.tex +latex/_readme_8txt.tex +latex/_r_e_a_d_m_e_8md.tex +latex/_main__page_8txt.tex +latex/_m_q_t_t_unsubscribe_server_8c__incl.pdf +latex/_m_q_t_t_unsubscribe_server_8c__incl.md5 +latex/_m_q_t_t_unsubscribe_server_8c.tex +latex/_m_q_t_t_unsubscribe_client_8c__incl.pdf +latex/_m_q_t_t_unsubscribe_client_8c__incl.md5 +latex/_m_q_t_t_unsubscribe_client_8c.tex +latex/_m_q_t_t_unsubscribe_8h__dep__incl.pdf +latex/_m_q_t_t_unsubscribe_8h__dep__incl.md5 +latex/_m_q_t_t_unsubscribe_8h.tex +latex/_m_q_t_t_subscribe_server_8c__incl.pdf +latex/_m_q_t_t_subscribe_server_8c__incl.md5 +latex/_m_q_t_t_subscribe_server_8c.tex +latex/_m_q_t_t_subscribe_client_8c__incl.pdf +latex/_m_q_t_t_subscribe_client_8c__incl.md5 +latex/_m_q_t_t_subscribe_client_8c.tex +latex/_m_q_t_t_subscribe_8h__dep__incl.pdf +latex/_m_q_t_t_subscribe_8h__dep__incl.md5 +latex/_m_q_t_t_subscribe_8h.tex +latex/_m_q_t_t_serialize_publish_8c__incl.pdf +latex/_m_q_t_t_serialize_publish_8c__incl.md5 +latex/_m_q_t_t_serialize_publish_8c.tex +latex/_m_q_t_t_publish_8h__dep__incl.pdf +latex/_m_q_t_t_publish_8h__dep__incl.md5 +latex/_m_q_t_t_publish_8h.tex +latex/_m_q_t_t_packet_8h__incl.pdf +latex/_m_q_t_t_packet_8h__incl.md5 +latex/_m_q_t_t_packet_8h__dep__incl.pdf +latex/_m_q_t_t_packet_8h__dep__incl.md5 +latex/_m_q_t_t_packet_8h.tex +latex/_m_q_t_t_packet_8c__incl.pdf +latex/_m_q_t_t_packet_8c__incl.md5 +latex/_m_q_t_t_packet_8c.tex +latex/_m_q_t_t_format_8h__incl.pdf +latex/_m_q_t_t_format_8h__incl.md5 +latex/_m_q_t_t_format_8h__dep__incl.pdf +latex/_m_q_t_t_format_8h__dep__incl.md5 +latex/_m_q_t_t_format_8h.tex +latex/_m_q_t_t_format_8c__incl.pdf +latex/_m_q_t_t_format_8c__incl.md5 +latex/_m_q_t_t_format_8c.tex +latex/_m_q_t_t_deserialize_publish_8c__incl.pdf +latex/_m_q_t_t_deserialize_publish_8c__incl.md5 +latex/_m_q_t_t_deserialize_publish_8c.tex +latex/_m_q_t_t_connect_server_8c__incl.pdf +latex/_m_q_t_t_connect_server_8c__incl.md5 +latex/_m_q_t_t_connect_server_8c.tex +latex/_m_q_t_t_connect_client_8c__incl.pdf +latex/_m_q_t_t_connect_client_8c__incl.md5 +latex/_m_q_t_t_connect_client_8c.tex +latex/_m_q_t_t_connect_8h__dep__incl.pdf +latex/_m_q_t_t_connect_8h__dep__incl.md5 +latex/_m_q_t_t_connect_8h.tex +latex/_m_q_t_t_client_8h__incl.pdf +latex/_m_q_t_t_client_8h__incl.md5 +latex/_m_q_t_t_client_8h__dep__incl.pdf +latex/_m_q_t_t_client_8h__dep__incl.md5 +latex/_m_q_t_t_client_8h.tex +latex/_m_q_t_t_client_8c__incl.pdf +latex/_m_q_t_t_client_8c__incl.md5 +latex/_m_q_t_t_client_8c.tex +latex/_f_t_p_server_2stdio__private_8h__incl.pdf +latex/_f_t_p_server_2stdio__private_8h__incl.md5 +latex/_f_t_p_server_2stdio__private_8h__dep__incl.pdf +latex/_f_t_p_server_2stdio__private_8h__dep__incl.md5 +latex/_f_t_p_server_2stdio__private_8h.tex +latex/_f_t_p_client_2stdio__private_8h__incl.pdf +latex/_f_t_p_client_2stdio__private_8h__incl.md5 +latex/_f_t_p_client_2stdio__private_8h__dep__incl.pdf +latex/_f_t_p_client_2stdio__private_8h__dep__incl.md5 +latex/_f_t_p_client_2stdio__private_8h.tex +latex/_berkeley___s_o_c_k_e_t_8jpg.tex +latex/Makefile +image/w5500.jpg +image/w5200_w5500.jpg +image/WIZnet_SOCKET.jpg +image/Berkeley_SOCKET.jpg +html/wizchip__conf_8h_source.html +html/wizchip__conf_8h__incl.png +html/wizchip__conf_8h__incl.md5 +html/wizchip__conf_8h__incl.map +html/wizchip__conf_8h__dep__incl.png +html/wizchip__conf_8h__dep__incl.md5 +html/wizchip__conf_8h__dep__incl.map +html/wizchip__conf_8h.html +html/wizchip__conf_8c_source.html +html/wizchip__conf_8c__incl.png +html/wizchip__conf_8c__incl.md5 +html/wizchip__conf_8c__incl.map +html/wizchip__conf_8c.html +html/w5500_8jpg_source.html +html/w5500_8jpg.html +html/w5500_8h_source.html +html/w5500_8h__incl.png +html/w5500_8h__incl.md5 +html/w5500_8h__incl.map +html/w5500_8h__dep__incl.png +html/w5500_8h__dep__incl.md5 +html/w5500_8h__dep__incl.map +html/w5500_8h.html +html/w5500_8c_source.html +html/w5500_8c__incl.png +html/w5500_8c__incl.md5 +html/w5500_8c__incl.map +html/w5500_8c.html +html/w5300_8h_source.html +html/w5300_8h__incl.png +html/w5300_8h__incl.md5 +html/w5300_8h__incl.map +html/w5300_8h.html +html/w5300_8c_source.html +html/w5300_8c__incl.png +html/w5300_8c__incl.md5 +html/w5300_8c__incl.map +html/w5300_8c.html +html/w5200_w5500.jpg +html/w5200__w5500_8jpg_source.html +html/w5200__w5500_8jpg.html +html/w5200_8h_source.html +html/w5200_8h__incl.png +html/w5200_8h__incl.md5 +html/w5200_8h__incl.map +html/w5200_8h__dep__incl.png +html/w5200_8h__dep__incl.md5 +html/w5200_8h__dep__incl.map +html/w5200_8h.html +html/w5200_8c_source.html +html/w5200_8c__incl.png +html/w5200_8c__incl.md5 +html/w5200_8c__incl.map +html/w5200_8c.html +html/w5100s_8h_source.html +html/w5100s_8h__incl.png +html/w5100s_8h__incl.md5 +html/w5100s_8h__incl.map +html/w5100s_8h__dep__incl.png +html/w5100s_8h__dep__incl.md5 +html/w5100s_8h__dep__incl.map +html/w5100s_8h.html +html/w5100s_8c_source.html +html/w5100s_8c__incl.png +html/w5100s_8c__incl.md5 +html/w5100s_8c__incl.map +html/w5100s_8c.html +html/w5100_8h_source.html +html/w5100_8h__incl.png +html/w5100_8h__incl.md5 +html/w5100_8h__incl.map +html/w5100_8h__dep__incl.png +html/w5100_8h__dep__incl.md5 +html/w5100_8h__dep__incl.map +html/w5100_8h.html +html/w5100_8c_source.html +html/w5100_8c__incl.png +html/w5100_8c__incl.md5 +html/w5100_8c__incl.map +html/w5100_8c.html +html/union_m_q_t_t_header.html +html/union_m_q_t_t_connect_flags.html +html/union_m_q_t_t_connack_flags.html +html/union__un__l2cval.html +html/union_____w_i_z_c_h_i_p_1_1___i_f.html +html/todo.html +html/tftp_8h_source.html +html/tftp_8h__incl.png +html/tftp_8h__incl.md5 +html/tftp_8h__incl.map +html/tftp_8h__dep__incl.png +html/tftp_8h__dep__incl.md5 +html/tftp_8h__dep__incl.map +html/tftp_8h.html +html/tftp_8c_source.html +html/tftp_8c__incl.png +html/tftp_8c__incl.md5 +html/tftp_8c__incl.map +html/tftp_8c.html +html/tabs.css +html/tab_s.png +html/tab_h.png +html/tab_b.png +html/tab_a.png +html/sync_on.png +html/sync_off.png +html/structwiz___phy_conf__t.html +html/structwiz___net_timeout__t.html +html/structwiz___net_info__t.html +html/structtlv_struct_type.html +html/structtftp__option.html +html/structtftp__error.html +html/structtftp__data.html +html/structmessage_struct.html +html/structftpd.html +html/structftpc.html +html/structdhdr.html +html/structdata_entry_type.html +html/struct_timer.html +html/struct_r_i_p___m_s_g.html +html/struct_network.html +html/struct_message_data__coll__graph.png +html/struct_message_data__coll__graph.md5 +html/struct_message_data__coll__graph.map +html/struct_message_data.html +html/struct_m_q_t_t_transport.html +html/struct_m_q_t_t_string__coll__graph.png +html/struct_m_q_t_t_string__coll__graph.md5 +html/struct_m_q_t_t_string__coll__graph.map +html/struct_m_q_t_t_string.html +html/struct_m_q_t_t_packet__will_options__coll__graph.png +html/struct_m_q_t_t_packet__will_options__coll__graph.md5 +html/struct_m_q_t_t_packet__will_options__coll__graph.map +html/struct_m_q_t_t_packet__will_options.html +html/struct_m_q_t_t_packet__connect_data__coll__graph.png +html/struct_m_q_t_t_packet__connect_data__coll__graph.md5 +html/struct_m_q_t_t_packet__connect_data__coll__graph.map +html/struct_m_q_t_t_packet__connect_data.html +html/struct_m_q_t_t_message.html +html/struct_m_q_t_t_len_string.html +html/struct_m_q_t_t_client__coll__graph.png +html/struct_m_q_t_t_client__coll__graph.md5 +html/struct_m_q_t_t_client__coll__graph.map +html/struct_m_q_t_t_client_1_1_message_handlers.html +html/struct_m_q_t_t_client.html +html/struct_command.html +html/struct__st__http__socket.html +html/struct__st__http__request.html +html/struct__ntpformat.html +html/struct__http_server__web_content.html +html/struct__datetime.html +html/struct____file.html +html/struct_____w_i_z_c_h_i_p__coll__graph.png +html/struct_____w_i_z_c_h_i_p__coll__graph.md5 +html/struct_____w_i_z_c_h_i_p__coll__graph.map +html/struct_____w_i_z_c_h_i_p_1_1___c_s.html +html/struct_____w_i_z_c_h_i_p_1_1___c_r_i_s.html +html/struct_____w_i_z_c_h_i_p.html +html/splitbar.png +html/socket_8h_source.html +html/socket_8h__incl.png +html/socket_8h__incl.md5 +html/socket_8h__incl.map +html/socket_8h__dep__incl.png +html/socket_8h__dep__incl.md5 +html/socket_8h__dep__incl.map +html/socket_8h.html +html/socket_8c_source.html +html/socket_8c__incl.png +html/socket_8c__incl.md5 +html/socket_8c__incl.map +html/socket_8c.html +html/sntp_8h_source.html +html/sntp_8h__incl.png +html/sntp_8h__incl.md5 +html/sntp_8h__incl.map +html/sntp_8h__dep__incl.png +html/sntp_8h__dep__incl.md5 +html/sntp_8h__dep__incl.map +html/sntp_8h.html +html/sntp_8c_source.html +html/sntp_8c__incl.png +html/sntp_8c__incl.md5 +html/sntp_8c__incl.map +html/sntp_8c.html +html/snmp__custom_8h_source.html +html/snmp__custom_8h__incl.png +html/snmp__custom_8h__incl.md5 +html/snmp__custom_8h__incl.map +html/snmp__custom_8h__dep__incl.png +html/snmp__custom_8h__dep__incl.md5 +html/snmp__custom_8h__dep__incl.map +html/snmp__custom_8h.html +html/snmp__custom_8c_source.html +html/snmp__custom_8c__incl.png +html/snmp__custom_8c__incl.md5 +html/snmp__custom_8c__incl.map +html/snmp__custom_8c.html +html/snmp_8h_source.html +html/snmp_8h__dep__incl.png +html/snmp_8h__dep__incl.md5 +html/snmp_8h__dep__incl.map +html/snmp_8h.html +html/snmp_8c_source.html +html/snmp_8c__incl.png +html/snmp_8c__incl.md5 +html/snmp_8c__incl.map +html/snmp_8c.html +html/search/variables_f.js +html/search/variables_f.html +html/search/variables_e.js +html/search/variables_e.html +html/search/variables_d.js +html/search/variables_d.html +html/search/variables_c.js +html/search/variables_c.html +html/search/variables_b.js +html/search/variables_b.html +html/search/variables_a.js +html/search/variables_a.html +html/search/variables_9.js +html/search/variables_9.html +html/search/variables_8.js +html/search/variables_8.html +html/search/variables_7.js +html/search/variables_7.html +html/search/variables_6.js +html/search/variables_6.html +html/search/variables_5.js +html/search/variables_5.html +html/search/variables_4.js +html/search/variables_4.html +html/search/variables_3.js +html/search/variables_3.html +html/search/variables_2.js +html/search/variables_2.html +html/search/variables_18.js +html/search/variables_18.html +html/search/variables_17.js +html/search/variables_17.html +html/search/variables_16.js +html/search/variables_16.html +html/search/variables_15.js +html/search/variables_15.html +html/search/variables_14.js +html/search/variables_14.html +html/search/variables_13.js +html/search/variables_13.html +html/search/variables_12.js +html/search/variables_12.html +html/search/variables_11.js +html/search/variables_11.html +html/search/variables_10.js +html/search/variables_10.html +html/search/variables_1.js +html/search/variables_1.html +html/search/variables_0.js +html/search/variables_0.html +html/search/typedefs_9.js +html/search/typedefs_9.html +html/search/typedefs_8.js +html/search/typedefs_8.html +html/search/typedefs_7.js +html/search/typedefs_7.html +html/search/typedefs_6.js +html/search/typedefs_6.html +html/search/typedefs_5.js +html/search/typedefs_5.html +html/search/typedefs_4.js +html/search/typedefs_4.html +html/search/typedefs_3.js +html/search/typedefs_3.html +html/search/typedefs_2.js +html/search/typedefs_2.html +html/search/typedefs_1.js +html/search/typedefs_1.html +html/search/typedefs_0.js +html/search/typedefs_0.html +html/search/searchdata.js +html/search/search_r.png +html/search/search_m.png +html/search/search_l.png +html/search/search.js +html/search/search.css +html/search/pages_2.js +html/search/pages_2.html +html/search/pages_1.js +html/search/pages_1.html +html/search/pages_0.js +html/search/pages_0.html +html/search/nomatches.html +html/search/mag_sel.png +html/search/groups_6.js +html/search/groups_6.html +html/search/groups_5.js +html/search/groups_5.html +html/search/groups_4.js +html/search/groups_4.html +html/search/groups_3.js +html/search/groups_3.html +html/search/groups_2.js +html/search/groups_2.html +html/search/groups_1.js +html/search/groups_1.html +html/search/groups_0.js +html/search/groups_0.html +html/search/functions_f.js +html/search/functions_f.html +html/search/functions_e.js +html/search/functions_e.html +html/search/functions_d.js +html/search/functions_d.html +html/search/functions_c.js +html/search/functions_c.html +html/search/functions_b.js +html/search/functions_b.html +html/search/functions_a.js +html/search/functions_a.html +html/search/functions_9.js +html/search/functions_9.html +html/search/functions_8.js +html/search/functions_8.html +html/search/functions_7.js +html/search/functions_7.html +html/search/functions_6.js +html/search/functions_6.html +html/search/functions_5.js +html/search/functions_5.html +html/search/functions_4.js +html/search/functions_4.html +html/search/functions_3.js +html/search/functions_3.html +html/search/functions_2.js +html/search/functions_2.html +html/search/functions_11.js +html/search/functions_11.html +html/search/functions_10.js +html/search/functions_10.html +html/search/functions_1.js +html/search/functions_1.html +html/search/functions_0.js +html/search/functions_0.html +html/search/files_a.js +html/search/files_a.html +html/search/files_9.js +html/search/files_9.html +html/search/files_8.js +html/search/files_8.html +html/search/files_7.js +html/search/files_7.html +html/search/files_6.js +html/search/files_6.html +html/search/files_5.js +html/search/files_5.html +html/search/files_4.js +html/search/files_4.html +html/search/files_3.js +html/search/files_3.html +html/search/files_2.js +html/search/files_2.html +html/search/files_1.js +html/search/files_1.html +html/search/files_0.js +html/search/files_0.html +html/search/enumvalues_f.js +html/search/enumvalues_f.html +html/search/enumvalues_e.js +html/search/enumvalues_e.html +html/search/enumvalues_d.js +html/search/enumvalues_d.html +html/search/enumvalues_c.js +html/search/enumvalues_c.html +html/search/enumvalues_b.js +html/search/enumvalues_b.html +html/search/enumvalues_a.js +html/search/enumvalues_a.html +html/search/enumvalues_9.js +html/search/enumvalues_9.html +html/search/enumvalues_8.js +html/search/enumvalues_8.html +html/search/enumvalues_7.js +html/search/enumvalues_7.html +html/search/enumvalues_6.js +html/search/enumvalues_6.html +html/search/enumvalues_5.js +html/search/enumvalues_5.html +html/search/enumvalues_4.js +html/search/enumvalues_4.html +html/search/enumvalues_3.js +html/search/enumvalues_3.html +html/search/enumvalues_2.js +html/search/enumvalues_2.html +html/search/enumvalues_12.js +html/search/enumvalues_12.html +html/search/enumvalues_11.js +html/search/enumvalues_11.html +html/search/enumvalues_10.js +html/search/enumvalues_10.html +html/search/enumvalues_1.js +html/search/enumvalues_1.html +html/search/enumvalues_0.js +html/search/enumvalues_0.html +html/search/enums_9.js +html/search/enums_9.html +html/search/enums_8.js +html/search/enums_8.html +html/search/enums_7.js +html/search/enums_7.html +html/search/enums_6.js +html/search/enums_6.html +html/search/enums_5.js +html/search/enums_5.html +html/search/enums_4.js +html/search/enums_4.html +html/search/enums_3.js +html/search/enums_3.html +html/search/enums_2.js +html/search/enums_2.html +html/search/enums_1.js +html/search/enums_1.html +html/search/enums_0.js +html/search/enums_0.html +html/search/defines_f.js +html/search/defines_f.html +html/search/defines_e.js +html/search/defines_e.html +html/search/defines_d.js +html/search/defines_d.html +html/search/defines_c.js +html/search/defines_c.html +html/search/defines_b.js +html/search/defines_b.html +html/search/defines_a.js +html/search/defines_a.html +html/search/defines_9.js +html/search/defines_9.html +html/search/defines_8.js +html/search/defines_8.html +html/search/defines_7.js +html/search/defines_7.html +html/search/defines_6.js +html/search/defines_6.html +html/search/defines_5.js +html/search/defines_5.html +html/search/defines_4.js +html/search/defines_4.html +html/search/defines_3.js +html/search/defines_3.html +html/search/defines_2.js +html/search/defines_2.html +html/search/defines_15.js +html/search/defines_15.html +html/search/defines_14.js +html/search/defines_14.html +html/search/defines_13.js +html/search/defines_13.html +html/search/defines_12.js +html/search/defines_12.html +html/search/defines_11.js +html/search/defines_11.html +html/search/defines_10.js +html/search/defines_10.html +html/search/defines_1.js +html/search/defines_1.html +html/search/defines_0.js +html/search/defines_0.html +html/search/close.png +html/search/classes_8.js +html/search/classes_8.html +html/search/classes_7.js +html/search/classes_7.html +html/search/classes_6.js +html/search/classes_6.html +html/search/classes_5.js +html/search/classes_5.html +html/search/classes_4.js +html/search/classes_4.html +html/search/classes_3.js +html/search/classes_3.html +html/search/classes_2.js +html/search/classes_2.html +html/search/classes_1.js +html/search/classes_1.html +html/search/classes_0.js +html/search/classes_0.html +html/search/all_f.js +html/search/all_f.html +html/search/all_e.js +html/search/all_e.html +html/search/all_d.js +html/search/all_d.html +html/search/all_c.js +html/search/all_c.html +html/search/all_b.js +html/search/all_b.html +html/search/all_a.js +html/search/all_a.html +html/search/all_9.js +html/search/all_9.html +html/search/all_8.js +html/search/all_8.html +html/search/all_7.js +html/search/all_7.html +html/search/all_6.js +html/search/all_6.html +html/search/all_5.js +html/search/all_5.html +html/search/all_4.js +html/search/all_4.html +html/search/all_3.js +html/search/all_3.html +html/search/all_2.js +html/search/all_2.html +html/search/all_1a.js +html/search/all_1a.html +html/search/all_19.js +html/search/all_19.html +html/search/all_18.js +html/search/all_18.html +html/search/all_17.js +html/search/all_17.html +html/search/all_16.js +html/search/all_16.html +html/search/all_15.js +html/search/all_15.html +html/search/all_14.js +html/search/all_14.html +html/search/all_13.js +html/search/all_13.html +html/search/all_12.js +html/search/all_12.html +html/search/all_11.js +html/search/all_11.html +html/search/all_10.js +html/search/all_10.html +html/search/all_1.js +html/search/all_1.html +html/search/all_0.js +html/search/all_0.html +html/pages.html +html/open.png +html/netutil_8h_source.html +html/netutil_8h__incl.png +html/netutil_8h__incl.md5 +html/netutil_8h__incl.map +html/netutil_8h__dep__incl.png +html/netutil_8h__dep__incl.md5 +html/netutil_8h__dep__incl.map +html/netutil_8h.html +html/netutil_8c_source.html +html/netutil_8c__incl.png +html/netutil_8c__incl.md5 +html/netutil_8c__incl.map +html/netutil_8c.html +html/nav_h.png +html/nav_g.png +html/nav_f.png +html/mqtt__interface_8h_source.html +html/mqtt__interface_8h__dep__incl.png +html/mqtt__interface_8h__dep__incl.md5 +html/mqtt__interface_8h__dep__incl.map +html/mqtt__interface_8h.html +html/mqtt__interface_8c_source.html +html/mqtt__interface_8c__incl.png +html/mqtt__interface_8c__incl.md5 +html/mqtt__interface_8c__incl.map +html/mqtt__interface_8c.html +html/modules.html +html/menudata.js +html/menu.js +html/md__r_e_a_d_m_e.html +html/loopback_8h_source.html +html/loopback_8h__incl.png +html/loopback_8h__incl.md5 +html/loopback_8h__incl.map +html/loopback_8h__dep__incl.png +html/loopback_8h__dep__incl.md5 +html/loopback_8h__dep__incl.map +html/loopback_8h.html +html/loopback_8c_source.html +html/loopback_8c__incl.png +html/loopback_8c__incl.md5 +html/loopback_8c__incl.map +html/loopback_8c.html +html/license_8txt.html +html/jquery.js +html/index.html +html/http_util_8h_source.html +html/http_util_8h__incl.png +html/http_util_8h__incl.md5 +html/http_util_8h__incl.map +html/http_util_8h__dep__incl.png +html/http_util_8h__dep__incl.md5 +html/http_util_8h__dep__incl.map +html/http_util_8h.html +html/http_util_8c_source.html +html/http_util_8c__incl.png +html/http_util_8c__incl.md5 +html/http_util_8c__incl.map +html/http_util_8c.html +html/http_server_8h_source.html +html/http_server_8h__incl.png +html/http_server_8h__incl.md5 +html/http_server_8h__incl.map +html/http_server_8h__dep__incl.png +html/http_server_8h__dep__incl.md5 +html/http_server_8h__dep__incl.map +html/http_server_8h.html +html/http_server_8c_source.html +html/http_server_8c__incl.png +html/http_server_8c__incl.md5 +html/http_server_8c__incl.map +html/http_server_8c.html +html/http_parser_8h_source.html +html/http_parser_8h__incl.png +html/http_parser_8h__incl.md5 +html/http_parser_8h__incl.map +html/http_parser_8h__dep__incl.png +html/http_parser_8h__dep__incl.md5 +html/http_parser_8h__dep__incl.map +html/http_parser_8h.html +html/http_parser_8c_source.html +html/http_parser_8c__incl.png +html/http_parser_8c__incl.md5 +html/http_parser_8c__incl.map +html/http_parser_8c.html +html/group__snmp__module.html +html/group__extra__functions.html +html/group___w_i_znet__socket___a_p_is.html +html/group___w_i_z_c_h_i_p__register___w5300.png +html/group___w_i_z_c_h_i_p__register___w5300.md5 +html/group___w_i_z_c_h_i_p__register___w5300.map +html/group___w_i_z_c_h_i_p__register___w5300.html +html/group___w_i_z_c_h_i_p__register___w5200.png +html/group___w_i_z_c_h_i_p__register___w5200.md5 +html/group___w_i_z_c_h_i_p__register___w5200.map +html/group___w_i_z_c_h_i_p__register___w5200.html +html/group___w_i_z_c_h_i_p__register___w5100_s.png +html/group___w_i_z_c_h_i_p__register___w5100_s.md5 +html/group___w_i_z_c_h_i_p__register___w5100_s.map +html/group___w_i_z_c_h_i_p__register___w5100_s.html +html/group___w_i_z_c_h_i_p__register___w5100.png +html/group___w_i_z_c_h_i_p__register___w5100.md5 +html/group___w_i_z_c_h_i_p__register___w5100.map +html/group___w_i_z_c_h_i_p__register___w5100.html +html/group___w_i_z_c_h_i_p__register.png +html/group___w_i_z_c_h_i_p__register.md5 +html/group___w_i_z_c_h_i_p__register.map +html/group___w_i_z_c_h_i_p__register.html +html/group___w_i_z_c_h_i_p___i_o___functions___w5300.png +html/group___w_i_z_c_h_i_p___i_o___functions___w5300.md5 +html/group___w_i_z_c_h_i_p___i_o___functions___w5300.map +html/group___w_i_z_c_h_i_p___i_o___functions___w5300.html +html/group___w_i_z_c_h_i_p___i_o___functions___w5200.png +html/group___w_i_z_c_h_i_p___i_o___functions___w5200.md5 +html/group___w_i_z_c_h_i_p___i_o___functions___w5200.map +html/group___w_i_z_c_h_i_p___i_o___functions___w5200.html +html/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.png +html/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.md5 +html/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.map +html/group___w_i_z_c_h_i_p___i_o___functions___w5100_s.html +html/group___w_i_z_c_h_i_p___i_o___functions___w5100.png +html/group___w_i_z_c_h_i_p___i_o___functions___w5100.md5 +html/group___w_i_z_c_h_i_p___i_o___functions___w5100.map +html/group___w_i_z_c_h_i_p___i_o___functions___w5100.html +html/group___w_i_z_c_h_i_p___i_o___functions.png +html/group___w_i_z_c_h_i_p___i_o___functions.md5 +html/group___w_i_z_c_h_i_p___i_o___functions.map +html/group___w_i_z_c_h_i_p___i_o___functions.html +html/group___w5500.png +html/group___w5500.md5 +html/group___w5500.map +html/group___w5500.html +html/group___w5300.png +html/group___w5300.md5 +html/group___w5300.map +html/group___w5300.html +html/group___w5200.png +html/group___w5200.md5 +html/group___w5200.map +html/group___w5200.html +html/group___w5100_s.png +html/group___w5100_s.md5 +html/group___w5100_s.map +html/group___w5100_s.html +html/group___w5100.png +html/group___w5100.md5 +html/group___w5100.map +html/group___w5100.html +html/group___special__function___w5100_s.png +html/group___special__function___w5100_s.md5 +html/group___special__function___w5100_s.map +html/group___special__function___w5100_s.html +html/group___socket__register__group___w5300.png +html/group___socket__register__group___w5300.md5 +html/group___socket__register__group___w5300.map +html/group___socket__register__group___w5300.html +html/group___socket__register__group___w5200.png +html/group___socket__register__group___w5200.md5 +html/group___socket__register__group___w5200.map +html/group___socket__register__group___w5200.html +html/group___socket__register__group___w5100_s.png +html/group___socket__register__group___w5100_s.md5 +html/group___socket__register__group___w5100_s.map +html/group___socket__register__group___w5100_s.html +html/group___socket__register__group___w5100.png +html/group___socket__register__group___w5100.md5 +html/group___socket__register__group___w5100.map +html/group___socket__register__group___w5100.html +html/group___socket__register__group.png +html/group___socket__register__group.md5 +html/group___socket__register__group.map +html/group___socket__register__group.html +html/group___socket__register__access__function___w5300.png +html/group___socket__register__access__function___w5300.md5 +html/group___socket__register__access__function___w5300.map +html/group___socket__register__access__function___w5300.html +html/group___socket__register__access__function___w5200.png +html/group___socket__register__access__function___w5200.md5 +html/group___socket__register__access__function___w5200.map +html/group___socket__register__access__function___w5200.html +html/group___socket__register__access__function___w5100_s.png +html/group___socket__register__access__function___w5100_s.md5 +html/group___socket__register__access__function___w5100_s.map +html/group___socket__register__access__function___w5100_s.html +html/group___socket__register__access__function___w5100.png +html/group___socket__register__access__function___w5100.md5 +html/group___socket__register__access__function___w5100.map +html/group___socket__register__access__function___w5100.html +html/group___socket__register__access__function.png +html/group___socket__register__access__function.md5 +html/group___socket__register__access__function.map +html/group___socket__register__access__function.html +html/group___d_a_t_a___t_y_p_e.html +html/group___common__register__group___w5300.png +html/group___common__register__group___w5300.md5 +html/group___common__register__group___w5300.map +html/group___common__register__group___w5300.html +html/group___common__register__group___w5200.png +html/group___common__register__group___w5200.md5 +html/group___common__register__group___w5200.map +html/group___common__register__group___w5200.html +html/group___common__register__group___w5100_s.png +html/group___common__register__group___w5100_s.md5 +html/group___common__register__group___w5100_s.map +html/group___common__register__group___w5100_s.html +html/group___common__register__group___w5100.png +html/group___common__register__group___w5100.md5 +html/group___common__register__group___w5100.map +html/group___common__register__group___w5100.html +html/group___common__register__group.png +html/group___common__register__group.md5 +html/group___common__register__group.map +html/group___common__register__group.html +html/group___common__register__access__function___w5300.png +html/group___common__register__access__function___w5300.md5 +html/group___common__register__access__function___w5300.map +html/group___common__register__access__function___w5300.html +html/group___common__register__access__function___w5200.png +html/group___common__register__access__function___w5200.md5 +html/group___common__register__access__function___w5200.map +html/group___common__register__access__function___w5200.html +html/group___common__register__access__function___w5100_s.png +html/group___common__register__access__function___w5100_s.md5 +html/group___common__register__access__function___w5100_s.map +html/group___common__register__access__function___w5100_s.html +html/group___common__register__access__function___w5100.png +html/group___common__register__access__function___w5100.md5 +html/group___common__register__access__function___w5100.map +html/group___common__register__access__function___w5100.html +html/group___common__register__access__function.png +html/group___common__register__access__function.md5 +html/group___common__register__access__function.map +html/group___common__register__access__function.html +html/group___basic___i_o__function___w5300.png +html/group___basic___i_o__function___w5300.md5 +html/group___basic___i_o__function___w5300.map +html/group___basic___i_o__function___w5300.html +html/group___basic___i_o__function___w5200.png +html/group___basic___i_o__function___w5200.md5 +html/group___basic___i_o__function___w5200.map +html/group___basic___i_o__function___w5200.html +html/group___basic___i_o__function___w5100_s.png +html/group___basic___i_o__function___w5100_s.md5 +html/group___basic___i_o__function___w5100_s.map +html/group___basic___i_o__function___w5100_s.html +html/group___basic___i_o__function___w5100.png +html/group___basic___i_o__function___w5100.md5 +html/group___basic___i_o__function___w5100.map +html/group___basic___i_o__function___w5100.html +html/group___basic___i_o__function.png +html/group___basic___i_o__function.md5 +html/group___basic___i_o__function.map +html/group___basic___i_o__function.html +html/graph_legend.png +html/graph_legend.md5 +html/graph_legend.html +html/globals_x.html +html/globals_w.html +html/globals_vars.html +html/globals_v.html +html/globals_u.html +html/globals_type.html +html/globals_t.html +html/globals_s.html +html/globals_r.html +html/globals_q.html +html/globals_p.html +html/globals_o.html +html/globals_n.html +html/globals_m.html +html/globals_l.html +html/globals_k.html +html/globals_i.html +html/globals_h.html +html/globals_g.html +html/globals_func_w.html +html/globals_func_u.html +html/globals_func_t.html +html/globals_func_s.html +html/globals_func_r.html +html/globals_func_p.html +html/globals_func_n.html +html/globals_func_m.html +html/globals_func_l.html +html/globals_func_k.html +html/globals_func_i.html +html/globals_func_h.html +html/globals_func_g.html +html/globals_func_f.html +html/globals_func_d.html +html/globals_func_c.html +html/globals_func_b.html +html/globals_func.html +html/globals_f.html +html/globals_eval_x.html +html/globals_eval_v.html +html/globals_eval_u.html +html/globals_eval_t.html +html/globals_eval_s.html +html/globals_eval_r.html +html/globals_eval_q.html +html/globals_eval_p.html +html/globals_eval_n.html +html/globals_eval_m.html +html/globals_eval_l.html +html/globals_eval_i.html +html/globals_eval_h.html +html/globals_eval_f.html +html/globals_eval_e.html +html/globals_eval_d.html +html/globals_eval_c.html +html/globals_eval_b.html +html/globals_eval.html +html/globals_enum.html +html/globals_e.html +html/globals_defs_w.html +html/globals_defs_v.html +html/globals_defs_u.html +html/globals_defs_t.html +html/globals_defs_s.html +html/globals_defs_r.html +html/globals_defs_q.html +html/globals_defs_p.html +html/globals_defs_o.html +html/globals_defs_n.html +html/globals_defs_m.html +html/globals_defs_l.html +html/globals_defs_i.html +html/globals_defs_h.html +html/globals_defs_g.html +html/globals_defs_f.html +html/globals_defs_e.html +html/globals_defs_d.html +html/globals_defs_c.html +html/globals_defs_b.html +html/globals_defs_a.html +html/globals_defs.html +html/globals_d.html +html/globals_c.html +html/globals_b.html +html/globals_a.html +html/globals.html +html/functions_y.html +html/functions_x.html +html/functions_w.html +html/functions_vars_y.html +html/functions_vars_x.html +html/functions_vars_w.html +html/functions_vars_v.html +html/functions_vars_u.html +html/functions_vars_t.html +html/functions_vars_s.html +html/functions_vars_r.html +html/functions_vars_q.html +html/functions_vars_p.html +html/functions_vars_o.html +html/functions_vars_n.html +html/functions_vars_m.html +html/functions_vars_l.html +html/functions_vars_k.html +html/functions_vars_i.html +html/functions_vars_h.html +html/functions_vars_g.html +html/functions_vars_f.html +html/functions_vars_e.html +html/functions_vars_d.html +html/functions_vars_c.html +html/functions_vars_b.html +html/functions_vars_a.html +html/functions_vars.html +html/functions_v.html +html/functions_u.html +html/functions_t.html +html/functions_s.html +html/functions_r.html +html/functions_q.html +html/functions_p.html +html/functions_o.html +html/functions_n.html +html/functions_m.html +html/functions_l.html +html/functions_k.html +html/functions_i.html +html/functions_h.html +html/functions_g.html +html/functions_f.html +html/functions_e.html +html/functions_d.html +html/functions_c.html +html/functions_b.html +html/functions_a.html +html/functions.html +html/ftpd_8h_source.html +html/ftpd_8h__incl.png +html/ftpd_8h__incl.md5 +html/ftpd_8h__incl.map +html/ftpd_8h__dep__incl.png +html/ftpd_8h__dep__incl.md5 +html/ftpd_8h__dep__incl.map +html/ftpd_8h.html +html/ftpd_8c_source.html +html/ftpd_8c__incl.png +html/ftpd_8c__incl.md5 +html/ftpd_8c__incl.map +html/ftpd_8c.html +html/ftpc_8h_source.html +html/ftpc_8h__incl.png +html/ftpc_8h__incl.md5 +html/ftpc_8h__incl.map +html/ftpc_8h__dep__incl.png +html/ftpc_8h__dep__incl.md5 +html/ftpc_8h__dep__incl.map +html/ftpc_8h.html +html/ftpc_8c_source.html +html/ftpc_8c__incl.png +html/ftpc_8c__incl.md5 +html/ftpc_8c__incl.map +html/ftpc_8c.html +html/folderopen.png +html/folderclosed.png +html/files.html +html/dynsections.js +html/doxygen__log_8txt.html +html/doxygen.png +html/doxygen.css +html/doc.png +html/dns_8h_source.html +html/dns_8h__incl.png +html/dns_8h__incl.md5 +html/dns_8h__incl.map +html/dns_8h__dep__incl.png +html/dns_8h__dep__incl.md5 +html/dns_8h__dep__incl.map +html/dns_8h.html +html/dns_8c_source.html +html/dns_8c__incl.png +html/dns_8c__incl.md5 +html/dns_8c__incl.map +html/dns_8c.html +html/dir_fe682d1d76c251404f71241aa833642c_dep.png +html/dir_fe682d1d76c251404f71241aa833642c_dep.md5 +html/dir_fe682d1d76c251404f71241aa833642c_dep.map +html/dir_fe682d1d76c251404f71241aa833642c.html +html/dir_fca0adf6655fb1759a15e5776097c124_dep.png +html/dir_fca0adf6655fb1759a15e5776097c124_dep.md5 +html/dir_fca0adf6655fb1759a15e5776097c124_dep.map +html/dir_fca0adf6655fb1759a15e5776097c124.html +html/dir_f841453af36a2df9a2123f87589fe4f8_dep.png +html/dir_f841453af36a2df9a2123f87589fe4f8_dep.md5 +html/dir_f841453af36a2df9a2123f87589fe4f8_dep.map +html/dir_f841453af36a2df9a2123f87589fe4f8.html +html/dir_f10a527ab5b3936e2edf95a019a13ec7_dep.png +html/dir_f10a527ab5b3936e2edf95a019a13ec7_dep.md5 +html/dir_f10a527ab5b3936e2edf95a019a13ec7_dep.map +html/dir_f10a527ab5b3936e2edf95a019a13ec7.html +html/dir_eb1463819d84903762eb6f59cc0c4383_dep.png +html/dir_eb1463819d84903762eb6f59cc0c4383_dep.md5 +html/dir_eb1463819d84903762eb6f59cc0c4383_dep.map +html/dir_eb1463819d84903762eb6f59cc0c4383.html +html/dir_e5121bff4754a4ad570fa548a998f0c5_dep.png +html/dir_e5121bff4754a4ad570fa548a998f0c5_dep.md5 +html/dir_e5121bff4754a4ad570fa548a998f0c5_dep.map +html/dir_e5121bff4754a4ad570fa548a998f0c5.html +html/dir_b88037d6581d528000057b4eaec3e673_dep.png +html/dir_b88037d6581d528000057b4eaec3e673_dep.md5 +html/dir_b88037d6581d528000057b4eaec3e673_dep.map +html/dir_b88037d6581d528000057b4eaec3e673.html +html/dir_a5a06f90a751e77147778694c516f622_dep.png +html/dir_a5a06f90a751e77147778694c516f622_dep.md5 +html/dir_a5a06f90a751e77147778694c516f622_dep.map +html/dir_a5a06f90a751e77147778694c516f622.html +html/dir_a483286db9c12f74c7364bdaa9e78c36_dep.png +html/dir_a483286db9c12f74c7364bdaa9e78c36_dep.md5 +html/dir_a483286db9c12f74c7364bdaa9e78c36_dep.map +html/dir_a483286db9c12f74c7364bdaa9e78c36.html +html/dir_a138ed074e64356ad02dbb8d94382c4f_dep.png +html/dir_a138ed074e64356ad02dbb8d94382c4f_dep.md5 +html/dir_a138ed074e64356ad02dbb8d94382c4f_dep.map +html/dir_a138ed074e64356ad02dbb8d94382c4f.html +html/dir_97b8cbb23222306012bd2d84398746c9_dep.png +html/dir_97b8cbb23222306012bd2d84398746c9_dep.md5 +html/dir_97b8cbb23222306012bd2d84398746c9_dep.map +html/dir_97b8cbb23222306012bd2d84398746c9.html +html/dir_6e6e4d5e89221ed61dd87b2954f72a78_dep.png +html/dir_6e6e4d5e89221ed61dd87b2954f72a78_dep.md5 +html/dir_6e6e4d5e89221ed61dd87b2954f72a78_dep.map +html/dir_6e6e4d5e89221ed61dd87b2954f72a78.html +html/dir_6de1940466803d61d2f9d1259cb01031.html +html/dir_5a912e51f6f9520965e8671f07512599_dep.png +html/dir_5a912e51f6f9520965e8671f07512599_dep.md5 +html/dir_5a912e51f6f9520965e8671f07512599_dep.map +html/dir_5a912e51f6f9520965e8671f07512599.html +html/dir_4c7002aef9ece892c0aedd728ed93eff.html +html/dir_498fbcdef69ea105b96b8673d051b2e3_dep.png +html/dir_498fbcdef69ea105b96b8673d051b2e3_dep.md5 +html/dir_498fbcdef69ea105b96b8673d051b2e3_dep.map +html/dir_498fbcdef69ea105b96b8673d051b2e3.html +html/dir_46819ec1095f3903911c103f5ebbb29f_dep.png +html/dir_46819ec1095f3903911c103f5ebbb29f_dep.md5 +html/dir_46819ec1095f3903911c103f5ebbb29f_dep.map +html/dir_46819ec1095f3903911c103f5ebbb29f.html +html/dir_4396dcc0e095a5bc10b1affe087807cf_dep.png +html/dir_4396dcc0e095a5bc10b1affe087807cf_dep.md5 +html/dir_4396dcc0e095a5bc10b1affe087807cf_dep.map +html/dir_4396dcc0e095a5bc10b1affe087807cf.html +html/dir_337e147d8ae2958ef29ccaa8e2f968db_dep.png +html/dir_337e147d8ae2958ef29ccaa8e2f968db_dep.md5 +html/dir_337e147d8ae2958ef29ccaa8e2f968db_dep.map +html/dir_337e147d8ae2958ef29ccaa8e2f968db.html +html/dir_2c7bb40a7e5a6685f00216dd2909cd99_dep.png +html/dir_2c7bb40a7e5a6685f00216dd2909cd99_dep.md5 +html/dir_2c7bb40a7e5a6685f00216dd2909cd99_dep.map +html/dir_2c7bb40a7e5a6685f00216dd2909cd99.html +html/dir_2c1dd796c287ab9a5cf44281d8a3cbeb.html +html/dir_072fcb7a67163ce1d8f22ad4144c7e08.html +html/dir_000020_000002.html +html/dir_000019_000002.html +html/dir_000018_000002.html +html/dir_000017_000002.html +html/dir_000015_000016.html +html/dir_000015_000002.html +html/dir_000014_000015.html +html/dir_000014_000002.html +html/dir_000013_000002.html +html/dir_000012_000002.html +html/dir_000011_000002.html +html/dir_000010_000002.html +html/dir_000009_000002.html +html/dir_000002_000007.html +html/dir_000002_000004.html +html/dir_000001_000002.html +html/dhcp_8h_source.html +html/dhcp_8h__dep__incl.png +html/dhcp_8h__dep__incl.md5 +html/dhcp_8h__dep__incl.map +html/dhcp_8h.html +html/dhcp_8c_source.html +html/dhcp_8c__incl.png +html/dhcp_8c__incl.md5 +html/dhcp_8c__incl.map +html/dhcp_8c.html +html/closed.png +html/classes.html +html/bdwn.png +html/bc_s.png +html/annotated.html +html/_w_i_znet___s_o_c_k_e_t_8jpg_source.html +html/_w_i_znet___s_o_c_k_e_t_8jpg.html +html/_stack_trace_8h_source.html +html/_stack_trace_8h__incl.png +html/_stack_trace_8h__incl.md5 +html/_stack_trace_8h__incl.map +html/_stack_trace_8h__dep__incl.png +html/_stack_trace_8h__dep__incl.md5 +html/_stack_trace_8h__dep__incl.map +html/_stack_trace_8h.html +html/_readme_8txt.html +html/_r_e_a_d_m_e_8md_source.html +html/_r_e_a_d_m_e_8md.html +html/_main__page_8txt.html +html/_m_q_t_t_unsubscribe_server_8c_source.html +html/_m_q_t_t_unsubscribe_server_8c__incl.png +html/_m_q_t_t_unsubscribe_server_8c__incl.md5 +html/_m_q_t_t_unsubscribe_server_8c__incl.map +html/_m_q_t_t_unsubscribe_server_8c.html +html/_m_q_t_t_unsubscribe_client_8c_source.html +html/_m_q_t_t_unsubscribe_client_8c__incl.png +html/_m_q_t_t_unsubscribe_client_8c__incl.md5 +html/_m_q_t_t_unsubscribe_client_8c__incl.map +html/_m_q_t_t_unsubscribe_client_8c.html +html/_m_q_t_t_unsubscribe_8h_source.html +html/_m_q_t_t_unsubscribe_8h__dep__incl.png +html/_m_q_t_t_unsubscribe_8h__dep__incl.md5 +html/_m_q_t_t_unsubscribe_8h__dep__incl.map +html/_m_q_t_t_unsubscribe_8h.html +html/_m_q_t_t_subscribe_server_8c_source.html +html/_m_q_t_t_subscribe_server_8c__incl.png +html/_m_q_t_t_subscribe_server_8c__incl.md5 +html/_m_q_t_t_subscribe_server_8c__incl.map +html/_m_q_t_t_subscribe_server_8c.html +html/_m_q_t_t_subscribe_client_8c_source.html +html/_m_q_t_t_subscribe_client_8c__incl.png +html/_m_q_t_t_subscribe_client_8c__incl.md5 +html/_m_q_t_t_subscribe_client_8c__incl.map +html/_m_q_t_t_subscribe_client_8c.html +html/_m_q_t_t_subscribe_8h_source.html +html/_m_q_t_t_subscribe_8h__dep__incl.png +html/_m_q_t_t_subscribe_8h__dep__incl.md5 +html/_m_q_t_t_subscribe_8h__dep__incl.map +html/_m_q_t_t_subscribe_8h.html +html/_m_q_t_t_serialize_publish_8c_source.html +html/_m_q_t_t_serialize_publish_8c__incl.png +html/_m_q_t_t_serialize_publish_8c__incl.md5 +html/_m_q_t_t_serialize_publish_8c__incl.map +html/_m_q_t_t_serialize_publish_8c.html +html/_m_q_t_t_publish_8h_source.html +html/_m_q_t_t_publish_8h__dep__incl.png +html/_m_q_t_t_publish_8h__dep__incl.md5 +html/_m_q_t_t_publish_8h__dep__incl.map +html/_m_q_t_t_publish_8h.html +html/_m_q_t_t_packet_8h_source.html +html/_m_q_t_t_packet_8h__incl.png +html/_m_q_t_t_packet_8h__incl.md5 +html/_m_q_t_t_packet_8h__incl.map +html/_m_q_t_t_packet_8h__dep__incl.png +html/_m_q_t_t_packet_8h__dep__incl.md5 +html/_m_q_t_t_packet_8h__dep__incl.map +html/_m_q_t_t_packet_8h.html +html/_m_q_t_t_packet_8c_source.html +html/_m_q_t_t_packet_8c__incl.png +html/_m_q_t_t_packet_8c__incl.md5 +html/_m_q_t_t_packet_8c__incl.map +html/_m_q_t_t_packet_8c.html +html/_m_q_t_t_format_8h_source.html +html/_m_q_t_t_format_8h__incl.png +html/_m_q_t_t_format_8h__incl.md5 +html/_m_q_t_t_format_8h__incl.map +html/_m_q_t_t_format_8h__dep__incl.png +html/_m_q_t_t_format_8h__dep__incl.md5 +html/_m_q_t_t_format_8h__dep__incl.map +html/_m_q_t_t_format_8h.html +html/_m_q_t_t_format_8c_source.html +html/_m_q_t_t_format_8c__incl.png +html/_m_q_t_t_format_8c__incl.md5 +html/_m_q_t_t_format_8c__incl.map +html/_m_q_t_t_format_8c.html +html/_m_q_t_t_deserialize_publish_8c_source.html +html/_m_q_t_t_deserialize_publish_8c__incl.png +html/_m_q_t_t_deserialize_publish_8c__incl.md5 +html/_m_q_t_t_deserialize_publish_8c__incl.map +html/_m_q_t_t_deserialize_publish_8c.html +html/_m_q_t_t_connect_server_8c_source.html +html/_m_q_t_t_connect_server_8c__incl.png +html/_m_q_t_t_connect_server_8c__incl.md5 +html/_m_q_t_t_connect_server_8c__incl.map +html/_m_q_t_t_connect_server_8c.html +html/_m_q_t_t_connect_client_8c_source.html +html/_m_q_t_t_connect_client_8c__incl.png +html/_m_q_t_t_connect_client_8c__incl.md5 +html/_m_q_t_t_connect_client_8c__incl.map +html/_m_q_t_t_connect_client_8c.html +html/_m_q_t_t_connect_8h_source.html +html/_m_q_t_t_connect_8h__dep__incl.png +html/_m_q_t_t_connect_8h__dep__incl.md5 +html/_m_q_t_t_connect_8h__dep__incl.map +html/_m_q_t_t_connect_8h.html +html/_m_q_t_t_client_8h_source.html +html/_m_q_t_t_client_8h__incl.png +html/_m_q_t_t_client_8h__incl.md5 +html/_m_q_t_t_client_8h__incl.map +html/_m_q_t_t_client_8h__dep__incl.png +html/_m_q_t_t_client_8h__dep__incl.md5 +html/_m_q_t_t_client_8h__dep__incl.map +html/_m_q_t_t_client_8h.html +html/_m_q_t_t_client_8c_source.html +html/_m_q_t_t_client_8c__incl.png +html/_m_q_t_t_client_8c__incl.md5 +html/_m_q_t_t_client_8c__incl.map +html/_m_q_t_t_client_8c.html +html/_f_t_p_server_2stdio__private_8h_source.html +html/_f_t_p_server_2stdio__private_8h__incl.png +html/_f_t_p_server_2stdio__private_8h__incl.md5 +html/_f_t_p_server_2stdio__private_8h__incl.map +html/_f_t_p_server_2stdio__private_8h__dep__incl.png +html/_f_t_p_server_2stdio__private_8h__dep__incl.md5 +html/_f_t_p_server_2stdio__private_8h__dep__incl.map +html/_f_t_p_server_2stdio__private_8h.html +html/_f_t_p_client_2stdio__private_8h_source.html +html/_f_t_p_client_2stdio__private_8h__incl.png +html/_f_t_p_client_2stdio__private_8h__incl.md5 +html/_f_t_p_client_2stdio__private_8h__incl.map +html/_f_t_p_client_2stdio__private_8h__dep__incl.png +html/_f_t_p_client_2stdio__private_8h__dep__incl.md5 +html/_f_t_p_client_2stdio__private_8h__dep__incl.map +html/_f_t_p_client_2stdio__private_8h.html +html/_berkeley___s_o_c_k_e_t_8jpg_source.html +html/_berkeley___s_o_c_k_e_t_8jpg.html +html/WIZnet_SOCKET.jpg +html/Berkeley_SOCKET.jpg +Main_page.txt +Doxyfile +man/man3/sntp.c.3 +man/man3/snmp_module.3 +man/man3/snmp_custom.h.3 +man/man3/snmp_custom.c.3 +man/man3/snmp.h.3 +man/man3/snmp.c.3 +man/man3/netutil.h.3 +man/man3/netutil.c.3 +man/man3/mqtt_interface.h.3 +man/man3/mqtt_interface.c.3 +man/man3/messageStruct.3 +man/man3/md__r_e_a_d_m_e.3 +man/man3/loopback.h.3 +man/man3/loopback.c.3 +man/man3/license.txt.3 +man/man3/httpUtil.h.3 +man/man3/_datetime.3 +man/man3/__file.3 +man/man3/__WIZCHIP__IF.3 +man/man3/__WIZCHIP__CS.3 +man/man3/__WIZCHIP__CRIS.3 +man/man3/__WIZCHIP.3 +man/man3/WIZnet_socket_APIs.3 +man/man3/WIZnet_SOCKET.jpg.3 +man/man3/WIZCHIP_register.3 +man/man3/WIZCHIP_IO_Functions_W5300.3 +man/man3/WIZCHIP_IO_Functions_W5200.3 +man/man3/WIZCHIP_IO_Functions_W5100S.3 +man/man3/W5500.3 +man/man3/W5300.3 +man/man3/W5100S.3 +man/man3/w5200.c.3 +man/man3/w5100s.h.3 +man/man3/w5100s.c.3 +man/man3/w5100.h.3 +man/man3/w5100.c.3 +man/man3/todo.3 +man/man3/tlvStructType.3 +man/man3/tftp_option.3 +man/man3/tftp_error.3 +man/man3/tftp_data.3 +man/man3/tftp.h.3 +man/man3/tftp.c.3 +man/man3/stdio_private.h.3 +man/man3/socket.h.3 +man/man3/socket.c.3 +man/man3/sntp.h.3 +man/man3/httpUtil.c.3 +man/man3/httpServer.h.3 +man/man3/httpServer.c.3 +man/man3/httpParser.h.3 +man/man3/httpParser.c.3 +man/man3/ftpd.h.3 +man/man3/ftpd.c.3 +man/man3/ftpd.3 +man/man3/WIZCHIP_register_W5300.3 +man/man3/WIZCHIP_register_W5200.3 +man/man3/WIZCHIP_register_W5100S.3 +man/man3/WIZCHIP_register_W5100.3 +man/man3/WIZCHIP_IO_Functions_W5100.3 +man/man3/WIZCHIP_IO_Functions.3 +man/man3/W5200.3 diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.c new file mode 100755 index 00000000000..a921092b494 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.c @@ -0,0 +1,225 @@ +#include +#include "loopback.h" +#include "socket.h" +#include "wizchip_conf.h" + +#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK + +int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port) +{ + int32_t ret; + uint16_t size = 0, sentsize=0; + +#ifdef _LOOPBACK_DEBUG_ + uint8_t destip[4]; + uint16_t destport; +#endif + + switch(getSn_SR(sn)) + { + case SOCK_ESTABLISHED : + if(getSn_IR(sn) & Sn_IR_CON) + { +#ifdef _LOOPBACK_DEBUG_ + getSn_DIPR(sn, destip); + destport = getSn_DPORT(sn); + + printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + setSn_IR(sn,Sn_IR_CON); + } + if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recv(sn, buf, size); + + if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY. + size = (uint16_t) ret; + sentsize = 0; + + while(size != sentsize) + { + ret = send(sn, buf+sentsize, size-sentsize); + if(ret < 0) + { + close(sn); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSE_WAIT : +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:CloseWait\r\n",sn); +#endif + if((ret = disconnect(sn)) != SOCK_OK) return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Socket Closed\r\n", sn); +#endif + break; + case SOCK_INIT : +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port); +#endif + if( (ret = listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:TCP server loopback start\r\n",sn); +#endif + if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:Socket opened\r\n",sn); +#endif + break; + default: + break; + } + return 1; +} + + +int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) +{ + int32_t ret; // return value for SOCK_ERRORs + uint16_t size = 0, sentsize=0; + + // Destination (TCP Server) IP info (will be connected) + // >> loopback_tcpc() function parameter + // >> Ex) + // uint8_t destip[4] = {192, 168, 0, 214}; + // uint16_t destport = 5000; + + // Port number for TCP client (will be increased) + static uint16_t any_port = 50000; + + // Socket Status Transitions + // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status) + switch(getSn_SR(sn)) + { + case SOCK_ESTABLISHED : + if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1' + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + // Data Transaction Parts; Handle the [data receive and send] process + ////////////////////////////////////////////////////////////////////////////////////////////// + if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array) + ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer) + + if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end + size = (uint16_t) ret; + sentsize = 0; + + // Data sentsize control + while(size != sentsize) + { + ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer) + if(ret < 0) // Send Error occurred (sent data length < 0) + { + close(sn); // socket close + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + ////////////////////////////////////////////////////////////////////////////////////////////// + break; + + case SOCK_CLOSE_WAIT : +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:CloseWait\r\n",sn); +#endif + if((ret=disconnect(sn)) != SOCK_OK) return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Socket Closed\r\n", sn); +#endif + break; + + case SOCK_INIT : +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination) + break; + + case SOCK_CLOSED: + close(sn); + if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn){ + if(any_port == 0xffff) any_port = 50000; + return ret; // TCP socket open with 'any_port' port number + } +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:TCP client loopback start\r\n",sn); + //printf("%d:Socket opened\r\n",sn); +#endif + break; + default: + break; + } + return 1; +} + + +int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port) +{ + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + + switch(getSn_SR(sn)) + { + case SOCK_UDP : + if((size = getSn_RX_RSR(sn)) > 0) + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport); + if(ret <= 0) + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d: recvfrom error. %ld\r\n",sn,ret); +#endif + return ret; + } + size = (uint16_t) ret; + sentsize = 0; + while(sentsize != size) + { + ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport); + if(ret < 0) + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d: sendto error. %ld\r\n",sn,ret); +#endif + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:UDP loopback start\r\n",sn); +#endif + if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn) + return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port); +#endif + break; + default : + break; + } + return 1; +} + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.h b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.h new file mode 100755 index 00000000000..8f5a3d6861d --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/loopback/loopback.h @@ -0,0 +1,38 @@ +#ifndef _LOOPBACK_H_ +#define _LOOPBACK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Loopback test debug message printout enable */ +#define _LOOPBACK_DEBUG_ + +/* DATA_BUF_SIZE define for Loopback example */ +#ifndef DATA_BUF_SIZE + #define DATA_BUF_SIZE 2048 +#endif + +/************************/ +/* Select LOOPBACK_MODE */ +/************************/ +#define LOOPBACK_MAIN_NOBLOCK 0 +#define LOOPBACK_MODE LOOPBACK_MAIN_NOBLOCK + + +/* TCP server Loopback test example */ +int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port); + +/* TCP client Loopback test example */ +int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport); + +/* UDP Loopback test example */ +int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/multicast/multicast.c b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/multicast/multicast.c new file mode 100755 index 00000000000..6b9aff02e18 --- /dev/null +++ b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Application/multicast/multicast.c @@ -0,0 +1,113 @@ +#include "multicast.h" +#include +#include "socket.h" +#include "wizchip_conf.h" + + +int32_t multicast_loopback(uint8_t sn, uint8_t* buf, uint8_t* multicast_ip, uint16_t multicast_port) +{ + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport, port=3000; + + switch(getSn_SR(sn)) + { + case SOCK_UDP : + if((size = getSn_RX_RSR(sn)) > 0) + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport); + if(ret <= 0) + { +#ifdef _MULTICAST_DEBUG_ + printf("%d: recvfrom error. %ld\r\n",sn,ret); +#endif + return ret; + } + size = (uint16_t) ret; + sentsize = 0; + while(sentsize != size) + { + ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport); + if(ret < 0) + { +#ifdef _MULTICAST_DEBUG_ + printf("%d: sendto error. %ld\r\n",sn,ret); +#endif + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + + break; + case SOCK_CLOSED: +#ifdef _MULTICAST_DEBUG_ + printf("%d:Multicast Loopback start\r\n",sn); +#endif + setSn_DIPR(0, multicast_ip); + setSn_DPORT(0, multicast_port); + if((ret = socket(sn, Sn_MR_UDP, port, Sn_MR_MULTI)) != sn) + return ret; +#ifdef _MULTICAST_DEBUG_ + printf("%d:Opened, UDP Multicast Socket\r\n", sn); + printf("%d:Multicast Group IP - %d.%d.%d.%d\r\n", sn, multicast_ip[0], multicast_ip[1], multicast_ip[2], multicast_ip[3]); + printf("%d:Multicast Group Port - %d\r\n", sn, multicast_port); +#endif + break; + default : + break; + } + return 1; +} + +int32_t multicast_recv(uint8_t sn, uint8_t* buf, uint8_t* multicast_ip, uint16_t multicast_port) +{ + int32_t ret; + uint16_t size, port=3000; + uint8_t destip[4]; + uint16_t destport; + + switch(getSn_SR(sn)) + { + case SOCK_UDP : + if((size = getSn_RX_RSR(sn)) > 0) + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport); + if(ret <= 0) + { +#ifdef _MULTICAST_DEBUG_ + printf("%d: recvfrom error. %ld\r\n",sn,ret); +#endif + return ret; + } + size = (uint16_t) ret; +#ifdef _MULTICAST_DEBUG_ + printf("\r\nrecv size : %d\r\n", size); + for(int i=0; i + +/* Multicast test debug message printout enable */ +#define _MULTICAST_DEBUG_ + +#ifndef DATA_BUF_SIZE + #define DATA_BUF_SIZE 2048 +#endif + +/* UDP Multicast Loopback test example */ +int32_t multicast_loopback(uint8_t sn, uint8_t* buf, uint8_t* multicast_ip, uint16_t multicast_port); + +/* UDP Multicast Recv test example */ +int32_t multicast_recv(uint8_t sn, uint8_t* buf, uint8_t* multicast_ip, uint16_t multicast_port); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/Socket_APIs_V3.0.3.chm b/non_catalog_apps/eth_troubleshooter/lib/ioLibrary_Driver/Ethernet/Socket_APIs_V3.0.3.chm new file mode 100755 index 0000000000000000000000000000000000000000..35ed51287ff1af9b935d50349eef01ce1b344340 GIT binary patch literal 1435546 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%0Af2pDJoX&<$1ME`g=iS#mk*M3G4Y(|3 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�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 literal 0 HcmV?d00001 diff --git a/non_catalog_apps/eth_troubleshooter/docs/w5500-lite-assembled-top.jpg b/non_catalog_apps/eth_troubleshooter/docs/w5500-lite-assembled-top.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4932ea90e3f09a78f82de5054a91ce929f8cc35c GIT binary patch literal 217569 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