Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 89-apps-should-be-able-to-specify-if-they-want-wifi-to-be-disabled-when-entering-them
  • 9Rmain
  • allow-reloading-sunmenu
  • always-have-a-wifi-instance
  • anon/gpndemo
  • anon/update-sim
  • anon/webflasher
  • app_text_viewer
  • audio_input
  • audio_io
  • blm_dev_chan
  • ch3/bl00mbox_docs
  • ci-1690580595
  • dev_p4
  • dev_p4-iggy
  • dev_p4-iggy-rebased
  • dx/dldldld
  • dx/fb-save-restore
  • dx/hint-hint
  • dx/jacksense-headset-mic-only
  • events
  • fil3s-limit-filesize
  • fil3s-media
  • fpletz/flake
  • gr33nhouse-improvements
  • history-rewrite
  • icon-flower
  • iggy/stemming
  • iggy/stemming_merge
  • led_fix_fix
  • main
  • main+schneider
  • media_has_video_has_audio
  • micropython_api
  • mixer2
  • moon2_demo_temp
  • moon2_migrate_apps
  • more-accurate-battery
  • pippin/ctx_sprite_sheet_support
  • pippin/display-python-errors-on-display
  • pippin/make_empty_drawlists_skip_render_and_blit
  • pippin/more-accurate-battery
  • pippin/tcp_redirect_hack
  • pippin/tune_ctx_config_update_from_upstream
  • pippin/uhm_flash_access_bust
  • pressable_bugfix
  • py_only_update_fps_overlay_when_changing
  • q3k/doom-poc
  • q3k/render-to-texture
  • rahix/flow3rseeds
  • raw_captouch_new
  • raw_captouch_old
  • release/1.0.0
  • release/1.1.0
  • release/1.1.1
  • release/1.2.0
  • release/1.3.0
  • release/1.4.0
  • restore_blit
  • return_of_melodic_demo
  • rev4_micropython
  • schneider/application-remove-name
  • schneider/bhi581
  • schneider/factory_test
  • schneider/recovery
  • scope_hack
  • sdkconfig-spiram-tinyusb
  • sec/auto-nick
  • sec/blinky
  • sector_size_512
  • shoegaze-fps
  • smaller_gradient_lut
  • store_delta_ms_and_ins_as_class_members
  • task_cleanup
  • uctx-wip
  • w1f1-in-sim
  • widgets_draw
  • wifi-json-error-handling
  • wip-docs
  • wip-tinyusb
  • v1.0.0
  • v1.0.0+rc1
  • v1.0.0+rc2
  • v1.0.0+rc3
  • v1.0.0+rc4
  • v1.0.0+rc5
  • v1.0.0+rc6
  • v1.1.0
  • v1.1.0+rc1
  • v1.1.1
  • v1.2.0
  • v1.2.0+rc1
  • v1.3.0
  • v1.4.0
94 results

Target

Select target project
  • flow3r/flow3r-firmware
  • Vespasian/flow3r-firmware
  • alxndr42/flow3r-firmware
  • pl/flow3r-firmware
  • Kari/flow3r-firmware
  • raimue/flow3r-firmware
  • grandchild/flow3r-firmware
  • mu5tach3/flow3r-firmware
  • Nervengift/flow3r-firmware
  • arachnist/flow3r-firmware
  • TheNewCivilian/flow3r-firmware
  • alibi/flow3r-firmware
  • manuel_v/flow3r-firmware
  • xeniter/flow3r-firmware
  • maxbachmann/flow3r-firmware
  • yGifoom/flow3r-firmware
  • istobic/flow3r-firmware
  • EiNSTeiN_/flow3r-firmware
  • gnudalf/flow3r-firmware
  • 999eagle/flow3r-firmware
  • toerb/flow3r-firmware
  • pandark/flow3r-firmware
  • teal/flow3r-firmware
  • x42/flow3r-firmware
  • alufers/flow3r-firmware
  • dos/flow3r-firmware
  • yrlf/flow3r-firmware
  • LuKaRo/flow3r-firmware
  • ThomasElRubio/flow3r-firmware
  • ai/flow3r-firmware
  • T_X/flow3r-firmware
  • highTower/flow3r-firmware
  • beanieboi/flow3r-firmware
  • Woazboat/flow3r-firmware
  • gooniesbro/flow3r-firmware
  • marvino/flow3r-firmware
  • kressnerd/flow3r-firmware
  • quazgar/flow3r-firmware
  • aoid/flow3r-firmware
  • jkj/flow3r-firmware
  • naomi/flow3r-firmware
41 results
Select Git revision
  • 9Rmain
  • anon/gpndemo
  • anon/update-sim
  • anon/webflasher
  • audio_input
  • audio_io
  • bl00mbox
  • bl00mbox_old
  • captouch-threshold
  • ch3/bl00mbox_docs
  • ci-1690580595
  • compressor
  • dev_p4
  • dev_p4-iggy
  • dev_p4-iggy-rebased
  • dos
  • dos-main-patch-50543
  • events
  • fm_fix
  • fm_fix2
  • fpletz/flake
  • history-rewrite
  • icon-flower
  • iggy/stemming
  • iggy/stemming_merge
  • json-error
  • main
  • main+schneider
  • media-buf
  • micropython_api
  • moon2_applications
  • moon2_demo_temp
  • moon2_gay_drums
  • passthrough
  • phhw
  • pippin/display-python-errors-on-display
  • pippin/make_empty_drawlists_skip_render_and_blit
  • pippin/media_framework
  • pippin/uhm_flash_access_bust
  • pressable_bugfix
  • q3k/doom-poc
  • rahix/big-flow3r
  • rahix/flow3rseeds
  • raw_captouch_new
  • raw_captouch_old
  • release/1.0.0
  • release/1.1.0
  • release/1.1.1
  • rev4_micropython
  • schneider/application-remove-name
  • schneider/bhi581
  • schneider/factory_test
  • schneider/recovery
  • scope
  • scope_hack
  • sdkconfig-spiram-tinyusb
  • sec/auto-nick
  • sec/blinky
  • simtest
  • slewtest
  • t
  • test
  • test2
  • uctx-wip
  • view-think
  • vm-pending
  • vsync
  • wave
  • wip-docs
  • wip-tinyusb
  • v1.0.0
  • v1.0.0+rc1
  • v1.0.0+rc2
  • v1.0.0+rc3
  • v1.0.0+rc4
  • v1.0.0+rc5
  • v1.0.0+rc6
  • v1.1.0
  • v1.1.0+rc1
  • v1.1.1
  • v1.2.0
  • v1.2.0+rc1
  • v1.3.0
83 results
Show changes
Showing
with 8299 additions and 0 deletions
#include "poly_squeeze.h"
radspa_descriptor_t poly_squeeze_desc = {
.name = "poly_squeeze",
.id = 172,
.description = "Multiplexes a number of trigger and pitch inputs into a lesser number of trigger pitch output pairs. "
"The latest triggered inputs are forwarded to the output. If such an input receives a stop trigger it is disconnected "
"from its output. If another inputs is in triggered state but not forwarded at the same time it will be connected to that "
"output and the output is triggered. Pitch is constantly streamed to the outputs if they are connected, else the last "
"connected value is being held."
"\ninit_var: lsb: number of outputs, 1..16, default 3; lsb+1: number of inputs, <lsb>..32, default 10; ",
.create_plugin_instance = poly_squeeze_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define NUM_MPX 2
// mpx block 1
#define TRIGGER_INPUT 0
#define PITCH_INPUT 1
// mpx block 2
#define TRIGGER_OUTPUT 0
#define PITCH_OUTPUT 1
static void assign_note_voices(poly_squeeze_data_t * data){
poly_squeeze_note_t * note = data->active_notes_top;
if(note == NULL) return;
uint32_t active_voices = 0xFFFFFFFFUL << data->num_voices;
for(uint8_t i = 0; i < data->num_voices; i++){
if(note == NULL) break;
if(note->voice >= 0) active_voices = active_voices | (1UL<<note->voice);
note = note->lower;
}
while(note != NULL){
note->voice = -1;
note = note->lower;
}
if(active_voices == UINT32_MAX) return;
note = data->active_notes_top;
for(uint8_t i = 0; i < data->num_voices; i++){
if(note == NULL) break;
if(note->voice < 0){
int8_t voice = -1;
for(int8_t v = 0; v < data->num_voices; v++){
if((~active_voices) & (1<<v)){
active_voices = active_voices | (1<<v);
voice = v;
break;
}
}
note->voice = voice;
}
note = note->lower;
}
}
static poly_squeeze_note_t * get_note_with_voice(poly_squeeze_data_t * data, int8_t voice){
poly_squeeze_note_t * note = data->active_notes_top;
for(uint8_t i = 0; i < data->num_voices; i++){
if(note == NULL) break;
if(note->voice == voice) return note;
note = note->lower;
}
return NULL;
}
void take_note(poly_squeeze_data_t * data, poly_squeeze_note_t * note){
if(note == NULL) return;
if(data->free_notes == note) data->free_notes = note->lower;
if(data->active_notes_bottom == note) data->active_notes_bottom = note->higher;
if(data->active_notes_top == note) data->active_notes_top = note->lower;
if(note->higher != NULL) note->higher->lower = note->lower;
if(note->lower != NULL) note->lower->higher = note->higher;
note->higher = NULL;
note->lower = NULL;
}
static int8_t put_note_on_top(poly_squeeze_data_t * data, poly_squeeze_note_t * note){
if(note == NULL) return -1;
if(note == data->active_notes_top) return note->voice;
take_note(data, note);
note->lower = data->active_notes_top;
if(note->lower != NULL) note->lower->higher = note;
data->active_notes_top = note;
if(note->lower == NULL) data->active_notes_bottom = note;
assign_note_voices(data);
return note->voice;
}
static int8_t free_note(poly_squeeze_data_t * data, poly_squeeze_note_t * note){
if(note == NULL) return -1;
take_note(data, note);
int8_t ret = note->voice;
note->voice = -1;
note->lower = data->free_notes;
if(note->lower != NULL) note->lower->higher = note;
data->free_notes = note;
assign_note_voices(data);
return ret;
}
static void voice_start(poly_squeeze_voice_t * voice, int16_t pitch, int16_t vol){
voice->pitch_out = pitch;
int16_t tmp = voice->_start_trigger;
radspa_trigger_start(vol, &tmp);
voice->trigger_out = tmp;
}
static void voice_stop(poly_squeeze_voice_t * voice){
int16_t tmp = voice->_start_trigger;
radspa_trigger_stop(&tmp);
voice->trigger_out = tmp;
}
void poly_squeeze_run(radspa_t * poly_squeeze, uint16_t num_samples, uint32_t render_pass_id){
poly_squeeze_data_t * data = poly_squeeze->plugin_data;
poly_squeeze_note_t * notes = (void *) (&(data[1]));
poly_squeeze_input_t * inputs = (void *) (&(notes[data->num_notes]));
poly_squeeze_voice_t * voices = (void *) (&(inputs[data->num_inputs]));
for(uint8_t j = 0; j < data->num_inputs; j++){
uint16_t pitch_index;
int16_t trigger_in = radspa_trigger_get_const(&poly_squeeze->signals[TRIGGER_INPUT + NUM_MPX*j],
&inputs[j].trigger_in_hist, &pitch_index, num_samples, render_pass_id);
notes[j].pitch = radspa_signal_get_value(&poly_squeeze->signals[PITCH_INPUT + NUM_MPX*j], pitch_index, render_pass_id);
// should order events by pitch index some day maybe
if(trigger_in > 0){
notes[j].vol = trigger_in;
int8_t voice = put_note_on_top(data, &(notes[j]));
if(voice >= 0) voice_start(&(voices[voice]), notes[j].pitch, notes[j].vol);
} else if(trigger_in < 0){
int8_t voice = free_note(data, &(notes[j]));
if(voice >= 0){
poly_squeeze_note_t * note = get_note_with_voice(data, voice);
if(note == NULL){
voice_stop(&(voices[voice]));
} else {
voice_start(&(voices[voice]), note->pitch, note->vol);
}
}
}
}
for(uint8_t j = 0; j < data->num_inputs; j++){
if((notes[j].voice != -1) && (notes[j].voice < data->num_voices)){
voices[notes[j].voice].pitch_out = notes[j].pitch;
}
}
for(uint8_t j = 0; j < data->num_voices; j++){
uint8_t k = data->num_inputs + j;
radspa_signal_set_const_value(&poly_squeeze->signals[TRIGGER_OUTPUT + NUM_MPX * k], voices[j].trigger_out);
radspa_signal_set_const_value(&poly_squeeze->signals[PITCH_OUTPUT + NUM_MPX * k], voices[j].pitch_out);
voices[j]._start_trigger = voices[j].trigger_out;
}
}
radspa_t * poly_squeeze_create(uint32_t init_var){
if(!init_var) init_var = 3 + (1UL<<8) + 9 * (1UL<<16);
uint8_t num_voices = init_var & 0xFF;
if(num_voices > 32) num_voices = 32;
if(num_voices < 1) num_voices = 1;
init_var = init_var >> 8;
uint8_t num_inputs = init_var & 0xFF;
if(num_inputs > 32) num_inputs = 32;
if(num_inputs < num_voices) num_inputs = num_voices;
uint8_t num_notes = num_inputs;
uint32_t num_signals = num_voices * NUM_MPX + num_inputs * NUM_MPX;
size_t data_size = sizeof(poly_squeeze_data_t);
data_size += sizeof(poly_squeeze_voice_t) * num_voices;
data_size += sizeof(poly_squeeze_note_t) * num_notes;
data_size += sizeof(poly_squeeze_input_t) * num_inputs;
radspa_t * poly_squeeze = radspa_standard_plugin_create(&poly_squeeze_desc, num_signals, data_size, 0);
if(poly_squeeze == NULL) return NULL;
poly_squeeze->render = poly_squeeze_run;
radspa_signal_set_group(poly_squeeze, num_inputs, NUM_MPX, TRIGGER_INPUT, "trigger_in",
RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
radspa_signal_set_group(poly_squeeze, num_inputs, NUM_MPX, PITCH_INPUT, "pitch_in",
RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_SCT, RADSPA_SIGNAL_VAL_SCT_A440);
radspa_signal_set_group(poly_squeeze, num_voices, NUM_MPX, TRIGGER_OUTPUT + NUM_MPX*num_inputs, "trigger_out",
RADSPA_SIGNAL_HINT_OUTPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
radspa_signal_set_group(poly_squeeze, num_voices, NUM_MPX, PITCH_OUTPUT + NUM_MPX*num_inputs, "pitch_out",
RADSPA_SIGNAL_HINT_OUTPUT | RADSPA_SIGNAL_HINT_SCT, RADSPA_SIGNAL_VAL_SCT_A440);
poly_squeeze_data_t * data = poly_squeeze->plugin_data;
data->num_voices = num_voices;
data->num_notes = num_notes;
data->num_inputs = num_inputs;
poly_squeeze_note_t * notes = (void *) (&(data[1]));
poly_squeeze_input_t * inputs = (void *) (&(notes[data->num_notes]));
poly_squeeze_voice_t * voices = (void *) (&(inputs[data->num_inputs]));
data->active_notes_top = NULL;
data->active_notes_bottom = NULL;
data->free_notes = &(notes[0]);
for(uint8_t i = 0; i < num_voices; i++){
voices[i].trigger_out = 0;
voices[i].pitch_out = RADSPA_SIGNAL_VAL_SCT_A440;
voices[i]._start_trigger = voices[i].trigger_out;
}
for(uint8_t i = 0; i < num_notes; i++){
notes[i].pitch = -32768;
notes[i].voice = -1;
if(i){
notes[i].higher = &(notes[i-1]);
} else{
notes[i].higher = NULL;
}
if(i != (num_notes - 1)){
notes[i].lower = &(notes[i+1]);
} else {
notes[i].lower = NULL;
}
}
for(uint8_t i = 0; i < num_inputs; i++){
inputs[i].trigger_in_hist = 0;
}
return poly_squeeze;
}
#pragma once
#include "radspa.h"
#include "radspa_helpers.h"
typedef struct _poly_squeeze_note_t {
int16_t pitch;
int16_t vol;
int8_t voice;
struct _poly_squeeze_note_t * lower;
struct _poly_squeeze_note_t * higher;
} poly_squeeze_note_t;
typedef struct {
int16_t trigger_out;
int16_t pitch_out;
int16_t _start_trigger;
} poly_squeeze_voice_t;
typedef struct {
int16_t trigger_in_hist;
} poly_squeeze_input_t;
typedef struct {
uint8_t num_voices;
uint8_t num_notes;
uint8_t num_inputs;
poly_squeeze_note_t * active_notes_top;
poly_squeeze_note_t * active_notes_bottom;
poly_squeeze_note_t * free_notes;
} poly_squeeze_data_t;
extern radspa_descriptor_t poly_squeeze_desc;
radspa_t * poly_squeeze_create(uint32_t init_var);
void poly_squeeze_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
#include "range_shifter.h"
radspa_t * range_shifter_create(uint32_t init_var);
radspa_descriptor_t range_shifter_desc = {
.name = "range_shifter",
.id = 69,
.description = "saturating multiplication and addition",
.create_plugin_instance = range_shifter_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define RANGE_SHIFTER_NUM_SIGNALS 7
#define RANGE_SHIFTER_OUTPUT 0
#define RANGE_SHIFTER_OUTPUT_A 1
#define RANGE_SHIFTER_OUTPUT_B 2
#define RANGE_SHIFTER_INPUT 3
#define RANGE_SHIFTER_INPUT_A 4
#define RANGE_SHIFTER_INPUT_B 5
#define RANGE_SHIFTER_SPEED 6
#define GET_GAIN { \
output_a = radspa_signal_get_value(output_a_sig, k, render_pass_id); \
output_b = radspa_signal_get_value(output_b_sig, k, render_pass_id); \
input_a = radspa_signal_get_value(input_a_sig, k, render_pass_id); \
input_b = radspa_signal_get_value(input_b_sig, k, render_pass_id); \
output_span = output_b - output_a; \
input_span = input_b - input_a; \
gain = (output_span << 14) / input_span; \
}
#define APPLY_GAIN { \
if(ret == input_a){ \
ret = output_a; \
} else if(ret == input_b){ \
ret = output_b; \
} else { \
ret -= input_a; \
ret = (ret * gain) >> 14; \
ret += output_a; \
} \
}
void range_shifter_run(radspa_t * range_shifter, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_OUTPUT);
radspa_signal_t * output_a_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_OUTPUT_A);
radspa_signal_t * output_b_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_OUTPUT_B);
radspa_signal_t * input_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_INPUT);
radspa_signal_t * input_a_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_INPUT_A);
radspa_signal_t * input_b_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_INPUT_B);
radspa_signal_t * speed_sig = radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_SPEED);
int16_t speed = radspa_signal_get_value(speed_sig, 0, render_pass_id);
int32_t output_a = radspa_signal_get_const_value(output_a_sig, render_pass_id);
int32_t output_b = radspa_signal_get_const_value(output_b_sig, render_pass_id);
int32_t input_a = radspa_signal_get_const_value(input_a_sig, render_pass_id);
int32_t input_b = radspa_signal_get_const_value(input_b_sig, render_pass_id);
int32_t input = radspa_signal_get_const_value(input_sig, render_pass_id);
bool range_const = true;
if(speed >= 10922){
range_const = range_const && (output_a != RADSPA_SIGNAL_NONCONST) && (output_b != RADSPA_SIGNAL_NONCONST);
range_const = range_const && (input_a != RADSPA_SIGNAL_NONCONST) && (input_b != RADSPA_SIGNAL_NONCONST);
}
bool input_const = true;
if(speed > -10922){
input_const = input != RADSPA_SIGNAL_NONCONST;
}
int32_t output_span;
int32_t input_span;
int32_t gain;
if(range_const){
uint16_t k = 0;
GET_GAIN
if(!output_span){
radspa_signal_set_const_value(output_sig, output_a);
} else if(!input_span){
radspa_signal_set_const_value(output_sig, (output_b - output_a)>>1);
} else if(input_const){
int32_t ret = radspa_signal_get_value(input_sig, 0, render_pass_id);
APPLY_GAIN
radspa_signal_set_const_value(output_sig, ret);
} else {
for(uint16_t i = 0; i < num_samples; i++){
int32_t ret = radspa_signal_get_value(input_sig, i, render_pass_id);
APPLY_GAIN
radspa_signal_set_value(output_sig, i, ret);
}
}
} else {
for(uint16_t i = 0; i < num_samples; i++){
uint16_t k = i;
GET_GAIN
if(!output_span){
radspa_signal_set_value(output_sig, i, output_a);
} else if(!input_span){
radspa_signal_set_value(output_sig, i, (output_b - output_a)>>1);
} else {
int32_t ret = radspa_signal_get_value(input_sig, i, render_pass_id);
APPLY_GAIN
radspa_signal_set_value(output_sig, i, ret);
}
}
}
}
radspa_t * range_shifter_create(uint32_t init_var){
radspa_t * range_shifter = radspa_standard_plugin_create(&range_shifter_desc, RANGE_SHIFTER_NUM_SIGNALS, sizeof(char), 0);
if(range_shifter == NULL) return NULL;
range_shifter->render = range_shifter_run;
radspa_signal_set(range_shifter, RANGE_SHIFTER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set_group(range_shifter, 2, 1, RANGE_SHIFTER_OUTPUT_A, "output_range", RADSPA_SIGNAL_HINT_INPUT, -32767);
radspa_signal_set(range_shifter, RANGE_SHIFTER_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set_group(range_shifter, 2, 1, RANGE_SHIFTER_INPUT_A, "input_range", RADSPA_SIGNAL_HINT_INPUT, -32767);
radspa_signal_set(range_shifter, RANGE_SHIFTER_SPEED, "speed", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_DEPRECATED, 32767);
radspa_signal_get_by_index(range_shifter, RANGE_SHIFTER_SPEED)->unit = "{SLOW:-32767} {SLOW_RANGE:0} {FAST:32767}";
range_shifter->signals[RANGE_SHIFTER_OUTPUT_B].value = 32767;
range_shifter->signals[RANGE_SHIFTER_INPUT_B].value = 32767;
return range_shifter;
}
#pragma once
#include <radspa.h>
#include <radspa_helpers.h>
extern radspa_descriptor_t range_shifter_desc;
radspa_t * range_shifter_create(uint32_t init_var);
void range_shifter_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
#include "sampler.h"
radspa_t * sampler_create(uint32_t init_var);
radspa_descriptor_t sampler_desc = {
.name = "sampler",
.id = 696969,
.description = "simple sampler that stores a copy of the sample in ram and has basic recording functionality."
"\ninit_var: length of pcm sample memory\ntable layout: [0:2] read head position (uint32_t), [2:4] write head position (uint32_t), "
"[4:6] sample start (uint32_t), [6:8] sample length (uint32_t), [8:10] sample rate (uint32_t), [10] sampler status "
"(int16_t bitmask), , [11:init_var+11] pcm sample data (int16_t)",
.create_plugin_instance = sampler_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define SAMPLER_NUM_SIGNALS 5
#define SAMPLER_OUTPUT 0
#define SAMPLER_TRIGGER 1
#define SAMPLER_PITCH_SHIFT 2
#define SAMPLER_REC_TRIGGER 3
#define SAMPLER_REC_IN 4
#define READ_HEAD_POS 0
#define WRITE_HEAD_POS 2
#define SAMPLE_START 4
#define SAMPLE_LEN 6
#define SAMPLE_RATE 8
#define STATUS 10
#define STATUS_PLAYBACK_ACTIVE 0
#define STATUS_PLAYBACK_LOOP 1
#define STATUS_RECORD_ACTIVE 2
#define STATUS_RECORD_OVERFLOW 3
#define STATUS_RECORD_NEW_EVENT 4
#define BUFFER_OFFSET 11
void sampler_run(radspa_t * sampler, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(sampler, SAMPLER_OUTPUT);
radspa_signal_t * trigger_sig = radspa_signal_get_by_index(sampler, SAMPLER_TRIGGER);
radspa_signal_t * rec_trigger_sig = radspa_signal_get_by_index(sampler, SAMPLER_REC_TRIGGER);
radspa_signal_t * rec_in_sig = radspa_signal_get_by_index(sampler, SAMPLER_REC_IN);
radspa_signal_t * pitch_shift_sig = radspa_signal_get_by_index(sampler, SAMPLER_PITCH_SHIFT);
sampler_data_t * data = sampler->plugin_data;
int16_t trigger = radspa_signal_get_const_value(trigger_sig, render_pass_id);
bool trigger_const = trigger != RADSPA_SIGNAL_NONCONST;
if(trigger_const) trigger = radspa_trigger_get(trigger, &(data->trigger_prev));
int16_t rec_trigger = radspa_signal_get_const_value(rec_trigger_sig, render_pass_id);
bool rec_trigger_const = rec_trigger != RADSPA_SIGNAL_NONCONST;
if(rec_trigger_const) rec_trigger = radspa_trigger_get(rec_trigger, &(data->rec_trigger_prev));
/*
if((!data->playback_active) && (!data->rec_active) && (trigger_const) && (rec_trigger_const) && (!rec_trigger) && (!trigger)){
radspa_signal_set_const_value(output_sig, 0);
return;
}
*/
int16_t * buf = sampler->plugin_table;
uint32_t * buf32 = (uint32_t *) buf;
uint32_t sample_len = buf32[SAMPLE_LEN/2];
uint32_t sample_start = buf32[SAMPLE_START/2];
uint32_t sample_rate = buf32[SAMPLE_RATE/2];
if(!sample_rate){
sample_rate = 1;
buf32[SAMPLE_RATE/2] = 1;
}
uint32_t buffer_size = sampler->plugin_table_len - BUFFER_OFFSET;
uint64_t buffer_size_long = buffer_size * 48000;
if(sample_len >= buffer_size) sample_len = buffer_size - 1;
if(sample_start >= buffer_size) sample_start = buffer_size - 1;
bool output_mute = !data->playback_active;
bool output_const = sample_rate < 100;
if(output_const){
sample_rate *= num_samples;
num_samples = 1;
}
int32_t ret = 0;
for(uint16_t i = 0; i < num_samples; i++){
if((!rec_trigger_const) || (!i)){
if(!rec_trigger_const) rec_trigger = radspa_trigger_get(radspa_signal_get_value(rec_trigger_sig, i, render_pass_id), &(data->rec_trigger_prev));
if(rec_trigger > 0){
data->rec_active = true;
data->write_head_pos_long = 0;
data->write_steps = 0;
data->write_head_pos_prev = -1;
data->write_overflow = false;
buf[STATUS] |= 1<<(STATUS_RECORD_NEW_EVENT);
} else if((rec_trigger < 0) && data->rec_active){
data->rec_active = false;
}
}
if(data->rec_active){
int16_t rec_in = radspa_signal_get_value(rec_in_sig, i, render_pass_id);
int32_t write_head_pos = (data->write_head_pos_long * 699) >> 25; // equiv to x/48000 (acc 0.008%)
if(data->write_head_pos_prev == write_head_pos){
if(data->write_steps){
data->rec_acc += rec_in;
} else {
data->rec_acc = buf[write_head_pos + BUFFER_OFFSET];
}
data->write_steps++;
} else {
if(data->write_steps) buf[data->write_head_pos_prev + BUFFER_OFFSET] = data->rec_acc/data->write_steps;
data->write_steps = 0;
if(write_head_pos > data->write_head_pos_prev){
for(uint32_t j = data->write_head_pos_prev + 1; j <= write_head_pos; j++){
buf[j + BUFFER_OFFSET] = rec_in;
}
} else {
uint32_t write_head_max = write_head_pos + buffer_size;
for(uint32_t j = data->write_head_pos_prev + 1; j <= write_head_max; j++){
uint32_t index = j;
if(index >= buffer_size) index -= buffer_size;
buf[index + BUFFER_OFFSET] = rec_in;
}
}
}
if(!data->write_overflow) data->write_overflow = write_head_pos < data->write_head_pos_prev;
data->write_head_pos_prev = write_head_pos;
if(data->write_overflow & (!(buf[STATUS] & (1<<(STATUS_RECORD_OVERFLOW))))){
data->rec_active = false;
} else {
if(data->write_overflow){
sample_start = (data->write_head_pos_long * 699) >> 25;
sample_len = buffer_size;
} else {
sample_start = 0;
sample_len = (data->write_head_pos_long * 699) >> 25;
}
data->write_head_pos_long += sample_rate;
while(data->write_head_pos_long >= buffer_size_long) data->write_head_pos_long -= buffer_size_long;
}
}
if((!trigger_const) || (!i)){
if(!trigger_const) trigger = radspa_trigger_get(radspa_signal_get_value(trigger_sig, i, render_pass_id), &(data->trigger_prev));
if(trigger > 0){
data->playback_active = true;
data->read_head_pos_long = 0;
data->playback_sample_start = sample_start;
data->volume = trigger;
if(output_mute){
radspa_signal_set_values(output_sig, 0, i, 0);
output_mute = false;
}
} else if(trigger < 0){
data->playback_active = false;
}
}
int32_t read_head_pos;
int8_t read_head_pos_subsample;
if(data->playback_active){
read_head_pos = (data->read_head_pos_long * 699) >> (25-6); // equiv to (x<<6)/48000 (acc 0.008%)
read_head_pos_subsample = read_head_pos & 0b111111;
read_head_pos = read_head_pos >> 6;
if(read_head_pos >= sample_len){
if(buf[STATUS] & (1<<(STATUS_PLAYBACK_LOOP))){
while(read_head_pos > sample_len){
if(sample_len){
data->read_head_pos_long -= (uint64_t) sample_len * 48000;
read_head_pos -= sample_len;
} else {
data->read_head_pos_long = 0;
read_head_pos = 0;
break;
}
}
} else {
data->playback_active = false;
}
}
}
if(data->playback_active){
uint32_t sample_offset_pos = read_head_pos + data->playback_sample_start;
while(sample_offset_pos >= sample_len){
if(sample_len){
sample_offset_pos -= sample_len;
} else {
sample_offset_pos = 0;
break;
}
}
ret = buf[sample_offset_pos + BUFFER_OFFSET];
if(read_head_pos_subsample){
ret *= (64 - read_head_pos_subsample);
sample_offset_pos++;
if(sample_offset_pos >= sample_len) sample_offset_pos -= sample_len;
ret += buf[sample_offset_pos + BUFFER_OFFSET] * read_head_pos_subsample;
ret = ret >> 6;
}
ret = radspa_mult_shift(ret, data->volume);
radspa_signal_set_value(output_sig, i, ret);
int32_t pitch_shift = radspa_signal_get_value(pitch_shift_sig, i, render_pass_id);
if(pitch_shift != data->pitch_shift_prev){
data->pitch_shift_mult = radspa_sct_to_rel_freq(radspa_clip(pitch_shift - 18376 - 10986 - 4800), 0);
if(data->pitch_shift_mult > (1<<13)) data->pitch_shift_mult = (1<<13);
data->pitch_shift_prev = pitch_shift;
}
data->read_head_pos_long += (sample_rate * data->pitch_shift_mult) >> 11;
} else {
if(!output_mute) radspa_signal_set_value(output_sig, i, 0);
}
}
if(output_mute || output_const) radspa_signal_set_const_value(output_sig, ret);
buf32[SAMPLE_START/2] = sample_start;
buf32[SAMPLE_LEN/2] = sample_len;
if(data->playback_active){
buf[STATUS] |= 1<<(STATUS_PLAYBACK_ACTIVE);
buf32[READ_HEAD_POS/2] = (data->read_head_pos_long * 699) >> 25;;
} else {
buf[STATUS] &= ~(1<<(STATUS_PLAYBACK_ACTIVE));
buf32[READ_HEAD_POS/2] = 0;
}
if(data->rec_active){
buf[STATUS] |= 1<<(STATUS_RECORD_ACTIVE);
buf32[WRITE_HEAD_POS/2] = (data->write_head_pos_long * 699) >> 25;;
} else {
buf[STATUS] &= ~(1<<(STATUS_RECORD_ACTIVE));
buf32[WRITE_HEAD_POS/2] = 0;
}
}
#define MAX_SAMPLE_LEN (48000UL*300)
radspa_t * sampler_create(uint32_t init_var){
if(init_var == 0) return NULL; //doesn't make sense
if(init_var > MAX_SAMPLE_LEN) init_var = MAX_SAMPLE_LEN;
uint32_t buffer_size = init_var;
radspa_t * sampler = radspa_standard_plugin_create(&sampler_desc, SAMPLER_NUM_SIGNALS, sizeof(sampler_data_t), buffer_size + BUFFER_OFFSET);
if(sampler == NULL) return NULL;
sampler->render = sampler_run;
radspa_signal_set(sampler, SAMPLER_OUTPUT, "playback_output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(sampler, SAMPLER_TRIGGER, "playback_trigger", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
radspa_signal_set(sampler, SAMPLER_PITCH_SHIFT, "playback_speed", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_SCT, 18367);
radspa_signal_set(sampler, SAMPLER_REC_IN, "record_input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(sampler, SAMPLER_REC_TRIGGER, "record_trigger", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
sampler_data_t * data = sampler->plugin_data;
data->pitch_shift_mult = 1<<11;
int16_t * buf = sampler->plugin_table;
uint32_t * buf32 = (uint32_t *) buf;
buf32[SAMPLE_RATE/2] = 48000;
buf[STATUS] = 1<<(STATUS_RECORD_OVERFLOW);
return sampler;
}
#pragma once
#include <radspa.h>
#include <radspa_helpers.h>
typedef struct {
int64_t write_head_pos_long;
int64_t read_head_pos_long;
uint32_t playback_sample_start;
int16_t pitch_shift_prev;
int16_t trigger_prev;
int16_t rec_trigger_prev;
int16_t volume;
uint32_t pitch_shift_mult;
int32_t rec_acc;
int32_t write_head_pos_prev;
int16_t write_steps;
bool rec_active;
bool write_overflow;
bool playback_active;
} sampler_data_t;
extern radspa_descriptor_t sampler_desc;
radspa_t * sampler_create(uint32_t init_var);
void sampler_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
#include "sequencer.h"
radspa_descriptor_t sequencer_desc = {
.name = "sequencer",
.id = 56709,
.description = "sequencer that can output triggers or general control signals, best enjoyed through the "
"'sequencer' patch.\ninit_var: 1st byte (lsb): number of tracks, 2nd byte: number of steps"
"\ntable encoding (all int16_t): index 0: track type (-32767: trigger track, 32767: direct "
"track). next 'number of steps' indices: track data (repeat for number of tracks)",
.create_plugin_instance = sequencer_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define SEQUENCER_NUM_SIGNALS 7
#define SEQUENCER_STEP 0
#define SEQUENCER_SYNC_OUT 1
#define SEQUENCER_SYNC_IN 2
#define SEQUENCER_START_STEP 3
#define SEQUENCER_END_STEP 4
#define SEQUENCER_BPM 5
#define SEQUENCER_BEAT_DIV 6
// mpx'd
#define SEQUENCER_OUTPUT 7
static uint64_t target(uint64_t step_len, uint64_t bpm, uint64_t beat_div){
if(bpm == 0) return 0;
return (48000ULL * 60 * 4) / (bpm * beat_div);
}
void sequencer_run(radspa_t * sequencer, uint16_t num_samples, uint32_t render_pass_id){
bool output_request = false;
sequencer_data_t * data = sequencer->plugin_data;
sequencer_track_data_t * tracks = (void *) (&data[1]);
radspa_signal_t * track_sigs[data->num_tracks];
radspa_signal_t * step_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_STEP);
if(step_sig->buffer != NULL) output_request = true;
radspa_signal_t * sync_out_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_SYNC_OUT);
if(sync_out_sig->buffer != NULL) output_request = true;
radspa_signal_t * sync_in_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_SYNC_IN);
radspa_signal_t * start_step_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_START_STEP);
radspa_signal_t * end_step_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_END_STEP);
radspa_signal_t * bpm_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_BPM);
radspa_signal_t * beat_div_sig = radspa_signal_get_by_index(sequencer, SEQUENCER_BEAT_DIV);
for(uint8_t j = 0; j < data->num_tracks; j++){
track_sigs[j] = radspa_signal_get_by_index(sequencer, SEQUENCER_OUTPUT+j);
if(track_sigs[j]->buffer != NULL) output_request = true;
}
if(!output_request) return;
int16_t * table = sequencer->plugin_table;
int16_t s1 = radspa_signal_get_value(end_step_sig, 0, render_pass_id);
int16_t s2 = data->track_step_len - 1;
data->step_end = s1 > 0 ? (s1 > s2 ? s2 : s1) : 0;
data->step_start = radspa_signal_get_value(start_step_sig, 0, render_pass_id);
int16_t bpm = radspa_signal_get_value(bpm_sig, 0, render_pass_id);
int16_t beat_div = radspa_signal_get_value(beat_div_sig, 0, render_pass_id);
if((bpm != data->bpm_prev) || (beat_div != data->beat_div_prev)){
data->counter_target = target(data->track_step_len, bpm, beat_div);
data->bpm_prev = bpm;
data->beat_div_prev = beat_div;
}
for(uint16_t i = 0; i < num_samples; i++){
int16_t sync_in = radspa_trigger_get(radspa_signal_get_value(sync_in_sig, i, render_pass_id),
&(data->sync_in_hist));
if(sync_in){
data->counter = 0;
data->step = data->step_start;
bool start = sync_in > 0;
data->is_stopped = !start;
data->sync_out_start = start;
data->sync_out_stop = !start;
if(!start){
for(uint8_t j = 0; j < data->num_tracks; j++){
int16_t type = table[j * (data->track_step_len + 1)];
int16_t stage_val = table[data->step + 1 + (1 + data->track_step_len) * j];
if(type == -32767) stage_val = -1;
if((!tracks[j].changed) && (tracks[j].stage_val_prev != stage_val)){
tracks[j].changed = true;
tracks[j].stage_val_prev = stage_val;
for(uint16_t k = 0; k < i; k++){
radspa_signal_set_value(track_sigs[j], k, tracks[j].track_fill);
}
}
if(type == 32767){
tracks[j].track_fill = stage_val;
} else if(type == -32767){
if(stage_val > 0){
radspa_trigger_start(stage_val, &(tracks[j].track_fill));
} else if(stage_val < 0){
radspa_trigger_stop(&(tracks[j].track_fill));
}
}
tracks[j].stage_val_prev = stage_val;
}
}
} else {
data->sync_out_start = false;
data->sync_out_stop = false;
}
if(!data->is_stopped && data->counter_target){
if(data->counter >= data->counter_target){
data->counter = 0;
data->step++;
if(data->step > data->step_end){
data->step = data->step_start;
data->sync_out_start = true;
}
}
if(!data->counter){ //event just happened
for(uint8_t j = 0; j < data->num_tracks; j++){
int16_t type = table[j * (data->track_step_len + 1)];
int16_t stage_val = table[data->step + 1 + (1 + data->track_step_len) * j];
if((!tracks[j].changed) && (tracks[j].stage_val_prev != stage_val)){
tracks[j].changed = true;
tracks[j].stage_val_prev = stage_val;
for(uint16_t k = 0; k < i; k++){
radspa_signal_set_value(track_sigs[j], k, tracks[j].track_fill);
}
}
if(type == 32767){
tracks[j].track_fill = stage_val;
} else if(type == -32767){
if(stage_val > 0){
radspa_trigger_start(stage_val, &(tracks[j].track_fill));
} else if(stage_val < 0){
radspa_trigger_stop(&(tracks[j].track_fill));
}
}
tracks[j].stage_val_prev = stage_val;
}
}
data->counter++;
}
for(uint8_t j = 0; j < data->num_tracks; j++){
if(tracks[j].changed) radspa_signal_set_value(track_sigs[j], i, tracks[j].track_fill);
}
int16_t sync_out = 0;
if(data->sync_out_start){
sync_out = radspa_trigger_start(sync_in, &(data->sync_out_hist));
} else if(data->sync_out_stop){
sync_out = radspa_trigger_stop(&(data->sync_out_hist));
}
radspa_signal_set_value(sync_out_sig, i, sync_out);
}
for(uint8_t j = 0; j < data->num_tracks; j++){
if(!tracks[j].changed){
int16_t type = table[j * (data->track_step_len + 1)];
if(type == 32767){
tracks[j].track_fill = table[data->step + 1 + (1 + data->track_step_len) * j];
tracks[j].stage_val_prev = tracks[j].track_fill;
}
radspa_signal_set_const_value(track_sigs[j], tracks[j].track_fill);
} else {
tracks[j].changed = false;
}
}
radspa_signal_set_const_value(step_sig, data->step);
}
radspa_t * sequencer_create(uint32_t init_var){
uint32_t num_tracks = 4;
uint32_t num_steps = 16;
if(init_var){
num_tracks = init_var & 0xFF;
num_steps = (init_var>>8) & 0xFF;
}
if(!num_tracks) return NULL;
if(!num_steps) return NULL;
uint32_t table_size = num_tracks * (num_steps + 1);
uint32_t num_signals = num_tracks + SEQUENCER_NUM_SIGNALS; //one for each channel output
size_t data_size = sizeof(sequencer_data_t) + sizeof(sequencer_track_data_t) * num_tracks;
radspa_t * sequencer = radspa_standard_plugin_create(&sequencer_desc, num_signals, data_size, table_size);
if(sequencer == NULL) return NULL;
sequencer->render = sequencer_run;
sequencer_data_t * data = sequencer->plugin_data;
data->track_step_len = num_steps;
data->num_tracks = num_tracks;
data->bpm_prev = 120;
data->beat_div_prev = 16;
data->counter_target = target(data->track_step_len, data->bpm_prev, data->beat_div_prev);
radspa_signal_set(sequencer, SEQUENCER_STEP, "step", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(sequencer, SEQUENCER_SYNC_OUT, "sync_out", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(sequencer, SEQUENCER_SYNC_IN, "sync_in", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_TRIGGER, 32767);
radspa_signal_set(sequencer, SEQUENCER_START_STEP, "step_start", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(sequencer, SEQUENCER_END_STEP, "step_end", RADSPA_SIGNAL_HINT_INPUT, num_steps-1);
radspa_signal_set(sequencer, SEQUENCER_BPM, "bpm", RADSPA_SIGNAL_HINT_INPUT, data->bpm_prev);
radspa_signal_set(sequencer, SEQUENCER_BEAT_DIV, "beat_div", RADSPA_SIGNAL_HINT_INPUT, data->beat_div_prev);
radspa_signal_set_group(sequencer, data->num_tracks, 1, SEQUENCER_OUTPUT, "track",
RADSPA_SIGNAL_HINT_OUTPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
data->counter = 0;
data->sync_in_hist = 0;
data->sync_out_hist = 0;
data->sync_out_start = false;
data->sync_out_stop = false;
data->is_stopped = true;
sequencer_track_data_t * tracks = (void *) (&data[1]);
for(uint8_t j = 0; j < data->num_tracks; j++){
tracks[j].changed = false;
tracks[j].track_fill = 0;
tracks[j].stage_val_prev = 0;
}
return sequencer;
}
#pragma once
#include <math.h>
#include "radspa.h"
#include "radspa_helpers.h"
typedef struct {
int16_t track_fill;
int16_t stage_val_prev;
bool changed;
} sequencer_track_data_t;
typedef struct {
uint8_t num_tracks;
uint16_t track_step_len;
uint8_t step_end;
uint8_t step_start;
uint8_t step;
uint64_t counter;
uint64_t counter_target;
int16_t sync_in_hist;
int16_t sync_out_hist;
bool sync_out_start;
bool sync_out_stop;
bool is_stopped;
int16_t bpm_prev;
int16_t beat_div_prev;
} sequencer_data_t;
extern radspa_descriptor_t sequencer_desc;
radspa_t * sequencer_create(uint32_t init_var);
void sequencer_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
#include "slew_rate_limiter.h"
radspa_descriptor_t slew_rate_limiter_desc = {
.name = "slew_rate_limiter",
.id = 23,
.description = "very cheap nonlinear filter",
.create_plugin_instance = slew_rate_limiter_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define SLEW_RATE_LIMITER_NUM_SIGNALS 3
#define SLEW_RATE_LIMITER_OUTPUT 0
#define SLEW_RATE_LIMITER_INPUT 1
#define SLEW_RATE_LIMITER_SLEW_RATE 2
radspa_t * slew_rate_limiter_create(uint32_t init_var){
radspa_t * slew_rate_limiter = radspa_standard_plugin_create(&slew_rate_limiter_desc, SLEW_RATE_LIMITER_NUM_SIGNALS, sizeof(slew_rate_limiter_data_t), 0);
slew_rate_limiter->render = slew_rate_limiter_run;
radspa_signal_set(slew_rate_limiter, SLEW_RATE_LIMITER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(slew_rate_limiter, SLEW_RATE_LIMITER_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(slew_rate_limiter, SLEW_RATE_LIMITER_SLEW_RATE, "slew_rate", RADSPA_SIGNAL_HINT_INPUT, 1000);
return slew_rate_limiter;
}
void slew_rate_limiter_run(radspa_t * slew_rate_limiter, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(slew_rate_limiter, SLEW_RATE_LIMITER_OUTPUT);
if(output_sig->buffer == NULL) return;
radspa_signal_t * input_sig = radspa_signal_get_by_index(slew_rate_limiter, SLEW_RATE_LIMITER_INPUT);
radspa_signal_t * slew_rate_sig = radspa_signal_get_by_index(slew_rate_limiter, SLEW_RATE_LIMITER_SLEW_RATE);
slew_rate_limiter_data_t * data = slew_rate_limiter->plugin_data;
int32_t ret = 0;
for(uint16_t i = 0; i < num_samples; i++){
int32_t input = radspa_signal_get_value(input_sig, i, render_pass_id);
int32_t slew_rate = (uint16_t) radspa_signal_get_value(slew_rate_sig, i, render_pass_id);
ret = data->prev;
if(input - ret > slew_rate){
ret += slew_rate;
} else if(ret - input > slew_rate){
ret -= slew_rate;
} else {
ret = input;
}
radspa_signal_set_value(output_sig, i, ret);
}
}
#pragma once
#include "radspa.h"
#include "radspa_helpers.h"
typedef struct {
int32_t prev;
} slew_rate_limiter_data_t;
extern radspa_descriptor_t slew_rate_limiter_desc;
radspa_t * slew_rate_limiter_create(uint32_t init_var);
void slew_rate_limiter_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
#include "trigger_merge.h"
#include <stdio.h>
radspa_descriptor_t trigger_merge_desc = {
.name = "trigger_merge",
.id = 38,
.description = "merges multiple trigger inputs together. lazy. if a start and a stop "
"collide the stop is preferred."
"\ninit_var: number of inputs, default 0, max 127",
.create_plugin_instance = trigger_merge_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
typedef struct {
int16_t trigger_out_prev;
int16_t blocked_stop;
int16_t trigger_in_prev[];
} trigger_merge_data_t;
void trigger_merge_run(radspa_t * plugin, uint16_t num_samples, uint32_t render_pass_id){
int num_inputs = plugin->len_signals - 1;
trigger_merge_data_t * data = plugin->plugin_data;
bool block_stop_events = plugin->plugin_table[0];
int16_t i;
int16_t merged_trigger = 0;
int16_t last_timestamp = -1;
for(uint8_t j = 0; j < num_inputs; j++){
int16_t trigger_in = radspa_trigger_get_const(&plugin->signals[j], &data->trigger_in_prev[j], (uint16_t *) &i, num_samples, render_pass_id);
if((last_timestamp > i) || (!trigger_in)) continue;
if((trigger_in > 0) && (last_timestamp == i)){
if(merged_trigger != -1){
merged_trigger = merged_trigger > trigger_in ? merged_trigger : trigger_in;
}
} else {
merged_trigger = trigger_in;
}
last_timestamp = i;
}
if(merged_trigger > 0){
radspa_trigger_start(merged_trigger, &(data->trigger_out_prev));
data->blocked_stop = false;
} else if(data->blocked_stop && (!block_stop_events)){
radspa_trigger_stop(&(data->trigger_out_prev));
data->blocked_stop = false;
} else if(merged_trigger < 0){
if(!block_stop_events){
radspa_trigger_stop(&(data->trigger_out_prev));
} else {
data->blocked_stop = true;
}
}
radspa_signal_set_const_value(&plugin->signals[num_inputs], data->trigger_out_prev);
}
radspa_t * trigger_merge_create(uint32_t init_var){
if(init_var > 127) init_var = 127;
if(!init_var) init_var = 1;
uint32_t size = sizeof(trigger_merge_data_t) + init_var * sizeof(int16_t);
radspa_t * plugin = radspa_standard_plugin_create(&trigger_merge_desc, init_var + 1, size, 1);
if(plugin == NULL) return NULL;
plugin->render = trigger_merge_run;
radspa_signal_set_group(plugin, init_var, 1, 0, "input", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
radspa_signal_set(plugin, init_var, "output", RADSPA_SIGNAL_HINT_OUTPUT | RADSPA_SIGNAL_HINT_TRIGGER, 0);
return plugin;
}
#pragma once
#include <radspa.h>
#include <radspa_helpers.h>
extern radspa_descriptor_t trigger_merge_desc;
radspa_t * trigger_merge_create(uint32_t init_var);
void trigger_merge_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
idf_component_register(
SRCS
bmi270.c
bmi2.c
INCLUDE_DIRS
.
)
Copyright (c) 2023 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
# Sensor API for the BMI2's OIS interface
## Table of Contents
- [Introduction](#Intro)
- [Integration details](#Integration)
- [Driver files information](#file)
- [Sensor interfaces](#interface)
- [Integration Examples](#examples)
### Introduction<a name=Intro></a>
This package contains Bosch Sensortec's BMI2 Sensor API.
### Integration details<a name=Integration></a>
- Integrate _bmi2.c_, _bmi2.h_, _bmi2_ois.c_, _bmi2_ois.h_, _bmi2_defs.h_ and the required variant files in your project.
- User has to include _bmi2_ois.h_ in the code to call OIS related APIs and a _variant header_ for initialization as
well as BMI2 related API calls, as shown below:
``` c
#include "bmi261.h"
#include "bmi2_ois.h"
````
### Driver files information<a name=file></a>
- *_bmi2_ois.c_*
* This file has function definitions of OIS related API interfaces.
- *_bmi2_ois.h_*
* This header file has necessary include files, function declarations, required to make OIS related API calls.
### Sensor interfaces<a name=interface></a>
#### _Host Interface_
- I2C interface
- SPI interface
_Note: By default, the interface is I2C._
#### _OIS Interface_
- SPI interface
### Integration examples<a name=examples></a>
#### Configuring SPI/I2C for host interface.
To configure host interface, an instance of the bmi2_dev structure should be
created for initializing BMI2 sensor. "_Refer **README** for initializing BMI2
sensor._"
#### Configuring SPI for OIS interface.
To configure OIS interface, an instance of the bmi2_ois_dev structure should be
created. The following parameters are required to be updated in the structure,
by the user.
Parameters | Details
--------------|-----------------------------------
_intf_ptr_ | device address reference of SPI interface
_ois_read_ | read through SPI interface
_ois_write_ | read through SPI interface
_ois_delay_us_| delay in micro seconds
_acc_en_ | for enabling accelerometer
_gyr_en_ | for enabling gyroscope
``` c
int8_t rslt = 0;
struct bmi2_ois_dev ois_dev = {
.intf_ptr = intf_ptr will contain the chip selection info of SPI CS pin,
.ois_read = user_spi_reg_read,
.ois_write = user_spi_reg_write,
.ois_delay_us = user_delay_us
};
```
>**_Important Note_**: For initializing and configuring BMI2 sensors, which is
done through host interface, the API's are to be used from bmi2.c file. Rest
of the API's, for OIS configurations and the reading of OIS data, which is done
through OIS interface, are to be used from bmi2_ois.c file.
##### Get accelerometer and gyroscope data through OIS interface
``` c
int8_t rslt;
/* Array to enable sensor through host interface */
uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO};
/* Array to enable sensor through OIS interface */
uint8_t sens_sel[2] = {BMI2_OIS_ACCEL, BMI2_OIS_GYRO};
/* Initialize the configuration structure */
struct bmi2_sens_config sens_cfg = {0};
/* Initialize BMI2 */
rslt = bmi2_init(&dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Enable accelerometer and gyroscope through host interface */
rslt = bmi2_sensor_enable(sens_list, 2, &dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Setting of OIS Range is done through host interface */
/* Select the gyroscope sensor for OIS Range configuration */
sens_cfg.type = BMI2_GYRO;
/* Get gyroscope configuration */
rslt = bmi2_get_sensor_config(&sens_cfg, 1, &dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Set the desired OIS Range */
sens_cfg.cfg.gyr.ois_range = BMI2_GYR_OIS_2000;
/* Set gyroscope configuration for default values */
rslt = bmi2_set_sensor_config(&sens_cfg, 1, &dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Enable OIS through host interface */
rslt = bmi2_set_ois_interface(BMI2_ENABLE, &dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Disable Advance Power Save Mode through host interface */
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Get configurations for OIS through OIS interface for default values */
rslt = bmi2_ois_get_config(&ois_dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
/* Enable accelerometer and gyroscope for reading OIS data */
ois_dev.acc_en = BMI2_ENABLE;
ois_dev.gyr_en = BMI2_ENABLE;
/* Set configurations for OIS through OIS interface */
rslt = bmi2_ois_set_config(&ois_dev);
if (rslt == BMI2_OK) {
/* Get OIS accelerometer and gyroscope data through OIS interface */
rslt = bmi2_ois_read_data(sens_sel, 2, &ois_dev);
if (rslt == BMI2_OK) {
/* Print accelerometer data */
printf("OIS Accel x-axis = %d\t", ois_dev.acc_data.x);
printf("OIS Accel y-axis= %d\t", ois_dev.acc_data.y);
printf("OIS Accel z-axis = %d\r\n", ois_dev.acc_data.z);
/* Print gyroscope data */
printf("OIS Gyro x-axis = %d\t", ois_dev.gyr_data.x);
printf("OIS Gyro y-axis= %d\t", ois_dev.gyr_data.y);
printf("OIS Gyro z-axis = %d\r\n", ois_dev.gyr_data.z);
}
}
if (rslt != BMI2_OK) {
printf("Error code: %d\n", rslt);
return;
}
/* Enable Advance Power Save Mode through host interface */
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, &dev);
if (rslt != BMI2_OK) {
printf("Error: %d\n", rslt);
return;
}
```
\ No newline at end of file
BMI270 Sensor API
> This package contains the sensor APIs for the BMI270 sensor
## Sensor Overview
The BMI270 is a small, low power, low noise inertial measurement unit designed for use in mobile applications like augmented reality or indoor navigation which require highly accurate, real-time sensor data.
## Applications
### BMI270 (base)
- Any motion, No motion, Significant motion detectors
- Wrist worn Step counter and Step detector (Pedometer)
- Activity change recognition
- Still
- Walking
- Running
- Wrist gestures
- Push arm down
- Pivot up
- Wrist shake jiggle
- Flick in
- Flick out
- Wrist wear wake up
### BMI270 Context
- Step counter and Step detector (Pedometer)
- Activity change recognition
- Still
- Walking
- Running
### BMI270 Legacy
- Any motion, No motion, Significant motion detector
- Orientation detector (Advanced Potrait-Landscape)
- High-G, Low-G (Freefall) detector
- Flat detector
- Tap detection (Single, Double, Triple taps)
- Smartphone Step counter and Step detector (Pedometer)
- Activity change recognition
- Still
- Walking
- Running
### BMI270 Maximum FIFO
- Supports a 6kB FIFO
For more information refer product page [Link](https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi270.html)
---
\ No newline at end of file
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/**
* Copyright (c) 2023 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 bmi2.h
* @date 2023-05-03
* @version v2.86.1
*
*/
/*!
* @defgroup bmi2xy BMI2XY
*/
/**
* \ingroup bmi2xy
* \defgroup bmi2 BMI2
* @brief Sensor driver for BMI2 sensor
*/
#ifndef BMI2_H_
#define BMI2_H_
/*! CPP guard */
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************/
/*! Header files
****************************************************************************/
#include "bmi2_defs.h"
/***************************************************************************/
/*! BMI2XY User Interface function prototypes
****************************************************************************/
/**
* \ingroup bmi2
* \defgroup bmi2ApiInit Initialization
* @brief Initialize the sensor and device structure
*/
/*!
* \ingroup bmi2ApiInit
* \page bmi2_api_bmi2_sec_init bmi2_sec_init
* \code
* int8_t bmi2_sec_init(struct bmi2_dev *dev);
* \endcode
* @details This API is the entry point for bmi2 sensor. It selects between
* I2C/SPI interface, based on user selection. It also reads the chip-id of
* the sensor.
*
* @param[in,out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_sec_init(struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInit
* \page bmi2_api_bmi2_set_spi_en bmi2_set_spi_en
* \code
* int8_t bmi2_set_spi_en(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API sets the status of SPI enable .
*
* @param[in] enable : To enable/disable SPI interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Enable I2C
* BMI2_ENABLE | Enable SPI
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_spi_en(uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInit
* \page bmi2_api_bmi2_get_spi_en bmi2_get_spi_en
* \code
* int8_t bmi2_get_spi_en(uint8_t *enable, struct bmi2_dev *dev);
* \endcode
* @details This API gets the status of SPI enable .
*
* @param[in] enable : Pointer to get enable/disable SPI interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Enable I2C
* BMI2_ENABLE | Enable SPI
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_spi_en(uint8_t *enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInit
* \page bmi2_api_bmi2_set_spi3_interface_mode bmi2_set_spi3_interface_mode
* \code
* int8_t bmi2_set_spi3_interface_mode(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API sets the status of SPI interface.
*
* @param[in] enable : To enable/disable SPI 3/4 wire interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Enable SPI 4 wire mode
* BMI2_ENABLE | Enable SPI 3 wire mode
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_spi3_interface_mode(uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInit
* \page bmi2_api_bmi2_get_spi3_interface_mode bmi2_get_spi3_interface_mode
* \code
* int8_t bmi2_get_spi3_interface_mode(uint8_t *enable, struct bmi2_dev *dev);
* \endcode
* @details This API gets the status of SPI interface.
*
* @param[in] enable : Pointer to get enable/disable SPI 3/4 wire interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Enable SPI 4 wire mode
* BMI2_ENABLE | Enable SPI 3 wire mode
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_spi3_interface_mode(uint8_t *enable, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiI2C I2c watchdog init
* @brief Initialize the watchdog for i2c
*/
/*!
* \ingroup bmi2ApiI2C
* \page bmi2_api_bmi2_set_i2c_wdt_en bmi2_set_i2c_wdt_en
* \code
* int8_t bmi2_set_i2c_wdt_en(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API enables/disables the i2c watchdog timer .
*
* @param[in] enable : To enable/disable i2c watchdog timer.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disable I2C watchdog timer
* BMI2_ENABLE | Enable I2C watchdog timer
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_i2c_wdt_en(uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiI2C
* \page bmi2_api_bmi2_get_i2c_wdt_en bmi2_get_i2c_wdt_en
* \code
* int8_t bmi2_get_i2c_wdt_en(uint8_t *enable, struct bmi2_dev *dev);
* \endcode
* @details This API gets the enable/disable status of the i2c watchdog timer .
*
* @param[in] enable : Pointer to get status of enable/disable i2c watchdog timer.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disable I2C watchdog timer
* BMI2_ENABLE | Enable I2C watchdog timer
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_i2c_wdt_en(uint8_t *enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiI2C
* \page bmi2_api_bmi2_set_i2c_wdt_sel bmi2_set_i2c_wdt_sel
* \code
* int8_t bmi2_set_i2c_wdt_sel(uint8_t watchdog_select, struct bmi2_dev *dev);
* \endcode
* @details This API sets i2c watchdog timer .
*
* @param[in] watchdog_select : To set watchdog timer for i2c.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Watchdog_select | Description
* ----------------------|---------------
* BMI2_DISABLE | I2C watchdog timeout after 1.25ms
* BMI2_ENABLE | I2c watchdog timeout after 40ms
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_i2c_wdt_sel(uint8_t watchdog_select, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiI2C
* \page bmi2_api_bmi2_get_i2c_wdt_sel bmi2_get_i2c_wdt_sel
* \code
* int8_t bmi2_get_i2c_wdt_sel(uint8_t *watchdog_select, struct bmi2_dev *dev);
* \endcode
* @details This API sets i2c watchdog timer .
*
* @param[in] watchdog_select : Pointer to get watchdog timer for i2c.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Watchdog_select | Description
* --------------------- |---------------
* BMI2_DISABLE | I2C watchdog timeout after 1.25ms
* BMI2_ENABLE | I2c watchdog timeout after 40ms
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_i2c_wdt_sel(uint8_t *watchdog_select, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiRegs Registers
* @brief Set / Get data from the given register address of the sensor
*/
/*!
* \ingroup bmi2ApiRegs
* \page bmi2_api_bmi2_get_regs bmi2_get_regs
* \code
* int8_t bmi2_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi2_dev *dev);
* \endcode
* @details This API reads the data from the given register address of bmi2
* sensor.
*
* @param[in] reg_addr : Register address from which data is read.
* @param[out] data : Pointer to data buffer where read data is stored.
* @param[in] len : No. of bytes of data to be read.
* @param[in] dev : Structure instance of bmi2_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 - 0x26, 0x5E.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiRegs
* \page bmi2_api_bmi2_set_regs bmi2_set_regs
* \code
* int8_t bmi2_set_regs(uint8_t reg_addr, const uint8_t *data, uint16_t len, struct bmi2_dev *dev);
* \endcode
* @details This API writes data to the given register address of bmi2 sensor.
*
* @param[in] reg_addr : Register address to which the data is written.
* @param[in] data : Pointer to data buffer in which data to be written
* is stored.
* @param[in] len : No. of bytes of data to be written.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_regs(uint8_t reg_addr, const uint8_t *data, uint16_t len, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiSR Soft reset
* @brief Set / Get data from the given register address of the sensor
*/
/*!
* \ingroup bmi2ApiSR
* \page bmi2_api_bmi2_soft_reset bmi2_soft_reset
* \code
* int8_t bmi2_soft_reset(struct bmi2_dev *dev);
* \endcode
* @details This API resets bmi2 sensor. All registers are overwritten with
* their default values.
*
* @note If selected interface is SPI, an extra dummy byte is read to bring the
* interface back to SPI from default, after the soft reset command.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_soft_reset(struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiConfig Configuration
* @brief Functions related to configuration of the sensor
*/
/*!
* \ingroup bmi2ApiConfig
* \page bmi2_api_bmi2_get_config_file_version bmi2_get_config_file_version
* \code
* int8_t bmi2_get_config_file_version(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev);
* \endcode
* @details This API is used to get the config file major and minor information.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[out] config_major : pointer to data buffer to store the config major.
* @param[out] config_minor : pointer to data buffer to store the config minor.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_config_file_version(uint8_t *config_major, uint8_t *config_minor, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiPowersave Advanced power save mode
* @brief Set / Get Advanced power save mode of the sensor
*/
/*!
* \ingroup bmi2ApiPowersave
* \page bmi2_api_bmi2_set_adv_power_save bmi2_set_adv_power_save
* \code
* int8_t bmi2_set_adv_power_save(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API enables/disables the advance power save mode in the sensor.
*
* @param[in] enable : To enable/disable advance power mode.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables advance power save.
* BMI2_ENABLE | Enables advance power save.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_adv_power_save(uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiPowersave
* \page bmi2_api_bmi2_get_adv_power_save bmi2_get_adv_power_save
* \code
* int8_t bmi2_get_adv_power_save(uint8_t *aps_status, struct bmi2_dev *dev);
* \endcode
* @details This API gets the status of advance power save mode in the sensor.
*
* @param[out] aps_status : Pointer to get the status of APS mode.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* aps_status | Description
* -------------|---------------
* BMI2_DISABLE | Advance power save disabled.
* BMI2_ENABLE | Advance power save enabled.
*@endverbatim
*
* @return Result of API execution status
*
* @retval BMI2_OK - Success.
* @retval BMI2_E_NULL_PTR - Error: Null pointer error
* @retval BMI2_E_COM_FAIL - Error: Communication fail
* @retval BMI2_E_SET_APS_FAIL - Error: Set Advance Power Save Fail
*/
int8_t bmi2_get_adv_power_save(uint8_t *aps_status, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiPowersave
* \page bmi2_api_bmi2_set_fast_power_up bmi2_set_fast_power_up
* \code
* int8_t bmi2_set_fast_power_up(uint8_t fast_power_up, struct bmi2_dev *dev);
* \endcode
* @details This API enables/disables the fast power up mode in the sensor.
*
* @param[in] fast_power_up : To enable/disable advance power mode.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Fast_power_up | Description
* --------------------|---------------
* BMI2_DISABLE | Disables fast power up.
* BMI2_ENABLE | Enables fast power up.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_fast_power_up(uint8_t fast_power_up, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiPowersave
* \page bmi2_api_bmi2_get_fast_power_up bmi2_get_fast_power_up
* \code
* int8_t bmi2_get_fast_power_up(uint8_t *fast_power_up, struct bmi2_dev *dev);
* \endcode
* @details This API gets the enable/disable status of the fast power up mode in the sensor.
*
* @param[in] fast_power_up : Pointer to get the enable/disable advance power mode.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Fast power up | Description
* --------------------|---------------
* BMI2_DISABLE | Disables fast power up.
* BMI2_ENABLE | Enables fast power up.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fast_power_up(uint8_t *fast_power_up, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiConfig
* \page bmi2_api_bmi2_write_config_file bmi2_write_config_file
* \code
* int8_t bmi2_write_config_file(struct bmi2_dev *dev);
* \endcode
* @details This API loads the configuration file to the bmi2 sensor.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_write_config_file(struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiInt Interrupt
* @brief Interrupt operations of the sensor
*/
/*!
* \ingroup bmi2ApiInt
* \page bmi2_api_bmi2_set_int_pin_config bmi2_set_int_pin_config
* \code
* int8_t bmi2_set_int_pin_config(const struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev);
* \endcode
* @details This API sets:
* 1) The input output configuration of the selected interrupt pin:
* INT1 or INT2.
* 2) The interrupt mode: permanently latched or non-latched.
*
* @param[in] int_cfg : Structure instance of bmi2_int_pin_config.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_int_pin_config(const struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInt
* \page bmi2_api_bmi2_get_int_pin_config bmi2_get_int_pin_config
* \code
* int8_t bmi2_get_int_pin_config(struct bmi2_int_pin_config *int_cfg, const struct bmi2_dev *dev);
* \endcode
* @details This API gets:
* 1) The input output configuration of the selected interrupt pin:
* INT1 or INT2.
* 2) The interrupt mode: permanently latched or non-latched.
*
* @param[in,out] int_cfg : Structure instance of bmi2_int_pin_config.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_int_pin_config(struct bmi2_int_pin_config *int_cfg, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInt
* \page bmi2_api_bmi2_get_int_status bmi2_get_int_status
* \code
* int8_t bmi2_get_int_status(uint16_t *int_status, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the interrupt status of both feature and data
* interrupts.
*
* @param[out] int_status : Pointer to get the status of the interrupts.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* int_status | Status
* -----------|------------
* 0x00 | BIT0
* 0x01 | BIT1
* 0x02 | BIT2
* 0x03 | BIT3
* 0x04 | BIT4
* 0x05 | BIT5
* 0x06 | BIT6
* 0x07 | BIT7
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_int_status(uint16_t *int_status, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiSensorC Sensor Configuration
* @brief Enable / Disable feature configuration of the sensor
*/
/*!
* \ingroup bmi2ApiSensorC
* \page bmi2_api_bmi2_set_sensor_config bmi2_set_sensor_config
* \code
* int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API sets the sensor/feature configuration.
*
* @param[in] sens_cfg : Structure instance of bmi2_sens_config.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features that can be configured
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_ACCEL | 0
* BMI2_GYRO | 1
* BMI2_AUX | 2
* BMI2_GYRO_GAIN_UPDATE | 9
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiSensorC
* \page bmi2_api_bmi2_get_sensor_config bmi2_get_sensor_config
* \code
* int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API gets the sensor/feature configuration.
*
* @param[in] sens_cfg : Structure instance of bmi2_sens_config.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features whose configurations can be read.
*
*@verbatim
* sens_list | Values
* -------------------------|-----------
* BMI2_ACCEL | 0
* BMI2_GYRO | 1
* BMI2_AUX | 2
* BMI2_GYRO_GAIN_UPDATE | 9
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiSensor Feature Set
* @brief Enable / Disable features of the sensor
*/
/*!
* \ingroup bmi2ApiSensor
* \page bmi2_api_bmi2_sensor_enable bmi2_sensor_enable
* \code
* int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API selects the sensors/features to be enabled.
*
* @param[in] sens_list : Pointer to select the sensor/feature.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features that can be enabled.
*
*@verbatim
* sens_list | Values
* -------------------------|-----------
* BMI2_ACCEL | 0
* BMI2_GYRO | 1
* BMI2_AUX | 2
* BMI2_TEMP | 31
*@endverbatim
*
* @note :
* example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO};
* uint8_t n_sens = 2;
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiSensor
* \page bmi2_api_bmi2_sensor_disable bmi2_sensor_disable
* \code
* int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API selects the sensors/features to be disabled.
*
* @param[in] sens_list : Pointer to select the sensor/feature.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features that can be disabled.
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_ACCEL | 0
* BMI2_GYRO | 1
* BMI2_AUX | 2
* BMI2_TEMP | 31
*@endverbatim
*
* @note :
* example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO};
* uint8_t n_sens = 2;
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiSensorD Sensor Data
* @brief Get sensor data
*/
/*!
* \ingroup bmi2ApiSensorD
* \page bmi2_api_bmi2_get_feature_data bmi2_get_feature_data
* \code
* int8_t bmi2_get_feature_data(struct bmi2_feat_sensor_data *feat_sensor_data, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API gets the feature data for gyroscope user-gain update and gyroscope cross sensitivity
*
* @param[out] feat_sensor_data : Structure instance of bmi2_feat_sensor_data.
* @param[in] n_sens : Number of sensors selected.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features whose data can be read
*
*@verbatim
* sens_list | Values
* ---------------------|-----------
* BMI2_GYRO_GAIN_UPDATE| 12
* BMI2_GYRO_CROSS_SENSE| 28
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_feature_data(struct bmi2_feat_sensor_data *feat_sensor_data, uint8_t n_sens, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiSensorD
* \page bmi2_api_bmi2_get_sensor_data bmi2_get_sensor_data
* \code
* int8_t bmi2_get_sensor_data(struct bmi2_sens_data *data, struct bmi2_dev *dev);
* \endcode
* @details This API gets the sensor data for accelerometer, gyroscope and auxiliary sensor
*
* @param[out] data : Structure instance of bmi2_sens_data.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_sensor_data(struct bmi2_sens_data *data, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiTemperature Temperature
* @brief Read temperature of the sensor.
*/
/*!
* \ingroup bmi2ApiTemperature
* \page bmi2_api_bmi2_get_temperature_data bmi2_get_temperature_data
* \code
* int8_t bmi2_get_temperature_data(uint16_t *temp_data, struct bmi2_dev *dev);
* \endcode
* @details This API reads the raw temperature data from the register and can be
* converted into degree celsius using the below formula.
* Formula: temperature_value = (float)(((float)((int16_t)temperature_data)) / 512.0) + 23.0
* @note Enable gyro to read temperature
*
* @param[out] temp_data : Pointer variable which stores the raw temperature value.
* @param[in] dev : Structure instance of bmi2_dev.
*
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_temperature_data(uint16_t *temp_data, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiSensorD
* \page bmi2_api_bmi2_parse_sensor_data bmi2_parse_sensor_data
* \code
* int8_t bmi2_parse_sensor_data(const uint8_t *sensor_data, struct bmi2_sens_data *data, const struct bmi2_dev *dev);
* \endcode
* @details This API parses the sensor data for accelerometer, gyroscope and auxiliary sensor
*
* @param[in] sensor_data : Array of register data (24 bytes from Register 0x03 to 0x1A)
* @param[out] data : Structure instance of bmi2_sens_data.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_parse_sensor_data(const uint8_t *sensor_data, struct bmi2_sens_data *data, const struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiFIFO FIFO
* @brief FIFO operations of the sensor
*/
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_set_fifo_config bmi2_set_fifo_config
* \code
* int8_t bmi2_set_fifo_config(uint16_t config, uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API sets the FIFO configuration in the sensor.
*
* @param[in] config : FIFO configurations to be enabled/disabled.
* @param[in] enable : Enable/Disable FIFO configurations.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables FIFO configuration.
* BMI2_ENABLE | Enables FIFO configuration.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_fifo_config(uint16_t config, uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_fifo_config bmi2_get_fifo_config
* \code
* int8_t bmi2_get_fifo_config(uint16_t *fifo_config, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the FIFO configuration from the sensor.
*
* @param[out] fifo_config : Pointer variable to get FIFO configuration value.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fifo_config(uint16_t *fifo_config, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_read_fifo_data bmi2_read_fifo_data
* \code
* int8_t bmi2_read_fifo_data(struct bmi2_fifo_frame *fifo, const struct bmi2_dev *dev);
* \endcode
* @details This API reads FIFO data.
*
* @param[in, out] fifo : Structure instance of bmi2_fifo_frame.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @note APS has to be disabled before calling this function.
* @note Dummy byte (for SPI Interface) required for FIFO data read
* must be given as part of data pointer in struct bmi2_fifo_frame
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_read_fifo_data(struct bmi2_fifo_frame *fifo, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_extract_accel bmi2_extract_accel
* \code
* int8_t bmi2_extract_accel(struct bmi2_sens_axes_data *accel_data,
* uint16_t *accel_length,
* struct bmi2_fifo_frame *fifo,
* const struct bmi2_dev *dev);
* \endcode
* @details This API parses and extracts the accelerometer frames from FIFO data read by
* the "bmi2_read_fifo_data" API and stores it in the "accel_data" structure
* instance.
*
* @param[out] accel_data : Structure instance of bmi2_sens_axes_data
* where the parsed data bytes are stored.
* @param[in,out] accel_length : Number of accelerometer frames.
* @param[in,out] fifo : Structure instance of bmi2_fifo_frame.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_extract_accel(struct bmi2_sens_axes_data *accel_data,
uint16_t *accel_length,
struct bmi2_fifo_frame *fifo,
const struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_extract_aux bmi2_extract_aux
* \code
* int8_t bmi2_extract_aux(struct bmi2_aux_fifo_data *aux,
* uint16_t *aux_length,
* struct bmi2_fifo_frame *fifo,
* const struct bmi2_dev *dev);
*
* \endcode
* @details This API parses and extracts the auxiliary frames from FIFO data
* read by the "bmi2_read_fifo_data" API and stores it in "aux_data" buffer.
*
* @param[out] aux : Pointer to structure where the parsed auxiliary
* data bytes are stored.
* @param[in,out] aux_length : Number of auxiliary frames.
* @param[in,out] fifo : Structure instance of bmi2_fifo_frame.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_extract_aux(struct bmi2_aux_fifo_data *aux,
uint16_t *aux_length,
struct bmi2_fifo_frame *fifo,
const struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_extract_gyro bmi2_extract_gyro
* \code
* int8_t bmi2_extract_gyro(struct bmi2_sens_axes_data *gyro_data,
* uint16_t *gyro_length,
* struct bmi2_fifo_frame *fifo,
* const struct bmi2_dev *dev);
* \endcode
* @details This API parses and extracts the gyroscope frames from FIFO data read by the
* "bmi2_read_fifo_data" API and stores it in the "gyro_data"
* structure instance.
*
* @param[out] gyro_data : Structure instance of bmi2_sens_axes_data
* where the parsed data bytes are stored.
* @param[in,out] gyro_length : Number of gyroscope frames.
* @param[in,out] fifo : Structure instance of bmi2_fifo_frame.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_extract_gyro(struct bmi2_sens_axes_data *gyro_data,
uint16_t *gyro_length,
struct bmi2_fifo_frame *fifo,
const struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiCmd Command Register
* @brief Write commands to the sensor
*/
/*!
* \ingroup bmi2ApiCmd
* \page bmi2_api_bmi2_set_command_register bmi2_set_command_register
* \code
* int8_t bmi2_set_command_register(uint8_t command, struct bmi2_dev *dev);
* \endcode
* @details This API writes the available sensor specific commands to the sensor.
*
* @param[in] command : Commands to be given to the sensor.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Commands | Values
* ---------------------|---------------------
* BMI2_SOFT_RESET_CMD | 0xB6
* BMI2_FIFO_FLUSH_CMD | 0xB0
* BMI2_USR_GAIN_CMD | 0x03
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_command_register(uint8_t command, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_set_fifo_self_wake_up bmi2_set_fifo_self_wake_up
* \code
* int8_t bmi2_set_fifo_self_wake_up(uint8_t fifo_self_wake_up, struct bmi2_dev *dev);
* \endcode
* @details This API sets the FIFO self wake up functionality in the sensor.
*
* @param[in] fifo_self_wake_up : Variable to set FIFO self wake-up.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* fifo_self_wake_up | Description
* -------------------|---------------
* BMI2_DISABLE | Disables self wake-up.
* BMI2_ENABLE | Enables self wake-up.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_fifo_self_wake_up(uint8_t fifo_self_wake_up, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_fifo_self_wake_up bmi2_get_fifo_self_wake_up
* \code
* int8_t bmi2_get_fifo_self_wake_up(uint8_t *fifo_self_wake_up, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the FIFO self wake up functionality from the sensor.
*
* @param[out] fifo_self_wake_up : Pointer variable to get the status of FIFO
* self wake-up.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* fifo_self_wake_up | Description
* -------------------|---------------
* BMI2_DISABLE | Self wake-up disabled
* BMI2_ENABLE | Self wake-up enabled.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fifo_self_wake_up(uint8_t *fifo_self_wake_up, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_set_fifo_wm bmi2_set_fifo_wm
* \code
* int8_t bmi2_set_fifo_wm(uint16_t fifo_wm, struct bmi2_dev *dev);
* \endcode
* @details This API sets the FIFO water mark level which is set in the sensor.
*
* @param[in] fifo_wm : Variable to set FIFO water-mark level.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_fifo_wm(uint16_t fifo_wm, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_fifo_wm bmi2_get_fifo_wm
* \code
* int8_t bmi2_get_fifo_wm(uint16_t *fifo_wm, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the FIFO water mark level which is set in the sensor.
*
* @param[out] fifo_wm : Pointer variable to store FIFO water-mark level.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fifo_wm(uint16_t *fifo_wm, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_set_fifo_filter_data bmi2_set_fifo_filter_data
* \code
* int8_t bmi2_set_fifo_filter_data(uint8_t sens_sel, uint8_t fifo_filter_data, struct bmi2_dev *dev);
* \endcode
* @details This API sets either filtered or un-filtered FIFO accelerometer or
* gyroscope data.
*
* @param[in] sens_sel : Selects either accelerometer or
* gyroscope sensor.
* @param[in] fifo_filter_data : Variable to set the filter data.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* sens_sel | values
* -----------------|----------
* BMI2_ACCEL | 0x01
* BMI2_GYRO | 0x02
*@endverbatim
*
*@verbatim
* Value | fifo_filter_data
* ---------|---------------------
* 0x00 | Un-filtered data
* 0x01 | Filtered data
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_fifo_filter_data(uint8_t sens_sel, uint8_t fifo_filter_data, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_fifo_filter_data bmi2_get_fifo_filter_data
* \code
* int8_t bmi2_get_fifo_filter_data(uint8_t sens_sel, uint8_t *fifo_filter_data, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the FIFO accelerometer or gyroscope filter data.
*
* @param[in] sens_sel : Selects either accelerometer or
* gyroscope sensor.
* @param[out] fifo_filter_data : Pointer variable to get the filter data.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* sens_sel | values
* -----------------|----------
* BMI2_ACCEL | 0x01
* BMI2_GYRO | 0x02
*@endverbatim
*
*@verbatim
* Value | fifo_filter_data
* ---------|---------------------
* 0x00 | Un-filtered data
* 0x01 | Filtered data
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fifo_filter_data(uint8_t sens_sel, uint8_t *fifo_filter_data, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_set_fifo_down_sample bmi2_set_fifo_down_sample
* \code
* int8_t bmi2_set_fifo_down_sample(uint8_t sens_sel, uint8_t fifo_down_samp, struct bmi2_dev *dev);
* \endcode
* @details This API sets the down sampling rate for FIFO accelerometer or
* gyroscope FIFO data.
*
* @param[in] sens_sel : Selects either either accelerometer or
* gyroscope sensor.
* @param[in] fifo_down_samp : Variable to set the down sampling rate.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* sens_sel | values
* ----------------|----------
* BMI2_ACCEL | 0x01
* BMI2_GYRO | 0x02
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_fifo_down_sample(uint8_t sens_sel, uint8_t fifo_down_samp, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_fifo_down_sample bmi2_get_fifo_down_sample
* \code
* int8_t bmi2_get_fifo_down_sample(uint8_t sens_sel, uint8_t *fifo_down_samp, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the down sampling rate, configured for FIFO
* accelerometer or gyroscope data.
*
* @param[in] sens_sel : Selects either either accelerometer or
* gyroscope sensor.
* @param[out] fifo_down_samp : Pointer variable to store the down sampling rate
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* sens_sel | values
* ----------------|----------
* BMI2_ACCEL | 0x01
* BMI2_GYRO | 0x02
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fifo_down_sample(uint8_t sens_sel, uint8_t *fifo_down_samp, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_fifo_length bmi2_get_fifo_length
* \code
* int8_t bmi2_get_fifo_length(uint16_t *fifo_length, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the length of FIFO data available in the sensor in
* bytes.
*
* @param[out] fifo_length : Pointer variable to store the value of FIFO byte
* counter.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @note The byte counter is updated each time a complete frame is read or
* written.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_fifo_length(uint16_t *fifo_length, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFIFO
* \page bmi2_api_bmi2_get_saturation_status bmi2_get_saturation_status
* \code
* int8_t bmi2_get_saturation_status(uint8_t *status, struct bmi2_dev *dev);
* \endcode
* @details This API reads the saturation status of the sensor.
*
* @param[in] status : Pointer to read the status of saturation.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Macro | Status
* -----------------------------|---------------
* BMI2_SATURATION_ACC_X_MASK | 0X01
* BMI2_SATURATION_ACC_Y_MASK | 0X02
* BMI2_SATURATION_ACC_Z_MASK | 0X04
* BMI2_SATURATION_GYR_X_MASK | 0X08
* BMI2_SATURATION_GYR_Y_MASK | 0X10
* BMI2_SATURATION_GYR_Z_MASK | 0X20
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_saturation_status(uint8_t *status, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiOIS OIS
* @brief OIS operations of the sensor
*/
/*!
* \ingroup bmi2ApiOIS
* \page bmi2_api_bmi2_set_ois_interface bmi2_set_ois_interface
* \code
* int8_t bmi2_set_ois_interface(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API enables/disables OIS interface.
*
* @param[in] enable : To enable/disable OIS interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables OIS interface.
* BMI2_ENABLE | Enables OIS interface.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_ois_interface(uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiOIS
* \page bmi2_api_bmi2_get_spi3_ois_mode bmi2_get_spi3_ois_mode
* \code
* int8_t bmi2_get_spi3_ois_mode(uint8_t *enable, struct bmi2_dev *dev);
* \endcode
* @details This API gets the status of SPI OIS interface.
*
* @param[in] enable : Pointer to read SPI OIS 3/4 wire interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Enable SPI OIS 4 wire mode
* BMI2_ENABLE | Enable SPI OIS 3 wire mode
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_spi3_ois_mode(uint8_t *enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApisensorC
* \page bmi2_api_bmi2_set_drv_reg bmi2_set_drv_reg
* \code
* int8_t bmi2_set_drv_reg(uint8_t drv_reg, struct bmi2_dev *dev);
* \endcode
* @details This API sets the drive strength of the sensor
*
* @param[in] drv_reg : To set the drive strength of the sensor.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_drv_reg(uint8_t drv_reg, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApisensorC
* \page bmi2_api_bmi2_get_drv_reg bmi2_get_drv_reg
* \code
* int8_t bmi2_get_drv_reg(uint8_t *drv_reg, struct bmi2_dev *dev);
* \endcode
* @details This API gets the drive strength of the sensor
*
* @param[in] drv_reg : Pointer to get the drive strength of the sensor.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_drv_reg(uint8_t *drv_reg, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiOIS
* \page bmi2_api_bmi2_set_spi3_ois_mode bmi2_set_spi3_ois_mode
* \code
* int8_t bmi2_set_spi3_ois_mode(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API sets the status of SPI OIS interface.
*
* @param[in] enable : To enable/disable SPI OIS 3/4 wire interface.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Enable SPI OIS 4 wire mode
* BMI2_ENABLE | Enable SPI OIS 3 wire mode
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_spi3_ois_mode(uint8_t enable, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiAux Auxiliary sensor
* @brief Auxiliary sensor operations of the sensor
*/
/*!
* \ingroup bmi2ApiAux
* \page bmi2_api_bmi2_read_aux_man_mode bmi2_read_aux_man_mode
* \code
* int8_t bmi2_read_aux_man_mode(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev);
* \endcode
* @details This API reads the user-defined bytes of data from the given register
* address of auxiliary sensor in manual mode.
*
* @param[in] reg_addr : Address from where data is read.
* @param[out] aux_data : Pointer to the stored buffer.
* @param[in] len : Total length of data to be read.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @note Change of BMI2_AUX_RD_ADDR is only allowed if AUX is not busy.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_read_aux_man_mode(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiAux
* \page bmi2_api_bmi2_write_aux_man_mode bmi2_write_aux_man_mode
* \code
* int8_t bmi2_write_aux_man_mode(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev);
* \endcode
* @details This API writes the user-defined bytes of data and the address of
* auxiliary sensor where data is to be written in manual mode.
*
* @param[in] reg_addr : AUX address where data is to be written.
* @param[in] aux_data : Pointer to data to be written.
* @param[in] len : Total length of data to be written.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @note Change of BMI2_AUX_WR_ADDR is only allowed if AUX is not busy.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_write_aux_man_mode(uint8_t reg_addr, const uint8_t *aux_data, uint16_t len, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiStatus Sensor Status
* @brief Get sensor status
*/
/*!
* \ingroup bmi2ApiStatus
* \page bmi2_api_bmi2_get_status bmi2_get_status
* \code
* int8_t bmi2_get_status(uint8_t *status, const struct bmi2_dev *dev);
* \endcode
* @details This API gets the data ready status of accelerometer, gyroscope,
* auxiliary, ready status of command decoder and busy status of auxiliary.
*
* @param[out] status : Pointer variable to the status.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Value | Status
* ---------|---------------------
* 0x80 | DRDY_ACC
* 0x40 | DRDY_GYR
* 0x20 | DRDY_AUX
* 0x10 | CMD_RDY
* 0x04 | AUX_BUSY
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_status(uint8_t *status, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiWSync Sync commands
* @brief Write sync commands
*/
/*!
* \ingroup bmi2ApiWSync
* \page bmi2_api_bmi2_write_sync_commands bmi2_write_sync_commands
* \code
* int8_t bmi2_write_sync_commands(const uint8_t *command, uint8_t n_comm, struct bmi2_dev *dev);
* \endcode
* @details This API can be used to write sync commands like ODR, sync period,
* frequency and phase, resolution ratio, sync time and delay time.
*
* @param[in] command : Sync command to be written.
* @param[in] n_comm : Length of the command.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_write_sync_commands(const uint8_t *command, uint8_t n_comm, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiASelftest Accel self test
* @brief Perform accel self test
*/
/*!
* \ingroup bmi2ApiASelftest
* \page bmi2_api_bmi2_perform_accel_self_test bmi2_perform_accel_self_test
* \code
* int8_t bmi2_perform_accel_self_test(struct bmi2_dev *dev);
* \endcode
* @details This API performs self-test to check the proper functionality of the
* accelerometer sensor.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_perform_accel_self_test(struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInt
* \page bmi2_api_bmi2_map_feat_int bmi2_map_feat_int
* \code
* int8_t bmi2_map_feat_int(const struct bmi2_sens_int_config *sens_int, struct bmi2_dev *dev);
* \endcode
* @details This API maps/unmaps feature interrupts to that of interrupt pins.
*
* @param[in] sens_int : Structure instance of bmi2_sens_int_config.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_map_feat_int(uint8_t type, enum bmi2_hw_int_pin hw_int_pin, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInt
* \page bmi2_api_bmi2_map_data_int bmi2_map_data_int
* \code
* int8_t bmi2_map_data_int(uint8_t data_int, enum bmi2_hw_int_pin int_pin, struct bmi2_dev *dev);
* \endcode
* @details This API maps/un-maps data interrupts to that of interrupt pins.
*
* @param[in] int_pin : Interrupt pin selected.
* @param[in] data_int : Type of data interrupt to be mapped.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* data_int | Mask values
* ---------------------|---------------------
* BMI2_FFULL_INT | 0x01
* BMI2_FWM_INT | 0x02
* BMI2_DRDY_INT | 0x04
* BMI2_ERR_INT | 0x08
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_map_data_int(uint8_t data_int, enum bmi2_hw_int_pin int_pin, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiRemap Remap Axes
* @brief Set / Get remap axes values from the sensor
*/
/*!
* \ingroup bmi2ApiRemap
* \page bmi2_api_bmi2_get_remap_axes bmi2_get_remap_axes
* \code
* int8_t bmi2_get_remap_axes(struct bmi2_remap *remapped_axis, struct bmi2_dev *dev);
* \endcode
* @details This API gets the re-mapped x, y and z axes from the sensor and
* updates the values in the device structure.
*
* @param[out] remapped_axis : Structure that stores re-mapped axes.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_remap_axes(struct bmi2_remap *remapped_axis, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiRemap
* \page bmi2_api_bmi2_set_remap_axes bmi2_set_remap_axes
* \code
* int8_t bmi2_set_remap_axes(const struct bmi2_remap *remapped_axis, struct bmi2_dev *dev);
* \endcode
* @details This API sets the re-mapped x, y and z axes to the sensor and
* updates them in the device structure.
*
* @param[in] remapped_axis : Structure that stores re-mapped axes.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_remap_axes(const struct bmi2_remap *remapped_axis, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiGyroOC Gyro Offset Compensation
* @brief Gyro Offset Compensation operations of the sensor
*/
/*!
* \ingroup bmi2ApiGyroOC
* \page bmi2_api_bmi2_set_gyro_offset_comp bmi2_set_gyro_offset_comp
* \code
* int8_t bmi2_set_gyro_offset_comp(uint8_t enable, struct bmi2_dev *dev);
* \endcode
* @details This API enables/disables gyroscope offset compensation. It adds the
* offsets defined in the offset register with gyroscope data.
*
* @param[in] enable : Enables/Disables gyroscope offset compensation.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* enable | Description
* -------------|---------------
* BMI2_ENABLE | Enables gyroscope offset compensation.
* BMI2_DISABLE | Disables gyroscope offset compensation.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_gyro_offset_comp(uint8_t enable, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiGyroOC
* \page bmi2_api_bmi2_set_gyro_offset_comp bmi2_get_gyro_offset_comp
* \code
* int8_t bmi2_get_gyro_offset_comp(uint8_t *offset, struct bmi2_dev *dev);
* \endcode
* @details This API reads the gyroscope offset compensation.
*
* @param[in, out] offset : The value of the offset compensation.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* enable | Description
* -------------|---------------
* BMI2_ENABLE | Enables gyroscope offset compensation.
* BMI2_DISABLE | Disables gyroscope offset compensation.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_gyro_offset_comp(uint8_t *offset, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiGyroOC
* \page bmi2_api_bmi2_set_gyro_offset_comp bmi2_set_gyro_gain
* \code
* int8_t bmi2_set_gyro_gain(uint8_t gyro_gain, struct bmi2_dev *dev);
* \endcode
* @details This API enables/disables gyroscope gain for Sensitivity Error Compensation.
*
* @param[in] gyro_gain : Enables/Disables gyroscope gain.
* @param[in] dev : Structure instance of bmi2_dev.
*
*@verbatim
* enable | Description
* -------------|---------------
* BMI2_ENABLE | Enables gyroscope gain.
* BMI2_DISABLE | Disables gyroscope gain.
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_gyro_gain(uint8_t gyro_gain, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiGyroOC
* \page bmi2_api_bmi2_set_gyro_offset_comp bmi2_get_gyro_gain
* \code
* int8_t bmi2_get_gyro_gain(uint8_t *gyro_gain, struct bmi2_dev *dev);
* \endcode
* @details This API reads the Gyro gain.
*
* @param[in, out] gyro_gain : The value of the Gyro gain.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_gyro_gain(uint8_t *gyro_gain, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiGyroOC
* \page bmi2_api_bmi2_read_gyro_offset_comp_axes bmi2_read_gyro_offset_comp_axes
* \code
* int8_t bmi2_read_gyro_offset_comp_axes(struct bmi2_sens_axes_data *gyr_off_comp_axes, const struct bmi2_dev *dev);
* \endcode
* @details This API reads the gyroscope bias values for each axis which is used
* for gyroscope offset compensation.
*
* @param[out] gyr_off_comp_axes: Structure to store gyroscope offset
* compensated values.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_read_gyro_offset_comp_axes(struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiGyroOC
* \page bmi2_api_bmi2_write_gyro_offset_comp_axes bmi2_write_gyro_offset_comp_axes
* \code
* int8_t bmi2_write_gyro_offset_comp_axes(const struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev);
* \endcode
* @details This API writes the gyroscope bias values for each axis which is used
* for gyroscope offset compensation.
*
* @param[in] gyr_off_comp_axes : Structure to store gyroscope offset
* compensated values.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_write_gyro_offset_comp_axes(const struct bmi2_sens_axes_data *gyr_off_comp_axes, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiGyroCS Gyro cross sensitivity
* @brief Gyro Cross sensitivity operation
*/
/*!
* \ingroup bmi2ApiGyroCS
* \page bmi2_api_bmi2_get_gyro_cross_sense bmi2_get_gyro_cross_sense
* \code
* int8_t bmi2_get_gyro_cross_sense(struct bmi2_dev *dev);
* \endcode
* @details This API updates the cross sensitivity coefficient between gyroscope's
* X and Z axes.
*
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_gyro_cross_sense(struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiInts Internal Status
* @brief Get Internal Status of the sensor
*/
/*!
* \ingroup bmi2ApiInts
* \page bmi2_api_bmi2_get_internal_status bmi2_get_internal_status
* \code
* int8_t bmi2_get_internal_status(uint8_t *int_stat, const struct bmi2_dev *dev);
* \endcode
* @details This API gets error bits and message indicating internal status.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[out] int_stat : Pointer variable to store error bits and
* message.
*
*@verbatim
* Internal status | *int_stat
* ---------------------|---------------------
* BMI2_NOT_INIT | 0x00
* BMI2_INIT_OK | 0x01
* BMI2_INIT_ERR | 0x02
* BMI2_DRV_ERR | 0x03
* BMI2_SNS_STOP | 0x04
* BMI2_NVM_ERROR | 0x05
* BMI2_START_UP_ERROR | 0x06
* BMI2_COMPAT_ERROR | 0x07
* BMI2_VFM_SKIPPED | 0x10
* BMI2_AXES_MAP_ERROR | 0x20
* BMI2_ODR_50_HZ_ERROR | 0x40
* BMI2_ODR_HIGH_ERROR | 0x80
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_internal_status(uint8_t *int_stat, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInts
* \page bmi2_api_bmi2_get_internal_error_status bmi2_get_internal_error_status
* \code
* int8_t bmi2_get_internal_error_status(uint8_t *status, struct bmi2_dev *dev);
* \endcode
* @details This API gets Interanl error status.
*
* @param[in] status : Pointer variable to store the status of the error
* @param[out] int_stat : Pointer variable to store error bits and
* message.
*
*@verbatim
* Internal status | status
* ---------------------------|---------------------
* BMI2_INTERNAL_ERROR_1_MASK | 0X02
* BMI2_INTERNAL_ERROR_2_MASK | 0X04
* BMI2_FEAT_ENG_DIS_MASK | 0X10
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_internal_error_status(uint8_t *status, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInts
* \page bmi2_api_bmi2_get_err_reg_mask bmi2_get_err_reg_mask
* \code
* int8_t bmi2_get_err_reg_mask(uint8_t *err_reg, struct bmi2_dev *dev);
* \endcode
* @details This API gets error status of interrupt.
*
* @param[in] err_reg : Pointer variable to store the status of the error
* @param[out] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Internal status | err_reg
* ---------------------------|---------------------
* BMI2_FATAL_ERR_MASK | 0X01
* BMI2_INTERNAL_ERR_MASK | 0X1E
* BMI2_FIFO_ERR_MASK | 0X40
* BMI2_AUX_ERR_MASK | 0x80
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_err_reg_mask(uint8_t *err_reg, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiInts
* \page bmi2_api_bmi2_set_err_reg_mask bmi2_set_err_reg_mask
* \code
* int8_t bmi2_set_err_reg_mask(uint8_t err_reg, struct bmi2_dev *dev);
* \endcode
* @details This API sets error interrupt.
*
* @param[in] err_reg : Variable to store the status of the error
* @param[out] dev : Structure instance of bmi2_dev.
*
*@verbatim
* Internal status | err_reg
* ---------------------------|---------------------
* BMI2_FATAL_ERR_MASK | 0X01
* BMI2_INTERNAL_ERR_MASK | 0X1E
* BMI2_FIFO_ERR_MASK | 0X40
* BMI2_AUX_ERR_MASK | 0x80
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_err_reg_mask(uint8_t err_reg, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiFOC FOC
* @brief FOC operations of the sensor
*/
/*!
* \ingroup bmi2ApiFOC
* \page bmi2_api_bmi2_perform_accel_foc bmi2_perform_accel_foc
* \code
* int8_t bmi2_perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, struct bmi2_dev *dev);
* \endcode
* @details This API performs Fast Offset Compensation for accelerometer.
*
* @param[in] accel_g_value : This parameter selects the accel foc
* axis to be performed
*
* input format is {x, y, z, sign}. '1' to enable. '0' to disable
*
* eg to choose x axis {1, 0, 0, 0}
* eg to choose -x axis {1, 0, 0, 1}
*
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_perform_accel_foc(const struct bmi2_accel_foc_g_value *accel_g_value, struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiFOC
* \page bmi2_api_bmi2_perform_gyro_foc bmi2_perform_gyro_foc
* \code
* int8_t bmi2_perform_gyro_foc(struct bmi2_dev *dev);
* \endcode
* @details This API performs Fast Offset Compensation for gyroscope.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_perform_gyro_foc(struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiCRT CRT
* @brief CRT operations of the sensor
*/
/*!
* \ingroup bmi2ApiCRT
* \page bmi2_api_bmi2_do_crt bmi2_do_crt
* \code
* int8_t bmi2_do_crt(struct bmi2_dev *dev);
* \endcode
* @details API performs Component Re-Trim calibration (CRT).
*
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*
* @note CRT calibration takes approximately 500ms & maximum time out configured as 2 seconds
*/
int8_t bmi2_do_crt(struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiCRTSt CRT and self test
* @brief Enable / Abort CRT and self test operations of gyroscope
*/
/*!
* \ingroup bmi2ApiCRTSt
* \page bmi2_api_bmi2_abort_crt_gyro_st bmi2_abort_crt_gyro_st
* \code
* int8_t bmi2_abort_crt_gyro_st(struct bmi2_dev *dev);
* \endcode
* @details This api is used to abort ongoing crt or gyro self test.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_abort_crt_gyro_st(struct bmi2_dev *dev);
/*!
* \ingroup bmi2ApiASelftest
* \page bmi2_api_bmi2_do_gyro_st bmi2_do_gyro_st
* \code
* int8_t bmi2_do_gyro_st
* \endcode
* @details this api is used to perform gyroscope self test.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_do_gyro_st(struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2ApiNVM NVM
* @brief NVM operations of the sensor
*/
/*!
* \ingroup bmi2ApiNVM
* \page bmi2_api_bmi2_nvm_prog bmi2_nvm_prog
* \code
* int8_t bmi2_nvm_prog
* \endcode
* @details This api is used for programming the non volatile memory(nvm)
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_nvm_prog(struct bmi2_dev *dev);
/*!
* @brief This API extracts the input feature configuration
* details like page and start address from the look-up table.
*
* @param[out] feat_config : Structure that stores feature configurations.
* @param[in] type : Type of feature or sensor.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Returns the feature found flag.
*
* @retval BMI2_FALSE : Feature not found
* BMI2_TRUE : Feature found
*/
uint8_t bmi2_extract_input_feat_config(struct bmi2_feature_config *feat_config, uint8_t type,
const struct bmi2_dev *dev);
/*!
* @brief This API is used to get the feature configuration from the
* selected page.
*
* @param[in] sw_page : Switches to the desired page.
* @param[out] feat_config : Pointer to the feature configuration.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_feat_config(uint8_t sw_page, uint8_t *feat_config, struct bmi2_dev *dev);
/**
* \ingroup bmi2
* \defgroup bmi2AccelOffset Accelerometer Offset Compensation
* @brief Enable / Disable Accelerometer Offset Compensation
*/
/*!
* \ingroup bmi2AccelOffset
* \page bmi2_api_bmi2_set_accel_offset_comp bmi2_set_accel_offset_comp
* \code
* int8_t bmi2_set_accel_offset_comp(uint8_t offset_en, struct bmi2_dev *dev);
* \endcode
* @brief This internal API enables/disables the offset compensation for
* filtered and un-filtered accelerometer data.
*
* @param[in] offset_en : enables/disables offset compensation.
* @param[in] dev : Structure instance of bmi2_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_set_accel_offset_comp(uint8_t offset_en, struct bmi2_dev *dev);
/*!
* \ingroup bmi2AccelOffset
* \page bmi2_api_bmi2_get_accel_offset_comp bmi2_get_accel_offset_comp
* \code
* int8_t bmi2_get_accel_offset_comp(uint8_t *accel_offset, struct bmi2_dev *dev);
* \endcode
* @brief This internal API reads the accelerometer offset compensation value.
*
* @param[in] accel_offset : Pointer to an array of size 3 to hold Accel Axis X, Y, Z,
* Offset Compensation.
* @param[in] dev : Structure instance of bmi2_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi2_get_accel_offset_comp(uint8_t *accel_offset, struct bmi2_dev *dev);
#ifdef __cplusplus
}
#endif /* End of CPP guard */
#endif /* BMI2_H_ */
/**
* Copyright (c) 2023 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 bmi270.c
* @date 2023-05-03
* @version v2.86.1
*
*/
/***************************************************************************/
/*! Header files
****************************************************************************/
#include "bmi270.h"
/***************************************************************************/
/*! Global Variable
****************************************************************************/
/*! @name Global array that stores the configuration file of BMI270 */
const uint8_t bmi270_config_file[] = {
0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x3d, 0xb1, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x91, 0x03, 0x80, 0x2e, 0xbc,
0xb0, 0x80, 0x2e, 0xa3, 0x03, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x00, 0xb0, 0x50, 0x30, 0x21, 0x2e, 0x59, 0xf5,
0x10, 0x30, 0x21, 0x2e, 0x6a, 0xf5, 0x80, 0x2e, 0x3b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x01, 0x00, 0x22,
0x00, 0x75, 0x00, 0x00, 0x10, 0x00, 0x10, 0xd1, 0x00, 0xb3, 0x43, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e,
0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e,
0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0xe0, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0xe0, 0xaa, 0x38, 0x05, 0xe0, 0x90, 0x30, 0xfa, 0x00, 0x96, 0x00, 0x4b, 0x09, 0x11, 0x00, 0x11, 0x00, 0x02, 0x00,
0x2d, 0x01, 0xd4, 0x7b, 0x3b, 0x01, 0xdb, 0x7a, 0x04, 0x00, 0x3f, 0x7b, 0xcd, 0x6c, 0xc3, 0x04, 0x85, 0x09, 0xc3,
0x04, 0xec, 0xe6, 0x0c, 0x46, 0x01, 0x00, 0x27, 0x00, 0x19, 0x00, 0x96, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x0c, 0x00,
0xf0, 0x3c, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x00, 0x05, 0x00, 0xee,
0x06, 0x04, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x04, 0x00, 0xa8, 0x05, 0xee, 0x06, 0x00, 0x04, 0xbc, 0x02, 0xb3, 0x00,
0x85, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xb4, 0x00, 0x01, 0x00, 0xb9, 0x00, 0x01, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0xde,
0x00, 0xeb, 0x00, 0xda, 0x00, 0x00, 0x0c, 0xff, 0x0f, 0x00, 0x04, 0xc0, 0x00, 0x5b, 0xf5, 0xc9, 0x01, 0x1e, 0xf2,
0x80, 0x00, 0x3f, 0xff, 0x19, 0xf4, 0x58, 0xf5, 0x66, 0xf5, 0x64, 0xf5, 0xc0, 0xf1, 0xf0, 0x00, 0xe0, 0x00, 0xcd,
0x01, 0xd3, 0x01, 0xdb, 0x01, 0xff, 0x7f, 0xff, 0x01, 0xe4, 0x00, 0x74, 0xf7, 0xf3, 0x00, 0xfa, 0x00, 0xff, 0x3f,
0xca, 0x03, 0x6c, 0x38, 0x56, 0xfe, 0x44, 0xfd, 0xbc, 0x02, 0xf9, 0x06, 0x00, 0xfc, 0x12, 0x02, 0xae, 0x01, 0x58,
0xfa, 0x9a, 0xfd, 0x77, 0x05, 0xbb, 0x02, 0x96, 0x01, 0x95, 0x01, 0x7f, 0x01, 0x82, 0x01, 0x89, 0x01, 0x87, 0x01,
0x88, 0x01, 0x8a, 0x01, 0x8c, 0x01, 0x8f, 0x01, 0x8d, 0x01, 0x92, 0x01, 0x91, 0x01, 0xdd, 0x00, 0x9f, 0x01, 0x7e,
0x01, 0xdb, 0x00, 0xb6, 0x01, 0x70, 0x69, 0x26, 0xd3, 0x9c, 0x07, 0x1f, 0x05, 0x9d, 0x00, 0x00, 0x08, 0xbc, 0x05,
0x37, 0xfa, 0xa2, 0x01, 0xaa, 0x01, 0xa1, 0x01, 0xa8, 0x01, 0xa0, 0x01, 0xa8, 0x05, 0xb4, 0x01, 0xb4, 0x01, 0xce,
0x00, 0xd0, 0x00, 0xfc, 0x00, 0xc5, 0x01, 0xff, 0xfb, 0xb1, 0x00, 0x00, 0x38, 0x00, 0x30, 0xfd, 0xf5, 0xfc, 0xf5,
0xcd, 0x01, 0xa0, 0x00, 0x5f, 0xff, 0x00, 0x40, 0xff, 0x00, 0x00, 0x80, 0x6d, 0x0f, 0xeb, 0x00, 0x7f, 0xff, 0xc2,
0xf5, 0x68, 0xf7, 0xb3, 0xf1, 0x67, 0x0f, 0x5b, 0x0f, 0x61, 0x0f, 0x80, 0x0f, 0x58, 0xf7, 0x5b, 0xf7, 0x83, 0x0f,
0x86, 0x00, 0x72, 0x0f, 0x85, 0x0f, 0xc6, 0xf1, 0x7f, 0x0f, 0x6c, 0xf7, 0x00, 0xe0, 0x00, 0xff, 0xd1, 0xf5, 0x87,
0x0f, 0x8a, 0x0f, 0xff, 0x03, 0xf0, 0x3f, 0x8b, 0x00, 0x8e, 0x00, 0x90, 0x00, 0xb9, 0x00, 0x2d, 0xf5, 0xca, 0xf5,
0xcb, 0x01, 0x20, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x50, 0x98, 0x2e,
0xd7, 0x0e, 0x50, 0x32, 0x98, 0x2e, 0xfa, 0x03, 0x00, 0x30, 0xf0, 0x7f, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x00,
0x2e, 0x01, 0x80, 0x08, 0xa2, 0xfb, 0x2f, 0x98, 0x2e, 0xba, 0x03, 0x21, 0x2e, 0x19, 0x00, 0x01, 0x2e, 0xee, 0x00,
0x00, 0xb2, 0x07, 0x2f, 0x01, 0x2e, 0x19, 0x00, 0x00, 0xb2, 0x03, 0x2f, 0x01, 0x50, 0x03, 0x52, 0x98, 0x2e, 0x07,
0xcc, 0x01, 0x2e, 0xdd, 0x00, 0x00, 0xb2, 0x27, 0x2f, 0x05, 0x2e, 0x8a, 0x00, 0x05, 0x52, 0x98, 0x2e, 0xc7, 0xc1,
0x03, 0x2e, 0xe9, 0x00, 0x40, 0xb2, 0xf0, 0x7f, 0x08, 0x2f, 0x01, 0x2e, 0x19, 0x00, 0x00, 0xb2, 0x04, 0x2f, 0x00,
0x30, 0x21, 0x2e, 0xe9, 0x00, 0x98, 0x2e, 0xb4, 0xb1, 0x01, 0x2e, 0x18, 0x00, 0x00, 0xb2, 0x10, 0x2f, 0x05, 0x50,
0x98, 0x2e, 0x4d, 0xc3, 0x05, 0x50, 0x98, 0x2e, 0x5a, 0xc7, 0x98, 0x2e, 0xf9, 0xb4, 0x98, 0x2e, 0x54, 0xb2, 0x98,
0x2e, 0x67, 0xb6, 0x98, 0x2e, 0x17, 0xb2, 0x10, 0x30, 0x21, 0x2e, 0x77, 0x00, 0x01, 0x2e, 0xef, 0x00, 0x00, 0xb2,
0x04, 0x2f, 0x98, 0x2e, 0x7a, 0xb7, 0x00, 0x30, 0x21, 0x2e, 0xef, 0x00, 0x01, 0x2e, 0xd4, 0x00, 0x04, 0xae, 0x0b,
0x2f, 0x01, 0x2e, 0xdd, 0x00, 0x00, 0xb2, 0x07, 0x2f, 0x05, 0x52, 0x98, 0x2e, 0x8e, 0x0e, 0x00, 0xb2, 0x02, 0x2f,
0x10, 0x30, 0x21, 0x2e, 0x7d, 0x00, 0x01, 0x2e, 0x7d, 0x00, 0x00, 0x90, 0x90, 0x2e, 0xf1, 0x02, 0x01, 0x2e, 0xd7,
0x00, 0x00, 0xb2, 0x04, 0x2f, 0x98, 0x2e, 0x2f, 0x0e, 0x00, 0x30, 0x21, 0x2e, 0x7b, 0x00, 0x01, 0x2e, 0x7b, 0x00,
0x00, 0xb2, 0x12, 0x2f, 0x01, 0x2e, 0xd4, 0x00, 0x00, 0x90, 0x02, 0x2f, 0x98, 0x2e, 0x1f, 0x0e, 0x09, 0x2d, 0x98,
0x2e, 0x81, 0x0d, 0x01, 0x2e, 0xd4, 0x00, 0x04, 0x90, 0x02, 0x2f, 0x50, 0x32, 0x98, 0x2e, 0xfa, 0x03, 0x00, 0x30,
0x21, 0x2e, 0x7b, 0x00, 0x01, 0x2e, 0x7c, 0x00, 0x00, 0xb2, 0x90, 0x2e, 0x09, 0x03, 0x01, 0x2e, 0x7c, 0x00, 0x01,
0x31, 0x01, 0x08, 0x00, 0xb2, 0x04, 0x2f, 0x98, 0x2e, 0x47, 0xcb, 0x10, 0x30, 0x21, 0x2e, 0x77, 0x00, 0x81, 0x30,
0x01, 0x2e, 0x7c, 0x00, 0x01, 0x08, 0x00, 0xb2, 0x61, 0x2f, 0x03, 0x2e, 0x89, 0x00, 0x01, 0x2e, 0xd4, 0x00, 0x98,
0xbc, 0x98, 0xb8, 0x05, 0xb2, 0x0f, 0x58, 0x23, 0x2f, 0x07, 0x90, 0x09, 0x54, 0x00, 0x30, 0x37, 0x2f, 0x15, 0x41,
0x04, 0x41, 0xdc, 0xbe, 0x44, 0xbe, 0xdc, 0xba, 0x2c, 0x01, 0x61, 0x00, 0x0f, 0x56, 0x4a, 0x0f, 0x0c, 0x2f, 0xd1,
0x42, 0x94, 0xb8, 0xc1, 0x42, 0x11, 0x30, 0x05, 0x2e, 0x6a, 0xf7, 0x2c, 0xbd, 0x2f, 0xb9, 0x80, 0xb2, 0x08, 0x22,
0x98, 0x2e, 0xc3, 0xb7, 0x21, 0x2d, 0x61, 0x30, 0x23, 0x2e, 0xd4, 0x00, 0x98, 0x2e, 0xc3, 0xb7, 0x00, 0x30, 0x21,
0x2e, 0x5a, 0xf5, 0x18, 0x2d, 0xe1, 0x7f, 0x50, 0x30, 0x98, 0x2e, 0xfa, 0x03, 0x0f, 0x52, 0x07, 0x50, 0x50, 0x42,
0x70, 0x30, 0x0d, 0x54, 0x42, 0x42, 0x7e, 0x82, 0xe2, 0x6f, 0x80, 0xb2, 0x42, 0x42, 0x05, 0x2f, 0x21, 0x2e, 0xd4,
0x00, 0x10, 0x30, 0x98, 0x2e, 0xc3, 0xb7, 0x03, 0x2d, 0x60, 0x30, 0x21, 0x2e, 0xd4, 0x00, 0x01, 0x2e, 0xd4, 0x00,
0x06, 0x90, 0x18, 0x2f, 0x01, 0x2e, 0x76, 0x00, 0x0b, 0x54, 0x07, 0x52, 0xe0, 0x7f, 0x98, 0x2e, 0x7a, 0xc1, 0xe1,
0x6f, 0x08, 0x1a, 0x40, 0x30, 0x08, 0x2f, 0x21, 0x2e, 0xd4, 0x00, 0x20, 0x30, 0x98, 0x2e, 0xaf, 0xb7, 0x50, 0x32,
0x98, 0x2e, 0xfa, 0x03, 0x05, 0x2d, 0x98, 0x2e, 0x38, 0x0e, 0x00, 0x30, 0x21, 0x2e, 0xd4, 0x00, 0x00, 0x30, 0x21,
0x2e, 0x7c, 0x00, 0x18, 0x2d, 0x01, 0x2e, 0xd4, 0x00, 0x03, 0xaa, 0x01, 0x2f, 0x98, 0x2e, 0x45, 0x0e, 0x01, 0x2e,
0xd4, 0x00, 0x3f, 0x80, 0x03, 0xa2, 0x01, 0x2f, 0x00, 0x2e, 0x02, 0x2d, 0x98, 0x2e, 0x5b, 0x0e, 0x30, 0x30, 0x98,
0x2e, 0xce, 0xb7, 0x00, 0x30, 0x21, 0x2e, 0x7d, 0x00, 0x50, 0x32, 0x98, 0x2e, 0xfa, 0x03, 0x01, 0x2e, 0x77, 0x00,
0x00, 0xb2, 0x24, 0x2f, 0x98, 0x2e, 0xf5, 0xcb, 0x03, 0x2e, 0xd5, 0x00, 0x11, 0x54, 0x01, 0x0a, 0xbc, 0x84, 0x83,
0x86, 0x21, 0x2e, 0xc9, 0x01, 0xe0, 0x40, 0x13, 0x52, 0xc4, 0x40, 0x82, 0x40, 0xa8, 0xb9, 0x52, 0x42, 0x43, 0xbe,
0x53, 0x42, 0x04, 0x0a, 0x50, 0x42, 0xe1, 0x7f, 0xf0, 0x31, 0x41, 0x40, 0xf2, 0x6f, 0x25, 0xbd, 0x08, 0x08, 0x02,
0x0a, 0xd0, 0x7f, 0x98, 0x2e, 0xa8, 0xcf, 0x06, 0xbc, 0xd1, 0x6f, 0xe2, 0x6f, 0x08, 0x0a, 0x80, 0x42, 0x98, 0x2e,
0x58, 0xb7, 0x00, 0x30, 0x21, 0x2e, 0xee, 0x00, 0x21, 0x2e, 0x77, 0x00, 0x21, 0x2e, 0xdd, 0x00, 0x80, 0x2e, 0xf4,
0x01, 0x1a, 0x24, 0x22, 0x00, 0x80, 0x2e, 0xec, 0x01, 0x10, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0xf3, 0x03, 0x57, 0x50,
0xfb, 0x6f, 0x01, 0x30, 0x71, 0x54, 0x11, 0x42, 0x42, 0x0e, 0xfc, 0x2f, 0xc0, 0x2e, 0x01, 0x42, 0xf0, 0x5f, 0x80,
0x2e, 0x00, 0xc1, 0xfd, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x01,
0x34, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x06, 0x32, 0x0f, 0x2e, 0x61, 0xf5, 0xfe, 0x09, 0xc0, 0xb3, 0x04,
0x2f, 0x17, 0x30, 0x2f, 0x2e, 0xef, 0x00, 0x2d, 0x2e, 0x61, 0xf5, 0xf6, 0x6f, 0xe7, 0x6f, 0xe0, 0x5f, 0xc8, 0x2e,
0x20, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x46, 0x30, 0x0f, 0x2e, 0xa4, 0xf1, 0xbe, 0x09, 0x80, 0xb3, 0x06, 0x2f, 0x0d,
0x2e, 0xd4, 0x00, 0x84, 0xaf, 0x02, 0x2f, 0x16, 0x30, 0x2d, 0x2e, 0x7b, 0x00, 0x86, 0x30, 0x2d, 0x2e, 0x60, 0xf5,
0xf6, 0x6f, 0xe7, 0x6f, 0xe0, 0x5f, 0xc8, 0x2e, 0x01, 0x2e, 0x77, 0xf7, 0x09, 0xbc, 0x0f, 0xb8, 0x00, 0xb2, 0x10,
0x50, 0xfb, 0x7f, 0x10, 0x30, 0x0b, 0x2f, 0x03, 0x2e, 0x8a, 0x00, 0x96, 0xbc, 0x9f, 0xb8, 0x40, 0xb2, 0x05, 0x2f,
0x03, 0x2e, 0x68, 0xf7, 0x9e, 0xbc, 0x9f, 0xb8, 0x40, 0xb2, 0x07, 0x2f, 0x03, 0x2e, 0x7e, 0x00, 0x41, 0x90, 0x01,
0x2f, 0x98, 0x2e, 0xdc, 0x03, 0x03, 0x2c, 0x00, 0x30, 0x21, 0x2e, 0x7e, 0x00, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e,
0x20, 0x50, 0xe0, 0x7f, 0xfb, 0x7f, 0x00, 0x2e, 0x27, 0x50, 0x98, 0x2e, 0x3b, 0xc8, 0x29, 0x50, 0x98, 0x2e, 0xa7,
0xc8, 0x01, 0x50, 0x98, 0x2e, 0x55, 0xcc, 0xe1, 0x6f, 0x2b, 0x50, 0x98, 0x2e, 0xe0, 0xc9, 0xfb, 0x6f, 0x00, 0x30,
0xe0, 0x5f, 0x21, 0x2e, 0x7e, 0x00, 0xb8, 0x2e, 0x73, 0x50, 0x01, 0x30, 0x57, 0x54, 0x11, 0x42, 0x42, 0x0e, 0xfc,
0x2f, 0xb8, 0x2e, 0x21, 0x2e, 0x59, 0xf5, 0x10, 0x30, 0xc0, 0x2e, 0x21, 0x2e, 0x4a, 0xf1, 0x90, 0x50, 0xf7, 0x7f,
0xe6, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa1, 0x7f, 0x90, 0x7f, 0x82, 0x7f, 0x7b, 0x7f, 0x98, 0x2e, 0x35,
0xb7, 0x00, 0xb2, 0x90, 0x2e, 0x97, 0xb0, 0x03, 0x2e, 0x8f, 0x00, 0x07, 0x2e, 0x91, 0x00, 0x05, 0x2e, 0xb1, 0x00,
0x3f, 0xba, 0x9f, 0xb8, 0x01, 0x2e, 0xb1, 0x00, 0xa3, 0xbd, 0x4c, 0x0a, 0x05, 0x2e, 0xb1, 0x00, 0x04, 0xbe, 0xbf,
0xb9, 0xcb, 0x0a, 0x4f, 0xba, 0x22, 0xbd, 0x01, 0x2e, 0xb3, 0x00, 0xdc, 0x0a, 0x2f, 0xb9, 0x03, 0x2e, 0xb8, 0x00,
0x0a, 0xbe, 0x9a, 0x0a, 0xcf, 0xb9, 0x9b, 0xbc, 0x01, 0x2e, 0x97, 0x00, 0x9f, 0xb8, 0x93, 0x0a, 0x0f, 0xbc, 0x91,
0x0a, 0x0f, 0xb8, 0x90, 0x0a, 0x25, 0x2e, 0x18, 0x00, 0x05, 0x2e, 0xc1, 0xf5, 0x2e, 0xbd, 0x2e, 0xb9, 0x01, 0x2e,
0x19, 0x00, 0x31, 0x30, 0x8a, 0x04, 0x00, 0x90, 0x07, 0x2f, 0x01, 0x2e, 0xd4, 0x00, 0x04, 0xa2, 0x03, 0x2f, 0x01,
0x2e, 0x18, 0x00, 0x00, 0xb2, 0x0c, 0x2f, 0x19, 0x50, 0x05, 0x52, 0x98, 0x2e, 0x4d, 0xb7, 0x05, 0x2e, 0x78, 0x00,
0x80, 0x90, 0x10, 0x30, 0x01, 0x2f, 0x21, 0x2e, 0x78, 0x00, 0x25, 0x2e, 0xdd, 0x00, 0x98, 0x2e, 0x3e, 0xb7, 0x00,
0xb2, 0x02, 0x30, 0x01, 0x30, 0x04, 0x2f, 0x01, 0x2e, 0x19, 0x00, 0x00, 0xb2, 0x00, 0x2f, 0x21, 0x30, 0x01, 0x2e,
0xea, 0x00, 0x08, 0x1a, 0x0e, 0x2f, 0x23, 0x2e, 0xea, 0x00, 0x33, 0x30, 0x1b, 0x50, 0x0b, 0x09, 0x01, 0x40, 0x17,
0x56, 0x46, 0xbe, 0x4b, 0x08, 0x4c, 0x0a, 0x01, 0x42, 0x0a, 0x80, 0x15, 0x52, 0x01, 0x42, 0x00, 0x2e, 0x01, 0x2e,
0x18, 0x00, 0x00, 0xb2, 0x1f, 0x2f, 0x03, 0x2e, 0xc0, 0xf5, 0xf0, 0x30, 0x48, 0x08, 0x47, 0xaa, 0x74, 0x30, 0x07,
0x2e, 0x7a, 0x00, 0x61, 0x22, 0x4b, 0x1a, 0x05, 0x2f, 0x07, 0x2e, 0x66, 0xf5, 0xbf, 0xbd, 0xbf, 0xb9, 0xc0, 0x90,
0x0b, 0x2f, 0x1d, 0x56, 0x2b, 0x30, 0xd2, 0x42, 0xdb, 0x42, 0x01, 0x04, 0xc2, 0x42, 0x04, 0xbd, 0xfe, 0x80, 0x81,
0x84, 0x23, 0x2e, 0x7a, 0x00, 0x02, 0x42, 0x02, 0x32, 0x25, 0x2e, 0x62, 0xf5, 0x05, 0x2e, 0xd6, 0x00, 0x81, 0x84,
0x25, 0x2e, 0xd6, 0x00, 0x02, 0x31, 0x25, 0x2e, 0x60, 0xf5, 0x05, 0x2e, 0x8a, 0x00, 0x0b, 0x50, 0x90, 0x08, 0x80,
0xb2, 0x0b, 0x2f, 0x05, 0x2e, 0xca, 0xf5, 0xf0, 0x3e, 0x90, 0x08, 0x25, 0x2e, 0xca, 0xf5, 0x05, 0x2e, 0x59, 0xf5,
0xe0, 0x3f, 0x90, 0x08, 0x25, 0x2e, 0x59, 0xf5, 0x90, 0x6f, 0xa1, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe6,
0x6f, 0xf7, 0x6f, 0x7b, 0x6f, 0x82, 0x6f, 0x70, 0x5f, 0xc8, 0x2e, 0xc0, 0x50, 0x90, 0x7f, 0xe5, 0x7f, 0xd4, 0x7f,
0xc3, 0x7f, 0xb1, 0x7f, 0xa2, 0x7f, 0x87, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x60, 0xf5, 0x60,
0x7f, 0x98, 0x2e, 0x35, 0xb7, 0x02, 0x30, 0x63, 0x6f, 0x15, 0x52, 0x50, 0x7f, 0x62, 0x7f, 0x5a, 0x2c, 0x02, 0x32,
0x1a, 0x09, 0x00, 0xb3, 0x14, 0x2f, 0x00, 0xb2, 0x03, 0x2f, 0x09, 0x2e, 0x18, 0x00, 0x00, 0x91, 0x0c, 0x2f, 0x43,
0x7f, 0x98, 0x2e, 0x97, 0xb7, 0x1f, 0x50, 0x02, 0x8a, 0x02, 0x32, 0x04, 0x30, 0x25, 0x2e, 0x64, 0xf5, 0x15, 0x52,
0x50, 0x6f, 0x43, 0x6f, 0x44, 0x43, 0x25, 0x2e, 0x60, 0xf5, 0xd9, 0x08, 0xc0, 0xb2, 0x36, 0x2f, 0x98, 0x2e, 0x3e,
0xb7, 0x00, 0xb2, 0x06, 0x2f, 0x01, 0x2e, 0x19, 0x00, 0x00, 0xb2, 0x02, 0x2f, 0x50, 0x6f, 0x00, 0x90, 0x0a, 0x2f,
0x01, 0x2e, 0x79, 0x00, 0x00, 0x90, 0x19, 0x2f, 0x10, 0x30, 0x21, 0x2e, 0x79, 0x00, 0x00, 0x30, 0x98, 0x2e, 0xdc,
0x03, 0x13, 0x2d, 0x01, 0x2e, 0xc3, 0xf5, 0x0c, 0xbc, 0x0f, 0xb8, 0x12, 0x30, 0x10, 0x04, 0x03, 0xb0, 0x26, 0x25,
0x21, 0x50, 0x03, 0x52, 0x98, 0x2e, 0x4d, 0xb7, 0x10, 0x30, 0x21, 0x2e, 0xee, 0x00, 0x02, 0x30, 0x60, 0x7f, 0x25,
0x2e, 0x79, 0x00, 0x60, 0x6f, 0x00, 0x90, 0x05, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0xea, 0x00, 0x15, 0x50, 0x21, 0x2e,
0x64, 0xf5, 0x15, 0x52, 0x23, 0x2e, 0x60, 0xf5, 0x02, 0x32, 0x50, 0x6f, 0x00, 0x90, 0x02, 0x2f, 0x03, 0x30, 0x27,
0x2e, 0x78, 0x00, 0x07, 0x2e, 0x60, 0xf5, 0x1a, 0x09, 0x00, 0x91, 0xa3, 0x2f, 0x19, 0x09, 0x00, 0x91, 0xa0, 0x2f,
0x90, 0x6f, 0xa2, 0x6f, 0xb1, 0x6f, 0xc3, 0x6f, 0xd4, 0x6f, 0xe5, 0x6f, 0x7b, 0x6f, 0xf6, 0x6f, 0x87, 0x6f, 0x40,
0x5f, 0xc8, 0x2e, 0xc0, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x26, 0x30, 0x0f, 0x2e, 0x61, 0xf5, 0x2f, 0x2e, 0x7c, 0x00,
0x0f, 0x2e, 0x7c, 0x00, 0xbe, 0x09, 0xa2, 0x7f, 0x80, 0x7f, 0x80, 0xb3, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0x91,
0x7f, 0x7b, 0x7f, 0x0b, 0x2f, 0x23, 0x50, 0x1a, 0x25, 0x12, 0x40, 0x42, 0x7f, 0x74, 0x82, 0x12, 0x40, 0x52, 0x7f,
0x00, 0x2e, 0x00, 0x40, 0x60, 0x7f, 0x98, 0x2e, 0x6a, 0xd6, 0x81, 0x30, 0x01, 0x2e, 0x7c, 0x00, 0x01, 0x08, 0x00,
0xb2, 0x42, 0x2f, 0x03, 0x2e, 0x89, 0x00, 0x01, 0x2e, 0x89, 0x00, 0x97, 0xbc, 0x06, 0xbc, 0x9f, 0xb8, 0x0f, 0xb8,
0x00, 0x90, 0x23, 0x2e, 0xd8, 0x00, 0x10, 0x30, 0x01, 0x30, 0x2a, 0x2f, 0x03, 0x2e, 0xd4, 0x00, 0x44, 0xb2, 0x05,
0x2f, 0x47, 0xb2, 0x00, 0x30, 0x2d, 0x2f, 0x21, 0x2e, 0x7c, 0x00, 0x2b, 0x2d, 0x03, 0x2e, 0xfd, 0xf5, 0x9e, 0xbc,
0x9f, 0xb8, 0x40, 0x90, 0x14, 0x2f, 0x03, 0x2e, 0xfc, 0xf5, 0x99, 0xbc, 0x9f, 0xb8, 0x40, 0x90, 0x0e, 0x2f, 0x03,
0x2e, 0x49, 0xf1, 0x25, 0x54, 0x4a, 0x08, 0x40, 0x90, 0x08, 0x2f, 0x98, 0x2e, 0x35, 0xb7, 0x00, 0xb2, 0x10, 0x30,
0x03, 0x2f, 0x50, 0x30, 0x21, 0x2e, 0xd4, 0x00, 0x10, 0x2d, 0x98, 0x2e, 0xaf, 0xb7, 0x00, 0x30, 0x21, 0x2e, 0x7c,
0x00, 0x0a, 0x2d, 0x05, 0x2e, 0x69, 0xf7, 0x2d, 0xbd, 0x2f, 0xb9, 0x80, 0xb2, 0x01, 0x2f, 0x21, 0x2e, 0x7d, 0x00,
0x23, 0x2e, 0x7c, 0x00, 0xe0, 0x31, 0x21, 0x2e, 0x61, 0xf5, 0xf6, 0x6f, 0xe7, 0x6f, 0x80, 0x6f, 0xa2, 0x6f, 0xb3,
0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0x7b, 0x6f, 0x91, 0x6f, 0x40, 0x5f, 0xc8, 0x2e, 0x60, 0x51, 0x0a, 0x25, 0x36, 0x88,
0xf4, 0x7f, 0xeb, 0x7f, 0x00, 0x32, 0x31, 0x52, 0x32, 0x30, 0x13, 0x30, 0x98, 0x2e, 0x15, 0xcb, 0x0a, 0x25, 0x33,
0x84, 0xd2, 0x7f, 0x43, 0x30, 0x05, 0x50, 0x2d, 0x52, 0x98, 0x2e, 0x95, 0xc1, 0xd2, 0x6f, 0x27, 0x52, 0x98, 0x2e,
0xd7, 0xc7, 0x2a, 0x25, 0xb0, 0x86, 0xc0, 0x7f, 0xd3, 0x7f, 0xaf, 0x84, 0x29, 0x50, 0xf1, 0x6f, 0x98, 0x2e, 0x4d,
0xc8, 0x2a, 0x25, 0xae, 0x8a, 0xaa, 0x88, 0xf2, 0x6e, 0x2b, 0x50, 0xc1, 0x6f, 0xd3, 0x6f, 0xf4, 0x7f, 0x98, 0x2e,
0xb6, 0xc8, 0xe0, 0x6e, 0x00, 0xb2, 0x32, 0x2f, 0x33, 0x54, 0x83, 0x86, 0xf1, 0x6f, 0xc3, 0x7f, 0x04, 0x30, 0x30,
0x30, 0xf4, 0x7f, 0xd0, 0x7f, 0xb2, 0x7f, 0xe3, 0x30, 0xc5, 0x6f, 0x56, 0x40, 0x45, 0x41, 0x28, 0x08, 0x03, 0x14,
0x0e, 0xb4, 0x08, 0xbc, 0x82, 0x40, 0x10, 0x0a, 0x2f, 0x54, 0x26, 0x05, 0x91, 0x7f, 0x44, 0x28, 0xa3, 0x7f, 0x98,
0x2e, 0xd9, 0xc0, 0x08, 0xb9, 0x33, 0x30, 0x53, 0x09, 0xc1, 0x6f, 0xd3, 0x6f, 0xf4, 0x6f, 0x83, 0x17, 0x47, 0x40,
0x6c, 0x15, 0xb2, 0x6f, 0xbe, 0x09, 0x75, 0x0b, 0x90, 0x42, 0x45, 0x42, 0x51, 0x0e, 0x32, 0xbc, 0x02, 0x89, 0xa1,
0x6f, 0x7e, 0x86, 0xf4, 0x7f, 0xd0, 0x7f, 0xb2, 0x7f, 0x04, 0x30, 0x91, 0x6f, 0xd6, 0x2f, 0xeb, 0x6f, 0xa0, 0x5e,
0xb8, 0x2e, 0x03, 0x2e, 0x97, 0x00, 0x1b, 0xbc, 0x60, 0x50, 0x9f, 0xbc, 0x0c, 0xb8, 0xf0, 0x7f, 0x40, 0xb2, 0xeb,
0x7f, 0x2b, 0x2f, 0x03, 0x2e, 0x7f, 0x00, 0x41, 0x40, 0x01, 0x2e, 0xc8, 0x00, 0x01, 0x1a, 0x11, 0x2f, 0x37, 0x58,
0x23, 0x2e, 0xc8, 0x00, 0x10, 0x41, 0xa0, 0x7f, 0x38, 0x81, 0x01, 0x41, 0xd0, 0x7f, 0xb1, 0x7f, 0x98, 0x2e, 0x64,
0xcf, 0xd0, 0x6f, 0x07, 0x80, 0xa1, 0x6f, 0x11, 0x42, 0x00, 0x2e, 0xb1, 0x6f, 0x01, 0x42, 0x11, 0x30, 0x01, 0x2e,
0xfc, 0x00, 0x00, 0xa8, 0x03, 0x30, 0xcb, 0x22, 0x4a, 0x25, 0x01, 0x2e, 0x7f, 0x00, 0x3c, 0x89, 0x35, 0x52, 0x05,
0x54, 0x98, 0x2e, 0xc4, 0xce, 0xc1, 0x6f, 0xf0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0x04, 0x2d, 0x01, 0x30, 0xf0, 0x6f,
0x98, 0x2e, 0x95, 0xcf, 0xeb, 0x6f, 0xa0, 0x5f, 0xb8, 0x2e, 0x03, 0x2e, 0xb3, 0x00, 0x02, 0x32, 0xf0, 0x30, 0x03,
0x31, 0x30, 0x50, 0x8a, 0x08, 0x08, 0x08, 0xcb, 0x08, 0xe0, 0x7f, 0x80, 0xb2, 0xf3, 0x7f, 0xdb, 0x7f, 0x25, 0x2f,
0x03, 0x2e, 0xca, 0x00, 0x41, 0x90, 0x04, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0xca, 0x00, 0x98, 0x2e, 0x3f, 0x03, 0xc0,
0xb2, 0x05, 0x2f, 0x03, 0x2e, 0xda, 0x00, 0x00, 0x30, 0x41, 0x04, 0x23, 0x2e, 0xda, 0x00, 0x98, 0x2e, 0x92, 0xb2,
0x10, 0x25, 0xf0, 0x6f, 0x00, 0xb2, 0x05, 0x2f, 0x01, 0x2e, 0xda, 0x00, 0x02, 0x30, 0x10, 0x04, 0x21, 0x2e, 0xda,
0x00, 0x40, 0xb2, 0x01, 0x2f, 0x23, 0x2e, 0xc8, 0x01, 0xdb, 0x6f, 0xe0, 0x6f, 0xd0, 0x5f, 0x80, 0x2e, 0x95, 0xcf,
0x01, 0x30, 0xe0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0x11, 0x30, 0x23, 0x2e, 0xca, 0x00, 0xdb, 0x6f, 0xd0, 0x5f, 0xb8,
0x2e, 0xd0, 0x50, 0x0a, 0x25, 0x33, 0x84, 0x55, 0x50, 0xd2, 0x7f, 0xe2, 0x7f, 0x03, 0x8c, 0xc0, 0x7f, 0xbb, 0x7f,
0x00, 0x30, 0x05, 0x5a, 0x39, 0x54, 0x51, 0x41, 0xa5, 0x7f, 0x96, 0x7f, 0x80, 0x7f, 0x98, 0x2e, 0xd9, 0xc0, 0x05,
0x30, 0xf5, 0x7f, 0x20, 0x25, 0x91, 0x6f, 0x3b, 0x58, 0x3d, 0x5c, 0x3b, 0x56, 0x98, 0x2e, 0x67, 0xcc, 0xc1, 0x6f,
0xd5, 0x6f, 0x52, 0x40, 0x50, 0x43, 0xc1, 0x7f, 0xd5, 0x7f, 0x10, 0x25, 0x98, 0x2e, 0xfe, 0xc9, 0x10, 0x25, 0x98,
0x2e, 0x74, 0xc0, 0x86, 0x6f, 0x30, 0x28, 0x92, 0x6f, 0x82, 0x8c, 0xa5, 0x6f, 0x6f, 0x52, 0x69, 0x0e, 0x39, 0x54,
0xdb, 0x2f, 0x19, 0xa0, 0x15, 0x30, 0x03, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x81, 0x01, 0x0a, 0x2d, 0x01, 0x2e, 0x81,
0x01, 0x05, 0x28, 0x42, 0x36, 0x21, 0x2e, 0x81, 0x01, 0x02, 0x0e, 0x01, 0x2f, 0x98, 0x2e, 0xf3, 0x03, 0x57, 0x50,
0x12, 0x30, 0x01, 0x40, 0x98, 0x2e, 0xfe, 0xc9, 0x51, 0x6f, 0x0b, 0x5c, 0x8e, 0x0e, 0x3b, 0x6f, 0x57, 0x58, 0x02,
0x30, 0x21, 0x2e, 0x95, 0x01, 0x45, 0x6f, 0x2a, 0x8d, 0xd2, 0x7f, 0xcb, 0x7f, 0x13, 0x2f, 0x02, 0x30, 0x3f, 0x50,
0xd2, 0x7f, 0xa8, 0x0e, 0x0e, 0x2f, 0xc0, 0x6f, 0x53, 0x54, 0x02, 0x00, 0x51, 0x54, 0x42, 0x0e, 0x10, 0x30, 0x59,
0x52, 0x02, 0x30, 0x01, 0x2f, 0x00, 0x2e, 0x03, 0x2d, 0x50, 0x42, 0x42, 0x42, 0x12, 0x30, 0xd2, 0x7f, 0x80, 0xb2,
0x03, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x80, 0x01, 0x12, 0x2d, 0x01, 0x2e, 0xc9, 0x00, 0x02, 0x80, 0x05, 0x2e, 0x80,
0x01, 0x11, 0x30, 0x91, 0x28, 0x00, 0x40, 0x25, 0x2e, 0x80, 0x01, 0x10, 0x0e, 0x05, 0x2f, 0x01, 0x2e, 0x7f, 0x01,
0x01, 0x90, 0x01, 0x2f, 0x98, 0x2e, 0xf3, 0x03, 0x00, 0x2e, 0xa0, 0x41, 0x01, 0x90, 0xa6, 0x7f, 0x90, 0x2e, 0xe3,
0xb4, 0x01, 0x2e, 0x95, 0x01, 0x00, 0xa8, 0x90, 0x2e, 0xe3, 0xb4, 0x5b, 0x54, 0x95, 0x80, 0x82, 0x40, 0x80, 0xb2,
0x02, 0x40, 0x2d, 0x8c, 0x3f, 0x52, 0x96, 0x7f, 0x90, 0x2e, 0xc2, 0xb3, 0x29, 0x0e, 0x76, 0x2f, 0x01, 0x2e, 0xc9,
0x00, 0x00, 0x40, 0x81, 0x28, 0x45, 0x52, 0xb3, 0x30, 0x98, 0x2e, 0x0f, 0xca, 0x5d, 0x54, 0x80, 0x7f, 0x00, 0x2e,
0xa1, 0x40, 0x72, 0x7f, 0x82, 0x80, 0x82, 0x40, 0x60, 0x7f, 0x98, 0x2e, 0xfe, 0xc9, 0x10, 0x25, 0x98, 0x2e, 0x74,
0xc0, 0x62, 0x6f, 0x05, 0x30, 0x87, 0x40, 0xc0, 0x91, 0x04, 0x30, 0x05, 0x2f, 0x05, 0x2e, 0x83, 0x01, 0x80, 0xb2,
0x14, 0x30, 0x00, 0x2f, 0x04, 0x30, 0x05, 0x2e, 0xc9, 0x00, 0x73, 0x6f, 0x81, 0x40, 0xe2, 0x40, 0x69, 0x04, 0x11,
0x0f, 0xe1, 0x40, 0x16, 0x30, 0xfe, 0x29, 0xcb, 0x40, 0x02, 0x2f, 0x83, 0x6f, 0x83, 0x0f, 0x22, 0x2f, 0x47, 0x56,
0x13, 0x0f, 0x12, 0x30, 0x77, 0x2f, 0x49, 0x54, 0x42, 0x0e, 0x12, 0x30, 0x73, 0x2f, 0x00, 0x91, 0x0a, 0x2f, 0x01,
0x2e, 0x8b, 0x01, 0x19, 0xa8, 0x02, 0x30, 0x6c, 0x2f, 0x63, 0x50, 0x00, 0x2e, 0x17, 0x42, 0x05, 0x42, 0x68, 0x2c,
0x12, 0x30, 0x0b, 0x25, 0x08, 0x0f, 0x50, 0x30, 0x02, 0x2f, 0x21, 0x2e, 0x83, 0x01, 0x03, 0x2d, 0x40, 0x30, 0x21,
0x2e, 0x83, 0x01, 0x2b, 0x2e, 0x85, 0x01, 0x5a, 0x2c, 0x12, 0x30, 0x00, 0x91, 0x2b, 0x25, 0x04, 0x2f, 0x63, 0x50,
0x02, 0x30, 0x17, 0x42, 0x17, 0x2c, 0x02, 0x42, 0x98, 0x2e, 0xfe, 0xc9, 0x10, 0x25, 0x98, 0x2e, 0x74, 0xc0, 0x05,
0x2e, 0xc9, 0x00, 0x81, 0x84, 0x5b, 0x30, 0x82, 0x40, 0x37, 0x2e, 0x83, 0x01, 0x02, 0x0e, 0x07, 0x2f, 0x5f, 0x52,
0x40, 0x30, 0x62, 0x40, 0x41, 0x40, 0x91, 0x0e, 0x01, 0x2f, 0x21, 0x2e, 0x83, 0x01, 0x05, 0x30, 0x2b, 0x2e, 0x85,
0x01, 0x12, 0x30, 0x36, 0x2c, 0x16, 0x30, 0x15, 0x25, 0x81, 0x7f, 0x98, 0x2e, 0xfe, 0xc9, 0x10, 0x25, 0x98, 0x2e,
0x74, 0xc0, 0x19, 0xa2, 0x16, 0x30, 0x15, 0x2f, 0x05, 0x2e, 0x97, 0x01, 0x80, 0x6f, 0x82, 0x0e, 0x05, 0x2f, 0x01,
0x2e, 0x86, 0x01, 0x06, 0x28, 0x21, 0x2e, 0x86, 0x01, 0x0b, 0x2d, 0x03, 0x2e, 0x87, 0x01, 0x5f, 0x54, 0x4e, 0x28,
0x91, 0x42, 0x00, 0x2e, 0x82, 0x40, 0x90, 0x0e, 0x01, 0x2f, 0x21, 0x2e, 0x88, 0x01, 0x02, 0x30, 0x13, 0x2c, 0x05,
0x30, 0xc0, 0x6f, 0x08, 0x1c, 0xa8, 0x0f, 0x16, 0x30, 0x05, 0x30, 0x5b, 0x50, 0x09, 0x2f, 0x02, 0x80, 0x2d, 0x2e,
0x82, 0x01, 0x05, 0x42, 0x05, 0x80, 0x00, 0x2e, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x06, 0x42, 0x02, 0x30, 0x90,
0x6f, 0x3e, 0x88, 0x01, 0x40, 0x04, 0x41, 0x4c, 0x28, 0x01, 0x42, 0x07, 0x80, 0x10, 0x25, 0x24, 0x40, 0x00, 0x40,
0x00, 0xa8, 0xf5, 0x22, 0x23, 0x29, 0x44, 0x42, 0x7a, 0x82, 0x7e, 0x88, 0x43, 0x40, 0x04, 0x41, 0x00, 0xab, 0xf5,
0x23, 0xdf, 0x28, 0x43, 0x42, 0xd9, 0xa0, 0x14, 0x2f, 0x00, 0x90, 0x02, 0x2f, 0xd2, 0x6f, 0x81, 0xb2, 0x05, 0x2f,
0x63, 0x54, 0x06, 0x28, 0x90, 0x42, 0x85, 0x42, 0x09, 0x2c, 0x02, 0x30, 0x5b, 0x50, 0x03, 0x80, 0x29, 0x2e, 0x7e,
0x01, 0x2b, 0x2e, 0x82, 0x01, 0x05, 0x42, 0x12, 0x30, 0x2b, 0x2e, 0x83, 0x01, 0x45, 0x82, 0x00, 0x2e, 0x40, 0x40,
0x7a, 0x82, 0x02, 0xa0, 0x08, 0x2f, 0x63, 0x50, 0x3b, 0x30, 0x15, 0x42, 0x05, 0x42, 0x37, 0x80, 0x37, 0x2e, 0x7e,
0x01, 0x05, 0x42, 0x12, 0x30, 0x01, 0x2e, 0xc9, 0x00, 0x02, 0x8c, 0x40, 0x40, 0x84, 0x41, 0x7a, 0x8c, 0x04, 0x0f,
0x03, 0x2f, 0x01, 0x2e, 0x8b, 0x01, 0x19, 0xa4, 0x04, 0x2f, 0x2b, 0x2e, 0x82, 0x01, 0x98, 0x2e, 0xf3, 0x03, 0x12,
0x30, 0x81, 0x90, 0x61, 0x52, 0x08, 0x2f, 0x65, 0x42, 0x65, 0x42, 0x43, 0x80, 0x39, 0x84, 0x82, 0x88, 0x05, 0x42,
0x45, 0x42, 0x85, 0x42, 0x05, 0x43, 0x00, 0x2e, 0x80, 0x41, 0x00, 0x90, 0x90, 0x2e, 0xe1, 0xb4, 0x65, 0x54, 0xc1,
0x6f, 0x80, 0x40, 0x00, 0xb2, 0x43, 0x58, 0x69, 0x50, 0x44, 0x2f, 0x55, 0x5c, 0xb7, 0x87, 0x8c, 0x0f, 0x0d, 0x2e,
0x96, 0x01, 0xc4, 0x40, 0x36, 0x2f, 0x41, 0x56, 0x8b, 0x0e, 0x2a, 0x2f, 0x0b, 0x52, 0xa1, 0x0e, 0x0a, 0x2f, 0x05,
0x2e, 0x8f, 0x01, 0x14, 0x25, 0x98, 0x2e, 0xfe, 0xc9, 0x4b, 0x54, 0x02, 0x0f, 0x69, 0x50, 0x05, 0x30, 0x65, 0x54,
0x15, 0x2f, 0x03, 0x2e, 0x8e, 0x01, 0x4d, 0x5c, 0x8e, 0x0f, 0x3a, 0x2f, 0x05, 0x2e, 0x8f, 0x01, 0x98, 0x2e, 0xfe,
0xc9, 0x4f, 0x54, 0x82, 0x0f, 0x05, 0x30, 0x69, 0x50, 0x65, 0x54, 0x30, 0x2f, 0x6d, 0x52, 0x15, 0x30, 0x42, 0x8c,
0x45, 0x42, 0x04, 0x30, 0x2b, 0x2c, 0x84, 0x43, 0x6b, 0x52, 0x42, 0x8c, 0x00, 0x2e, 0x85, 0x43, 0x15, 0x30, 0x24,
0x2c, 0x45, 0x42, 0x8e, 0x0f, 0x20, 0x2f, 0x0d, 0x2e, 0x8e, 0x01, 0xb1, 0x0e, 0x1c, 0x2f, 0x23, 0x2e, 0x8e, 0x01,
0x1a, 0x2d, 0x0e, 0x0e, 0x17, 0x2f, 0xa1, 0x0f, 0x15, 0x2f, 0x23, 0x2e, 0x8d, 0x01, 0x13, 0x2d, 0x98, 0x2e, 0x74,
0xc0, 0x43, 0x54, 0xc2, 0x0e, 0x0a, 0x2f, 0x65, 0x50, 0x04, 0x80, 0x0b, 0x30, 0x06, 0x82, 0x0b, 0x42, 0x79, 0x80,
0x41, 0x40, 0x12, 0x30, 0x25, 0x2e, 0x8c, 0x01, 0x01, 0x42, 0x05, 0x30, 0x69, 0x50, 0x65, 0x54, 0x84, 0x82, 0x43,
0x84, 0xbe, 0x8c, 0x84, 0x40, 0x86, 0x41, 0x26, 0x29, 0x94, 0x42, 0xbe, 0x8e, 0xd5, 0x7f, 0x19, 0xa1, 0x43, 0x40,
0x0b, 0x2e, 0x8c, 0x01, 0x84, 0x40, 0xc7, 0x41, 0x5d, 0x29, 0x27, 0x29, 0x45, 0x42, 0x84, 0x42, 0xc2, 0x7f, 0x01,
0x2f, 0xc0, 0xb3, 0x1d, 0x2f, 0x05, 0x2e, 0x94, 0x01, 0x99, 0xa0, 0x01, 0x2f, 0x80, 0xb3, 0x13, 0x2f, 0x80, 0xb3,
0x18, 0x2f, 0xc0, 0xb3, 0x16, 0x2f, 0x12, 0x40, 0x01, 0x40, 0x92, 0x7f, 0x98, 0x2e, 0x74, 0xc0, 0x92, 0x6f, 0x10,
0x0f, 0x20, 0x30, 0x03, 0x2f, 0x10, 0x30, 0x21, 0x2e, 0x7e, 0x01, 0x0a, 0x2d, 0x21, 0x2e, 0x7e, 0x01, 0x07, 0x2d,
0x20, 0x30, 0x21, 0x2e, 0x7e, 0x01, 0x03, 0x2d, 0x10, 0x30, 0x21, 0x2e, 0x7e, 0x01, 0xc2, 0x6f, 0x01, 0x2e, 0xc9,
0x00, 0xbc, 0x84, 0x02, 0x80, 0x82, 0x40, 0x00, 0x40, 0x90, 0x0e, 0xd5, 0x6f, 0x02, 0x2f, 0x15, 0x30, 0x98, 0x2e,
0xf3, 0x03, 0x41, 0x91, 0x05, 0x30, 0x07, 0x2f, 0x67, 0x50, 0x3d, 0x80, 0x2b, 0x2e, 0x8f, 0x01, 0x05, 0x42, 0x04,
0x80, 0x00, 0x2e, 0x05, 0x42, 0x02, 0x2c, 0x00, 0x30, 0x00, 0x30, 0xa2, 0x6f, 0x98, 0x8a, 0x86, 0x40, 0x80, 0xa7,
0x05, 0x2f, 0x98, 0x2e, 0xf3, 0x03, 0xc0, 0x30, 0x21, 0x2e, 0x95, 0x01, 0x06, 0x25, 0x1a, 0x25, 0xe2, 0x6f, 0x76,
0x82, 0x96, 0x40, 0x56, 0x43, 0x51, 0x0e, 0xfb, 0x2f, 0xbb, 0x6f, 0x30, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0xb8, 0x00,
0x01, 0x31, 0x41, 0x08, 0x40, 0xb2, 0x20, 0x50, 0xf2, 0x30, 0x02, 0x08, 0xfb, 0x7f, 0x01, 0x30, 0x10, 0x2f, 0x05,
0x2e, 0xcc, 0x00, 0x81, 0x90, 0xe0, 0x7f, 0x03, 0x2f, 0x23, 0x2e, 0xcc, 0x00, 0x98, 0x2e, 0x55, 0xb6, 0x98, 0x2e,
0x1d, 0xb5, 0x10, 0x25, 0xfb, 0x6f, 0xe0, 0x6f, 0xe0, 0x5f, 0x80, 0x2e, 0x95, 0xcf, 0x98, 0x2e, 0x95, 0xcf, 0x10,
0x30, 0x21, 0x2e, 0xcc, 0x00, 0xfb, 0x6f, 0xe0, 0x5f, 0xb8, 0x2e, 0x00, 0x51, 0x05, 0x58, 0xeb, 0x7f, 0x2a, 0x25,
0x89, 0x52, 0x6f, 0x5a, 0x89, 0x50, 0x13, 0x41, 0x06, 0x40, 0xb3, 0x01, 0x16, 0x42, 0xcb, 0x16, 0x06, 0x40, 0xf3,
0x02, 0x13, 0x42, 0x65, 0x0e, 0xf5, 0x2f, 0x05, 0x40, 0x14, 0x30, 0x2c, 0x29, 0x04, 0x42, 0x08, 0xa1, 0x00, 0x30,
0x90, 0x2e, 0x52, 0xb6, 0xb3, 0x88, 0xb0, 0x8a, 0xb6, 0x84, 0xa4, 0x7f, 0xc4, 0x7f, 0xb5, 0x7f, 0xd5, 0x7f, 0x92,
0x7f, 0x73, 0x30, 0x04, 0x30, 0x55, 0x40, 0x42, 0x40, 0x8a, 0x17, 0xf3, 0x08, 0x6b, 0x01, 0x90, 0x02, 0x53, 0xb8,
0x4b, 0x82, 0xad, 0xbe, 0x71, 0x7f, 0x45, 0x0a, 0x09, 0x54, 0x84, 0x7f, 0x98, 0x2e, 0xd9, 0xc0, 0xa3, 0x6f, 0x7b,
0x54, 0xd0, 0x42, 0xa3, 0x7f, 0xf2, 0x7f, 0x60, 0x7f, 0x20, 0x25, 0x71, 0x6f, 0x75, 0x5a, 0x77, 0x58, 0x79, 0x5c,
0x75, 0x56, 0x98, 0x2e, 0x67, 0xcc, 0xb1, 0x6f, 0x62, 0x6f, 0x50, 0x42, 0xb1, 0x7f, 0xb3, 0x30, 0x10, 0x25, 0x98,
0x2e, 0x0f, 0xca, 0x84, 0x6f, 0x20, 0x29, 0x71, 0x6f, 0x92, 0x6f, 0xa5, 0x6f, 0x76, 0x82, 0x6a, 0x0e, 0x73, 0x30,
0x00, 0x30, 0xd0, 0x2f, 0xd2, 0x6f, 0xd1, 0x7f, 0xb4, 0x7f, 0x98, 0x2e, 0x2b, 0xb7, 0x15, 0xbd, 0x0b, 0xb8, 0x02,
0x0a, 0xc2, 0x6f, 0xc0, 0x7f, 0x98, 0x2e, 0x2b, 0xb7, 0x15, 0xbd, 0x0b, 0xb8, 0x42, 0x0a, 0xc0, 0x6f, 0x08, 0x17,
0x41, 0x18, 0x89, 0x16, 0xe1, 0x18, 0xd0, 0x18, 0xa1, 0x7f, 0x27, 0x25, 0x16, 0x25, 0x98, 0x2e, 0x79, 0xc0, 0x8b,
0x54, 0x90, 0x7f, 0xb3, 0x30, 0x82, 0x40, 0x80, 0x90, 0x0d, 0x2f, 0x7d, 0x52, 0x92, 0x6f, 0x98, 0x2e, 0x0f, 0xca,
0xb2, 0x6f, 0x90, 0x0e, 0x06, 0x2f, 0x8b, 0x50, 0x14, 0x30, 0x42, 0x6f, 0x51, 0x6f, 0x14, 0x42, 0x12, 0x42, 0x01,
0x42, 0x00, 0x2e, 0x31, 0x6f, 0x98, 0x2e, 0x74, 0xc0, 0x41, 0x6f, 0x80, 0x7f, 0x98, 0x2e, 0x74, 0xc0, 0x82, 0x6f,
0x10, 0x04, 0x43, 0x52, 0x01, 0x0f, 0x05, 0x2e, 0xcb, 0x00, 0x00, 0x30, 0x04, 0x30, 0x21, 0x2f, 0x51, 0x6f, 0x43,
0x58, 0x8c, 0x0e, 0x04, 0x30, 0x1c, 0x2f, 0x85, 0x88, 0x41, 0x6f, 0x04, 0x41, 0x8c, 0x0f, 0x04, 0x30, 0x16, 0x2f,
0x84, 0x88, 0x00, 0x2e, 0x04, 0x41, 0x04, 0x05, 0x8c, 0x0e, 0x04, 0x30, 0x0f, 0x2f, 0x82, 0x88, 0x31, 0x6f, 0x04,
0x41, 0x04, 0x05, 0x8c, 0x0e, 0x04, 0x30, 0x08, 0x2f, 0x83, 0x88, 0x00, 0x2e, 0x04, 0x41, 0x8c, 0x0f, 0x04, 0x30,
0x02, 0x2f, 0x21, 0x2e, 0xad, 0x01, 0x14, 0x30, 0x00, 0x91, 0x14, 0x2f, 0x03, 0x2e, 0xa1, 0x01, 0x41, 0x90, 0x0e,
0x2f, 0x03, 0x2e, 0xad, 0x01, 0x14, 0x30, 0x4c, 0x28, 0x23, 0x2e, 0xad, 0x01, 0x46, 0xa0, 0x06, 0x2f, 0x81, 0x84,
0x8d, 0x52, 0x48, 0x82, 0x82, 0x40, 0x21, 0x2e, 0xa1, 0x01, 0x42, 0x42, 0x5c, 0x2c, 0x02, 0x30, 0x05, 0x2e, 0xaa,
0x01, 0x80, 0xb2, 0x02, 0x30, 0x55, 0x2f, 0x03, 0x2e, 0xa9, 0x01, 0x92, 0x6f, 0xb3, 0x30, 0x98, 0x2e, 0x0f, 0xca,
0xb2, 0x6f, 0x90, 0x0f, 0x00, 0x30, 0x02, 0x30, 0x4a, 0x2f, 0xa2, 0x6f, 0x87, 0x52, 0x91, 0x00, 0x85, 0x52, 0x51,
0x0e, 0x02, 0x2f, 0x00, 0x2e, 0x43, 0x2c, 0x02, 0x30, 0xc2, 0x6f, 0x7f, 0x52, 0x91, 0x0e, 0x02, 0x30, 0x3c, 0x2f,
0x51, 0x6f, 0x81, 0x54, 0x98, 0x2e, 0xfe, 0xc9, 0x10, 0x25, 0xb3, 0x30, 0x21, 0x25, 0x98, 0x2e, 0x0f, 0xca, 0x32,
0x6f, 0xc0, 0x7f, 0xb3, 0x30, 0x12, 0x25, 0x98, 0x2e, 0x0f, 0xca, 0x42, 0x6f, 0xb0, 0x7f, 0xb3, 0x30, 0x12, 0x25,
0x98, 0x2e, 0x0f, 0xca, 0xb2, 0x6f, 0x90, 0x28, 0x83, 0x52, 0x98, 0x2e, 0xfe, 0xc9, 0xc2, 0x6f, 0x90, 0x0f, 0x00,
0x30, 0x02, 0x30, 0x1d, 0x2f, 0x05, 0x2e, 0xa1, 0x01, 0x80, 0xb2, 0x12, 0x30, 0x0f, 0x2f, 0x42, 0x6f, 0x03, 0x2e,
0xab, 0x01, 0x91, 0x0e, 0x02, 0x30, 0x12, 0x2f, 0x52, 0x6f, 0x03, 0x2e, 0xac, 0x01, 0x91, 0x0f, 0x02, 0x30, 0x0c,
0x2f, 0x21, 0x2e, 0xaa, 0x01, 0x0a, 0x2c, 0x12, 0x30, 0x03, 0x2e, 0xcb, 0x00, 0x8d, 0x58, 0x08, 0x89, 0x41, 0x40,
0x11, 0x43, 0x00, 0x43, 0x25, 0x2e, 0xa1, 0x01, 0xd4, 0x6f, 0x8f, 0x52, 0x00, 0x43, 0x3a, 0x89, 0x00, 0x2e, 0x10,
0x43, 0x10, 0x43, 0x61, 0x0e, 0xfb, 0x2f, 0x03, 0x2e, 0xa0, 0x01, 0x11, 0x1a, 0x02, 0x2f, 0x02, 0x25, 0x21, 0x2e,
0xa0, 0x01, 0xeb, 0x6f, 0x00, 0x5f, 0xb8, 0x2e, 0x91, 0x52, 0x10, 0x30, 0x02, 0x30, 0x95, 0x56, 0x52, 0x42, 0x4b,
0x0e, 0xfc, 0x2f, 0x8d, 0x54, 0x88, 0x82, 0x93, 0x56, 0x80, 0x42, 0x53, 0x42, 0x40, 0x42, 0x42, 0x86, 0x83, 0x54,
0xc0, 0x2e, 0xc2, 0x42, 0x00, 0x2e, 0xa3, 0x52, 0x00, 0x51, 0x52, 0x40, 0x47, 0x40, 0x1a, 0x25, 0x01, 0x2e, 0x97,
0x00, 0x8f, 0xbe, 0x72, 0x86, 0xfb, 0x7f, 0x0b, 0x30, 0x7c, 0xbf, 0xa5, 0x50, 0x10, 0x08, 0xdf, 0xba, 0x70, 0x88,
0xf8, 0xbf, 0xcb, 0x42, 0xd3, 0x7f, 0x6c, 0xbb, 0xfc, 0xbb, 0xc5, 0x0a, 0x90, 0x7f, 0x1b, 0x7f, 0x0b, 0x43, 0xc0,
0xb2, 0xe5, 0x7f, 0xb7, 0x7f, 0xa6, 0x7f, 0xc4, 0x7f, 0x90, 0x2e, 0x1c, 0xb7, 0x07, 0x2e, 0xd2, 0x00, 0xc0, 0xb2,
0x0b, 0x2f, 0x97, 0x52, 0x01, 0x2e, 0xcd, 0x00, 0x82, 0x7f, 0x98, 0x2e, 0xbb, 0xcc, 0x0b, 0x30, 0x37, 0x2e, 0xd2,
0x00, 0x82, 0x6f, 0x90, 0x6f, 0x1a, 0x25, 0x00, 0xb2, 0x8b, 0x7f, 0x14, 0x2f, 0xa6, 0xbd, 0x25, 0xbd, 0xb6, 0xb9,
0x2f, 0xb9, 0x80, 0xb2, 0xd4, 0xb0, 0x0c, 0x2f, 0x99, 0x54, 0x9b, 0x56, 0x0b, 0x30, 0x0b, 0x2e, 0xb1, 0x00, 0xa1,
0x58, 0x9b, 0x42, 0xdb, 0x42, 0x6c, 0x09, 0x2b, 0x2e, 0xb1, 0x00, 0x8b, 0x42, 0xcb, 0x42, 0x86, 0x7f, 0x73, 0x84,
0xa7, 0x56, 0xc3, 0x08, 0x39, 0x52, 0x05, 0x50, 0x72, 0x7f, 0x63, 0x7f, 0x98, 0x2e, 0xc2, 0xc0, 0xe1, 0x6f, 0x62,
0x6f, 0xd1, 0x0a, 0x01, 0x2e, 0xcd, 0x00, 0xd5, 0x6f, 0xc4, 0x6f, 0x72, 0x6f, 0x97, 0x52, 0x9d, 0x5c, 0x98, 0x2e,
0x06, 0xcd, 0x23, 0x6f, 0x90, 0x6f, 0x99, 0x52, 0xc0, 0xb2, 0x04, 0xbd, 0x54, 0x40, 0xaf, 0xb9, 0x45, 0x40, 0xe1,
0x7f, 0x02, 0x30, 0x06, 0x2f, 0xc0, 0xb2, 0x02, 0x30, 0x03, 0x2f, 0x9b, 0x5c, 0x12, 0x30, 0x94, 0x43, 0x85, 0x43,
0x03, 0xbf, 0x6f, 0xbb, 0x80, 0xb3, 0x20, 0x2f, 0x06, 0x6f, 0x26, 0x01, 0x16, 0x6f, 0x6e, 0x03, 0x45, 0x42, 0xc0,
0x90, 0x29, 0x2e, 0xce, 0x00, 0x9b, 0x52, 0x14, 0x2f, 0x9b, 0x5c, 0x00, 0x2e, 0x93, 0x41, 0x86, 0x41, 0xe3, 0x04,
0xae, 0x07, 0x80, 0xab, 0x04, 0x2f, 0x80, 0x91, 0x0a, 0x2f, 0x86, 0x6f, 0x73, 0x0f, 0x07, 0x2f, 0x83, 0x6f, 0xc0,
0xb2, 0x04, 0x2f, 0x54, 0x42, 0x45, 0x42, 0x12, 0x30, 0x04, 0x2c, 0x11, 0x30, 0x02, 0x2c, 0x11, 0x30, 0x11, 0x30,
0x02, 0xbc, 0x0f, 0xb8, 0xd2, 0x7f, 0x00, 0xb2, 0x0a, 0x2f, 0x01, 0x2e, 0xfc, 0x00, 0x05, 0x2e, 0xc7, 0x01, 0x10,
0x1a, 0x02, 0x2f, 0x21, 0x2e, 0xc7, 0x01, 0x03, 0x2d, 0x02, 0x2c, 0x01, 0x30, 0x01, 0x30, 0xb0, 0x6f, 0x98, 0x2e,
0x95, 0xcf, 0xd1, 0x6f, 0xa0, 0x6f, 0x98, 0x2e, 0x95, 0xcf, 0xe2, 0x6f, 0x9f, 0x52, 0x01, 0x2e, 0xce, 0x00, 0x82,
0x40, 0x50, 0x42, 0x0c, 0x2c, 0x42, 0x42, 0x11, 0x30, 0x23, 0x2e, 0xd2, 0x00, 0x01, 0x30, 0xb0, 0x6f, 0x98, 0x2e,
0x95, 0xcf, 0xa0, 0x6f, 0x01, 0x30, 0x98, 0x2e, 0x95, 0xcf, 0x00, 0x2e, 0xfb, 0x6f, 0x00, 0x5f, 0xb8, 0x2e, 0x83,
0x86, 0x01, 0x30, 0x00, 0x30, 0x94, 0x40, 0x24, 0x18, 0x06, 0x00, 0x53, 0x0e, 0x4f, 0x02, 0xf9, 0x2f, 0xb8, 0x2e,
0xa9, 0x52, 0x00, 0x2e, 0x60, 0x40, 0x41, 0x40, 0x0d, 0xbc, 0x98, 0xbc, 0xc0, 0x2e, 0x01, 0x0a, 0x0f, 0xb8, 0xab,
0x52, 0x53, 0x3c, 0x52, 0x40, 0x40, 0x40, 0x4b, 0x00, 0x82, 0x16, 0x26, 0xb9, 0x01, 0xb8, 0x41, 0x40, 0x10, 0x08,
0x97, 0xb8, 0x01, 0x08, 0xc0, 0x2e, 0x11, 0x30, 0x01, 0x08, 0x43, 0x86, 0x25, 0x40, 0x04, 0x40, 0xd8, 0xbe, 0x2c,
0x0b, 0x22, 0x11, 0x54, 0x42, 0x03, 0x80, 0x4b, 0x0e, 0xf6, 0x2f, 0xb8, 0x2e, 0x9f, 0x50, 0x10, 0x50, 0xad, 0x52,
0x05, 0x2e, 0xd3, 0x00, 0xfb, 0x7f, 0x00, 0x2e, 0x13, 0x40, 0x93, 0x42, 0x41, 0x0e, 0xfb, 0x2f, 0x98, 0x2e, 0xa5,
0xb7, 0x98, 0x2e, 0x87, 0xcf, 0x01, 0x2e, 0xd9, 0x00, 0x00, 0xb2, 0xfb, 0x6f, 0x0b, 0x2f, 0x01, 0x2e, 0x69, 0xf7,
0xb1, 0x3f, 0x01, 0x08, 0x01, 0x30, 0xf0, 0x5f, 0x23, 0x2e, 0xd9, 0x00, 0x21, 0x2e, 0x69, 0xf7, 0x80, 0x2e, 0x7a,
0xb7, 0xf0, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0xc0, 0xf8, 0x03, 0x2e, 0xfc, 0xf5, 0x15, 0x54, 0xaf, 0x56, 0x82, 0x08,
0x0b, 0x2e, 0x69, 0xf7, 0xcb, 0x0a, 0xb1, 0x58, 0x80, 0x90, 0xdd, 0xbe, 0x4c, 0x08, 0x5f, 0xb9, 0x59, 0x22, 0x80,
0x90, 0x07, 0x2f, 0x03, 0x34, 0xc3, 0x08, 0xf2, 0x3a, 0x0a, 0x08, 0x02, 0x35, 0xc0, 0x90, 0x4a, 0x0a, 0x48, 0x22,
0xc0, 0x2e, 0x23, 0x2e, 0xfc, 0xf5, 0x10, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0x56, 0xc7, 0x98, 0x2e, 0x49, 0xc3, 0x10,
0x30, 0xfb, 0x6f, 0xf0, 0x5f, 0x21, 0x2e, 0xcc, 0x00, 0x21, 0x2e, 0xca, 0x00, 0xb8, 0x2e, 0x03, 0x2e, 0xd3, 0x00,
0x16, 0xb8, 0x02, 0x34, 0x4a, 0x0c, 0x21, 0x2e, 0x2d, 0xf5, 0xc0, 0x2e, 0x23, 0x2e, 0xd3, 0x00, 0x03, 0xbc, 0x21,
0x2e, 0xd5, 0x00, 0x03, 0x2e, 0xd5, 0x00, 0x40, 0xb2, 0x10, 0x30, 0x21, 0x2e, 0x77, 0x00, 0x01, 0x30, 0x05, 0x2f,
0x05, 0x2e, 0xd8, 0x00, 0x80, 0x90, 0x01, 0x2f, 0x23, 0x2e, 0x6f, 0xf5, 0xc0, 0x2e, 0x21, 0x2e, 0xd9, 0x00, 0x11,
0x30, 0x81, 0x08, 0x01, 0x2e, 0x6a, 0xf7, 0x71, 0x3f, 0x23, 0xbd, 0x01, 0x08, 0x02, 0x0a, 0xc0, 0x2e, 0x21, 0x2e,
0x6a, 0xf7, 0x30, 0x25, 0x00, 0x30, 0x21, 0x2e, 0x5a, 0xf5, 0x10, 0x50, 0x21, 0x2e, 0x7b, 0x00, 0x21, 0x2e, 0x7c,
0x00, 0xfb, 0x7f, 0x98, 0x2e, 0xc3, 0xb7, 0x40, 0x30, 0x21, 0x2e, 0xd4, 0x00, 0xfb, 0x6f, 0xf0, 0x5f, 0x03, 0x25,
0x80, 0x2e, 0xaf, 0xb7, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e,
0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x01, 0x2e, 0x5d, 0xf7, 0x08, 0xbc, 0x80, 0xac, 0x0e, 0xbb, 0x02, 0x2f,
0x00, 0x30, 0x41, 0x04, 0x82, 0x06, 0xc0, 0xa4, 0x00, 0x30, 0x11, 0x2f, 0x40, 0xa9, 0x03, 0x2f, 0x40, 0x91, 0x0d,
0x2f, 0x00, 0xa7, 0x0b, 0x2f, 0x80, 0xb3, 0xb3, 0x58, 0x02, 0x2f, 0x90, 0xa1, 0x26, 0x13, 0x20, 0x23, 0x80, 0x90,
0x10, 0x30, 0x01, 0x2f, 0xcc, 0x0e, 0x00, 0x2f, 0x00, 0x30, 0xb8, 0x2e, 0xb5, 0x50, 0x18, 0x08, 0x08, 0xbc, 0x88,
0xb6, 0x0d, 0x17, 0xc6, 0xbd, 0x56, 0xbc, 0xb7, 0x58, 0xda, 0xba, 0x04, 0x01, 0x1d, 0x0a, 0x10, 0x50, 0x05, 0x30,
0x32, 0x25, 0x45, 0x03, 0xfb, 0x7f, 0xf6, 0x30, 0x21, 0x25, 0x98, 0x2e, 0x37, 0xca, 0x16, 0xb5, 0x9a, 0xbc, 0x06,
0xb8, 0x80, 0xa8, 0x41, 0x0a, 0x0e, 0x2f, 0x80, 0x90, 0x02, 0x2f, 0x2d, 0x50, 0x48, 0x0f, 0x09, 0x2f, 0xbf, 0xa0,
0x04, 0x2f, 0xbf, 0x90, 0x06, 0x2f, 0xb7, 0x54, 0xca, 0x0f, 0x03, 0x2f, 0x00, 0x2e, 0x02, 0x2c, 0xb7, 0x52, 0x2d,
0x52, 0xf2, 0x33, 0x98, 0x2e, 0xd9, 0xc0, 0xfb, 0x6f, 0xf1, 0x37, 0xc0, 0x2e, 0x01, 0x08, 0xf0, 0x5f, 0xbf, 0x56,
0xb9, 0x54, 0xd0, 0x40, 0xc4, 0x40, 0x0b, 0x2e, 0xfd, 0xf3, 0xbf, 0x52, 0x90, 0x42, 0x94, 0x42, 0x95, 0x42, 0x05,
0x30, 0xc1, 0x50, 0x0f, 0x88, 0x06, 0x40, 0x04, 0x41, 0x96, 0x42, 0xc5, 0x42, 0x48, 0xbe, 0x73, 0x30, 0x0d, 0x2e,
0xd8, 0x00, 0x4f, 0xba, 0x84, 0x42, 0x03, 0x42, 0x81, 0xb3, 0x02, 0x2f, 0x2b, 0x2e, 0x6f, 0xf5, 0x06, 0x2d, 0x05,
0x2e, 0x77, 0xf7, 0xbd, 0x56, 0x93, 0x08, 0x25, 0x2e, 0x77, 0xf7, 0xbb, 0x54, 0x25, 0x2e, 0xc2, 0xf5, 0x07, 0x2e,
0xfd, 0xf3, 0x42, 0x30, 0xb4, 0x33, 0xda, 0x0a, 0x4c, 0x00, 0x27, 0x2e, 0xfd, 0xf3, 0x43, 0x40, 0xd4, 0x3f, 0xdc,
0x08, 0x43, 0x42, 0x00, 0x2e, 0x00, 0x2e, 0x43, 0x40, 0x24, 0x30, 0xdc, 0x0a, 0x43, 0x42, 0x04, 0x80, 0x03, 0x2e,
0xfd, 0xf3, 0x4a, 0x0a, 0x23, 0x2e, 0xfd, 0xf3, 0x61, 0x34, 0xc0, 0x2e, 0x01, 0x42, 0x00, 0x2e, 0x60, 0x50, 0x1a,
0x25, 0x7a, 0x86, 0xe0, 0x7f, 0xf3, 0x7f, 0x03, 0x25, 0xc3, 0x52, 0x41, 0x84, 0xdb, 0x7f, 0x33, 0x30, 0x98, 0x2e,
0x16, 0xc2, 0x1a, 0x25, 0x7d, 0x82, 0xf0, 0x6f, 0xe2, 0x6f, 0x32, 0x25, 0x16, 0x40, 0x94, 0x40, 0x26, 0x01, 0x85,
0x40, 0x8e, 0x17, 0xc4, 0x42, 0x6e, 0x03, 0x95, 0x42, 0x41, 0x0e, 0xf4, 0x2f, 0xdb, 0x6f, 0xa0, 0x5f, 0xb8, 0x2e,
0xb0, 0x51, 0xfb, 0x7f, 0x98, 0x2e, 0xe8, 0x0d, 0x5a, 0x25, 0x98, 0x2e, 0x0f, 0x0e, 0xcb, 0x58, 0x32, 0x87, 0xc4,
0x7f, 0x65, 0x89, 0x6b, 0x8d, 0xc5, 0x5a, 0x65, 0x7f, 0xe1, 0x7f, 0x83, 0x7f, 0xa6, 0x7f, 0x74, 0x7f, 0xd0, 0x7f,
0xb6, 0x7f, 0x94, 0x7f, 0x17, 0x30, 0xc7, 0x52, 0xc9, 0x54, 0x51, 0x7f, 0x00, 0x2e, 0x85, 0x6f, 0x42, 0x7f, 0x00,
0x2e, 0x51, 0x41, 0x45, 0x81, 0x42, 0x41, 0x13, 0x40, 0x3b, 0x8a, 0x00, 0x40, 0x4b, 0x04, 0xd0, 0x06, 0xc0, 0xac,
0x85, 0x7f, 0x02, 0x2f, 0x02, 0x30, 0x51, 0x04, 0xd3, 0x06, 0x41, 0x84, 0x05, 0x30, 0x5d, 0x02, 0xc9, 0x16, 0xdf,
0x08, 0xd3, 0x00, 0x8d, 0x02, 0xaf, 0xbc, 0xb1, 0xb9, 0x59, 0x0a, 0x65, 0x6f, 0x11, 0x43, 0xa1, 0xb4, 0x52, 0x41,
0x53, 0x41, 0x01, 0x43, 0x34, 0x7f, 0x65, 0x7f, 0x26, 0x31, 0xe5, 0x6f, 0xd4, 0x6f, 0x98, 0x2e, 0x37, 0xca, 0x32,
0x6f, 0x75, 0x6f, 0x83, 0x40, 0x42, 0x41, 0x23, 0x7f, 0x12, 0x7f, 0xf6, 0x30, 0x40, 0x25, 0x51, 0x25, 0x98, 0x2e,
0x37, 0xca, 0x14, 0x6f, 0x20, 0x05, 0x70, 0x6f, 0x25, 0x6f, 0x69, 0x07, 0xa2, 0x6f, 0x31, 0x6f, 0x0b, 0x30, 0x04,
0x42, 0x9b, 0x42, 0x8b, 0x42, 0x55, 0x42, 0x32, 0x7f, 0x40, 0xa9, 0xc3, 0x6f, 0x71, 0x7f, 0x02, 0x30, 0xd0, 0x40,
0xc3, 0x7f, 0x03, 0x2f, 0x40, 0x91, 0x15, 0x2f, 0x00, 0xa7, 0x13, 0x2f, 0x00, 0xa4, 0x11, 0x2f, 0x84, 0xbd, 0x98,
0x2e, 0x79, 0xca, 0x55, 0x6f, 0xb7, 0x54, 0x54, 0x41, 0x82, 0x00, 0xf3, 0x3f, 0x45, 0x41, 0xcb, 0x02, 0xf6, 0x30,
0x98, 0x2e, 0x37, 0xca, 0x35, 0x6f, 0xa4, 0x6f, 0x41, 0x43, 0x03, 0x2c, 0x00, 0x43, 0xa4, 0x6f, 0x35, 0x6f, 0x17,
0x30, 0x42, 0x6f, 0x51, 0x6f, 0x93, 0x40, 0x42, 0x82, 0x00, 0x41, 0xc3, 0x00, 0x03, 0x43, 0x51, 0x7f, 0x00, 0x2e,
0x94, 0x40, 0x41, 0x41, 0x4c, 0x02, 0xc4, 0x6f, 0xd1, 0x56, 0x63, 0x0e, 0x74, 0x6f, 0x51, 0x43, 0xa5, 0x7f, 0x8a,
0x2f, 0x09, 0x2e, 0xd8, 0x00, 0x01, 0xb3, 0x21, 0x2f, 0xcb, 0x58, 0x90, 0x6f, 0x13, 0x41, 0xb6, 0x6f, 0xe4, 0x7f,
0x00, 0x2e, 0x91, 0x41, 0x14, 0x40, 0x92, 0x41, 0x15, 0x40, 0x17, 0x2e, 0x6f, 0xf5, 0xb6, 0x7f, 0xd0, 0x7f, 0xcb,
0x7f, 0x98, 0x2e, 0x00, 0x0c, 0x07, 0x15, 0xc2, 0x6f, 0x14, 0x0b, 0x29, 0x2e, 0x6f, 0xf5, 0xc3, 0xa3, 0xc1, 0x8f,
0xe4, 0x6f, 0xd0, 0x6f, 0xe6, 0x2f, 0x14, 0x30, 0x05, 0x2e, 0x6f, 0xf5, 0x14, 0x0b, 0x29, 0x2e, 0x6f, 0xf5, 0x18,
0x2d, 0xcd, 0x56, 0x04, 0x32, 0xb5, 0x6f, 0x1c, 0x01, 0x51, 0x41, 0x52, 0x41, 0xc3, 0x40, 0xb5, 0x7f, 0xe4, 0x7f,
0x98, 0x2e, 0x1f, 0x0c, 0xe4, 0x6f, 0x21, 0x87, 0x00, 0x43, 0x04, 0x32, 0xcf, 0x54, 0x5a, 0x0e, 0xef, 0x2f, 0x15,
0x54, 0x09, 0x2e, 0x77, 0xf7, 0x22, 0x0b, 0x29, 0x2e, 0x77, 0xf7, 0xfb, 0x6f, 0x50, 0x5e, 0xb8, 0x2e, 0x10, 0x50,
0x01, 0x2e, 0xd4, 0x00, 0x00, 0xb2, 0xfb, 0x7f, 0x51, 0x2f, 0x01, 0xb2, 0x48, 0x2f, 0x02, 0xb2, 0x42, 0x2f, 0x03,
0x90, 0x56, 0x2f, 0xd7, 0x52, 0x79, 0x80, 0x42, 0x40, 0x81, 0x84, 0x00, 0x40, 0x42, 0x42, 0x98, 0x2e, 0x93, 0x0c,
0xd9, 0x54, 0xd7, 0x50, 0xa1, 0x40, 0x98, 0xbd, 0x82, 0x40, 0x3e, 0x82, 0xda, 0x0a, 0x44, 0x40, 0x8b, 0x16, 0xe3,
0x00, 0x53, 0x42, 0x00, 0x2e, 0x43, 0x40, 0x9a, 0x02, 0x52, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x15, 0x54, 0x4a, 0x0e,
0x3a, 0x2f, 0x3a, 0x82, 0x00, 0x30, 0x41, 0x40, 0x21, 0x2e, 0x85, 0x0f, 0x40, 0xb2, 0x0a, 0x2f, 0x98, 0x2e, 0xb1,
0x0c, 0x98, 0x2e, 0x45, 0x0e, 0x98, 0x2e, 0x5b, 0x0e, 0xfb, 0x6f, 0xf0, 0x5f, 0x00, 0x30, 0x80, 0x2e, 0xce, 0xb7,
0xdd, 0x52, 0xd3, 0x54, 0x42, 0x42, 0x4f, 0x84, 0x73, 0x30, 0xdb, 0x52, 0x83, 0x42, 0x1b, 0x30, 0x6b, 0x42, 0x23,
0x30, 0x27, 0x2e, 0xd7, 0x00, 0x37, 0x2e, 0xd4, 0x00, 0x21, 0x2e, 0xd6, 0x00, 0x7a, 0x84, 0x17, 0x2c, 0x42, 0x42,
0x30, 0x30, 0x21, 0x2e, 0xd4, 0x00, 0x12, 0x2d, 0x21, 0x30, 0x00, 0x30, 0x23, 0x2e, 0xd4, 0x00, 0x21, 0x2e, 0x7b,
0xf7, 0x0b, 0x2d, 0x17, 0x30, 0x98, 0x2e, 0x51, 0x0c, 0xd5, 0x50, 0x0c, 0x82, 0x72, 0x30, 0x2f, 0x2e, 0xd4, 0x00,
0x25, 0x2e, 0x7b, 0xf7, 0x40, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x70, 0x50, 0x0a, 0x25, 0x39,
0x86, 0xfb, 0x7f, 0xe1, 0x32, 0x62, 0x30, 0x98, 0x2e, 0xc2, 0xc4, 0xb5, 0x56, 0xa5, 0x6f, 0xab, 0x08, 0x91, 0x6f,
0x4b, 0x08, 0xdf, 0x56, 0xc4, 0x6f, 0x23, 0x09, 0x4d, 0xba, 0x93, 0xbc, 0x8c, 0x0b, 0xd1, 0x6f, 0x0b, 0x09, 0xcb,
0x52, 0xe1, 0x5e, 0x56, 0x42, 0xaf, 0x09, 0x4d, 0xba, 0x23, 0xbd, 0x94, 0x0a, 0xe5, 0x6f, 0x68, 0xbb, 0xeb, 0x08,
0xbd, 0xb9, 0x63, 0xbe, 0xfb, 0x6f, 0x52, 0x42, 0xe3, 0x0a, 0xc0, 0x2e, 0x43, 0x42, 0x90, 0x5f, 0xd1, 0x50, 0x03,
0x2e, 0x25, 0xf3, 0x13, 0x40, 0x00, 0x40, 0x9b, 0xbc, 0x9b, 0xb4, 0x08, 0xbd, 0xb8, 0xb9, 0x98, 0xbc, 0xda, 0x0a,
0x08, 0xb6, 0x89, 0x16, 0xc0, 0x2e, 0x19, 0x00, 0x62, 0x02, 0x10, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0x81, 0x0d, 0x01,
0x2e, 0xd4, 0x00, 0x31, 0x30, 0x08, 0x04, 0xfb, 0x6f, 0x01, 0x30, 0xf0, 0x5f, 0x23, 0x2e, 0xd6, 0x00, 0x21, 0x2e,
0xd7, 0x00, 0xb8, 0x2e, 0x01, 0x2e, 0xd7, 0x00, 0x03, 0x2e, 0xd6, 0x00, 0x48, 0x0e, 0x01, 0x2f, 0x80, 0x2e, 0x1f,
0x0e, 0xb8, 0x2e, 0xe3, 0x50, 0x21, 0x34, 0x01, 0x42, 0x82, 0x30, 0xc1, 0x32, 0x25, 0x2e, 0x62, 0xf5, 0x01, 0x00,
0x22, 0x30, 0x01, 0x40, 0x4a, 0x0a, 0x01, 0x42, 0xb8, 0x2e, 0xe3, 0x54, 0xf0, 0x3b, 0x83, 0x40, 0xd8, 0x08, 0xe5,
0x52, 0x83, 0x42, 0x00, 0x30, 0x83, 0x30, 0x50, 0x42, 0xc4, 0x32, 0x27, 0x2e, 0x64, 0xf5, 0x94, 0x00, 0x50, 0x42,
0x40, 0x42, 0xd3, 0x3f, 0x84, 0x40, 0x7d, 0x82, 0xe3, 0x08, 0x40, 0x42, 0x83, 0x42, 0xb8, 0x2e, 0xdd, 0x52, 0x00,
0x30, 0x40, 0x42, 0x7c, 0x86, 0xb9, 0x52, 0x09, 0x2e, 0x70, 0x0f, 0xbf, 0x54, 0xc4, 0x42, 0xd3, 0x86, 0x54, 0x40,
0x55, 0x40, 0x94, 0x42, 0x85, 0x42, 0x21, 0x2e, 0xd7, 0x00, 0x42, 0x40, 0x25, 0x2e, 0xfd, 0xf3, 0xc0, 0x42, 0x7e,
0x82, 0x05, 0x2e, 0x7d, 0x00, 0x80, 0xb2, 0x14, 0x2f, 0x05, 0x2e, 0x89, 0x00, 0x27, 0xbd, 0x2f, 0xb9, 0x80, 0x90,
0x02, 0x2f, 0x21, 0x2e, 0x6f, 0xf5, 0x0c, 0x2d, 0x07, 0x2e, 0x71, 0x0f, 0x14, 0x30, 0x1c, 0x09, 0x05, 0x2e, 0x77,
0xf7, 0xbd, 0x56, 0x47, 0xbe, 0x93, 0x08, 0x94, 0x0a, 0x25, 0x2e, 0x77, 0xf7, 0xe7, 0x54, 0x50, 0x42, 0x4a, 0x0e,
0xfc, 0x2f, 0xb8, 0x2e, 0x50, 0x50, 0x02, 0x30, 0x43, 0x86, 0xe5, 0x50, 0xfb, 0x7f, 0xe3, 0x7f, 0xd2, 0x7f, 0xc0,
0x7f, 0xb1, 0x7f, 0x00, 0x2e, 0x41, 0x40, 0x00, 0x40, 0x48, 0x04, 0x98, 0x2e, 0x74, 0xc0, 0x1e, 0xaa, 0xd3, 0x6f,
0x14, 0x30, 0xb1, 0x6f, 0xe3, 0x22, 0xc0, 0x6f, 0x52, 0x40, 0xe4, 0x6f, 0x4c, 0x0e, 0x12, 0x42, 0xd3, 0x7f, 0xeb,
0x2f, 0x03, 0x2e, 0x86, 0x0f, 0x40, 0x90, 0x11, 0x30, 0x03, 0x2f, 0x23, 0x2e, 0x86, 0x0f, 0x02, 0x2c, 0x00, 0x30,
0xd0, 0x6f, 0xfb, 0x6f, 0xb0, 0x5f, 0xb8, 0x2e, 0x40, 0x50, 0xf1, 0x7f, 0x0a, 0x25, 0x3c, 0x86, 0xeb, 0x7f, 0x41,
0x33, 0x22, 0x30, 0x98, 0x2e, 0xc2, 0xc4, 0xd3, 0x6f, 0xf4, 0x30, 0xdc, 0x09, 0x47, 0x58, 0xc2, 0x6f, 0x94, 0x09,
0xeb, 0x58, 0x6a, 0xbb, 0xdc, 0x08, 0xb4, 0xb9, 0xb1, 0xbd, 0xe9, 0x5a, 0x95, 0x08, 0x21, 0xbd, 0xf6, 0xbf, 0x77,
0x0b, 0x51, 0xbe, 0xf1, 0x6f, 0xeb, 0x6f, 0x52, 0x42, 0x54, 0x42, 0xc0, 0x2e, 0x43, 0x42, 0xc0, 0x5f, 0x50, 0x50,
0xf5, 0x50, 0x31, 0x30, 0x11, 0x42, 0xfb, 0x7f, 0x7b, 0x30, 0x0b, 0x42, 0x11, 0x30, 0x02, 0x80, 0x23, 0x33, 0x01,
0x42, 0x03, 0x00, 0x07, 0x2e, 0x80, 0x03, 0x05, 0x2e, 0xd3, 0x00, 0x23, 0x52, 0xe2, 0x7f, 0xd3, 0x7f, 0xc0, 0x7f,
0x98, 0x2e, 0xb6, 0x0e, 0xd1, 0x6f, 0x08, 0x0a, 0x1a, 0x25, 0x7b, 0x86, 0xd0, 0x7f, 0x01, 0x33, 0x12, 0x30, 0x98,
0x2e, 0xc2, 0xc4, 0xd1, 0x6f, 0x08, 0x0a, 0x00, 0xb2, 0x0d, 0x2f, 0xe3, 0x6f, 0x01, 0x2e, 0x80, 0x03, 0x51, 0x30,
0xc7, 0x86, 0x23, 0x2e, 0x21, 0xf2, 0x08, 0xbc, 0xc0, 0x42, 0x98, 0x2e, 0xa5, 0xb7, 0x00, 0x2e, 0x00, 0x2e, 0xd0,
0x2e, 0xb0, 0x6f, 0x0b, 0xb8, 0x03, 0x2e, 0x1b, 0x00, 0x08, 0x1a, 0xb0, 0x7f, 0x70, 0x30, 0x04, 0x2f, 0x21, 0x2e,
0x21, 0xf2, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x98, 0x2e, 0x6d, 0xc0, 0x98, 0x2e, 0x5d, 0xc0, 0xed, 0x50, 0x98,
0x2e, 0x44, 0xcb, 0xef, 0x50, 0x98, 0x2e, 0x46, 0xc3, 0xf1, 0x50, 0x98, 0x2e, 0x53, 0xc7, 0x35, 0x50, 0x98, 0x2e,
0x64, 0xcf, 0x10, 0x30, 0x98, 0x2e, 0xdc, 0x03, 0x20, 0x26, 0xc0, 0x6f, 0x02, 0x31, 0x12, 0x42, 0xab, 0x33, 0x0b,
0x42, 0x37, 0x80, 0x01, 0x30, 0x01, 0x42, 0xf3, 0x37, 0xf7, 0x52, 0xfb, 0x50, 0x44, 0x40, 0xa2, 0x0a, 0x42, 0x42,
0x8b, 0x31, 0x09, 0x2e, 0x5e, 0xf7, 0xf9, 0x54, 0xe3, 0x08, 0x83, 0x42, 0x1b, 0x42, 0x23, 0x33, 0x4b, 0x00, 0xbc,
0x84, 0x0b, 0x40, 0x33, 0x30, 0x83, 0x42, 0x0b, 0x42, 0xe0, 0x7f, 0xd1, 0x7f, 0x98, 0x2e, 0x58, 0xb7, 0xd1, 0x6f,
0x80, 0x30, 0x40, 0x42, 0x03, 0x30, 0xe0, 0x6f, 0xf3, 0x54, 0x04, 0x30, 0x00, 0x2e, 0x00, 0x2e, 0x01, 0x89, 0x62,
0x0e, 0xfa, 0x2f, 0x43, 0x42, 0x11, 0x30, 0xfb, 0x6f, 0xc0, 0x2e, 0x01, 0x42, 0xb0, 0x5f, 0xc1, 0x4a, 0x00, 0x00,
0x6d, 0x57, 0x00, 0x00, 0x77, 0x8e, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xd3, 0xff, 0xff, 0xff, 0xe5, 0xff, 0xff,
0xff, 0xee, 0xe1, 0xff, 0xff, 0x7c, 0x13, 0x00, 0x00, 0x46, 0xe6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e,
0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e,
0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e,
0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80,
0x2e, 0x00, 0xc1
};
/*! @name Global array that stores the feature input configuration of BMI270 */
const struct bmi2_feature_config bmi270_feat_in[BMI270_MAX_FEAT_IN] = {
{ .type = BMI2_CONFIG_ID, .page = BMI2_PAGE_1, .start_addr = BMI270_CONFIG_ID_STRT_ADDR },
{ .type = BMI2_MAX_BURST_LEN, .page = BMI2_PAGE_1, .start_addr = BMI270_MAX_BURST_LEN_STRT_ADDR },
{ .type = BMI2_CRT_GYRO_SELF_TEST, .page = BMI2_PAGE_1, .start_addr = BMI270_CRT_GYRO_SELF_TEST_STRT_ADDR },
{ .type = BMI2_ABORT_CRT_GYRO_SELF_TEST, .page = BMI2_PAGE_1, .start_addr = BMI270_ABORT_STRT_ADDR },
{ .type = BMI2_AXIS_MAP, .page = BMI2_PAGE_1, .start_addr = BMI270_AXIS_MAP_STRT_ADDR },
{ .type = BMI2_GYRO_SELF_OFF, .page = BMI2_PAGE_1, .start_addr = BMI270_GYRO_SELF_OFF_STRT_ADDR },
{ .type = BMI2_NVM_PROG_PREP, .page = BMI2_PAGE_1, .start_addr = BMI270_NVM_PROG_PREP_STRT_ADDR },
{ .type = BMI2_GYRO_GAIN_UPDATE, .page = BMI2_PAGE_1, .start_addr = BMI270_GYRO_GAIN_UPDATE_STRT_ADDR },
{ .type = BMI2_ANY_MOTION, .page = BMI2_PAGE_1, .start_addr = BMI270_ANY_MOT_STRT_ADDR },
{ .type = BMI2_NO_MOTION, .page = BMI2_PAGE_2, .start_addr = BMI270_NO_MOT_STRT_ADDR },
{ .type = BMI2_SIG_MOTION, .page = BMI2_PAGE_2, .start_addr = BMI270_SIG_MOT_STRT_ADDR },
{ .type = BMI2_STEP_COUNTER_PARAMS, .page = BMI2_PAGE_3, .start_addr = BMI270_STEP_CNT_1_STRT_ADDR },
{ .type = BMI2_STEP_DETECTOR, .page = BMI2_PAGE_6, .start_addr = BMI270_STEP_CNT_4_STRT_ADDR },
{ .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_6, .start_addr = BMI270_STEP_CNT_4_STRT_ADDR },
{ .type = BMI2_STEP_ACTIVITY, .page = BMI2_PAGE_6, .start_addr = BMI270_STEP_CNT_4_STRT_ADDR },
{ .type = BMI2_WRIST_GESTURE, .page = BMI2_PAGE_6, .start_addr = BMI270_WRIST_GEST_STRT_ADDR },
{ .type = BMI2_WRIST_WEAR_WAKE_UP, .page = BMI2_PAGE_7, .start_addr = BMI270_WRIST_WEAR_WAKE_UP_STRT_ADDR },
};
/*! @name Global array that stores the feature output configuration */
const struct bmi2_feature_config bmi270_feat_out[BMI270_MAX_FEAT_OUT] = {
{ .type = BMI2_STEP_COUNTER, .page = BMI2_PAGE_0, .start_addr = BMI270_STEP_CNT_OUT_STRT_ADDR },
{ .type = BMI2_STEP_ACTIVITY, .page = BMI2_PAGE_0, .start_addr = BMI270_STEP_ACT_OUT_STRT_ADDR },
{ .type = BMI2_WRIST_GESTURE, .page = BMI2_PAGE_0, .start_addr = BMI270_WRIST_GEST_OUT_STRT_ADDR },
{ .type = BMI2_GYRO_GAIN_UPDATE, .page = BMI2_PAGE_0, .start_addr = BMI270_GYR_USER_GAIN_OUT_STRT_ADDR },
{ .type = BMI2_GYRO_CROSS_SENSE, .page = BMI2_PAGE_0, .start_addr = BMI270_GYRO_CROSS_SENSE_STRT_ADDR },
{ .type = BMI2_NVM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_NVM_VFRM_OUT_STRT_ADDR },
{ .type = BMI2_VFRM_STATUS, .page = BMI2_PAGE_0, .start_addr = BMI270_NVM_VFRM_OUT_STRT_ADDR }
};
/*! @name Global array that stores the feature interrupts of BMI270 */
struct bmi2_map_int bmi270_map_int[BMI270_MAX_INT_MAP] = {
{ .type = BMI2_SIG_MOTION, .sens_map_int = BMI270_INT_SIG_MOT_MASK },
{ .type = BMI2_STEP_COUNTER, .sens_map_int = BMI270_INT_STEP_COUNTER_MASK },
{ .type = BMI2_STEP_DETECTOR, .sens_map_int = BMI270_INT_STEP_DETECTOR_MASK },
{ .type = BMI2_STEP_ACTIVITY, .sens_map_int = BMI270_INT_STEP_ACT_MASK },
{ .type = BMI2_WRIST_GESTURE, .sens_map_int = BMI270_INT_WRIST_GEST_MASK },
{ .type = BMI2_WRIST_WEAR_WAKE_UP, .sens_map_int = BMI270_INT_WRIST_WEAR_WAKEUP_MASK },
{ .type = BMI2_ANY_MOTION, .sens_map_int = BMI270_INT_ANY_MOT_MASK },
{ .type = BMI2_NO_MOTION, .sens_map_int = BMI270_INT_NO_MOT_MASK },
};
/******************************************************************************/
/*! Local Function Prototypes
******************************************************************************/
/*!
* @brief This internal API is used to validate the device pointer for
* null conditions.
*
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t null_ptr_check(const struct bmi2_dev *dev);
/*!
* @brief This internal API enables the selected sensor/features.
*
* @param[in] sensor_sel : Selects the desired sensor.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev);
/*!
* @brief This internal API disables the selected sensor/features.
*
* @param[in] sensor_sel : Selects the desired sensor.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev);
/*!
* @brief This internal API selects the sensors/features to be enabled or
* disabled.
*
* @param[in] sens_list : Pointer to select the sensor.
* @param[in] n_sens : Number of sensors selected.
* @param[out] sensor_sel : Gets the selected sensor.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel);
/*!
* @brief This internal API is used to enable/disable any-motion feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables any-motion.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables any-motion.
* BMI2_ENABLE | Enables any-motion.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable/disable no-motion feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables no-motion.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables no-motion.
* BMI2_ENABLE | Enables no-motion.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable/disable sig-motion feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables sig-motion.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables sig-motion.
* BMI2_ENABLE | Enables sig-motion.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_sig_motion(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable/disable step detector feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables step-detector.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables step detector
* BMI2_ENABLE | Enables step detector
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable/disable step counter feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables step counter.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables step counter
* BMI2_ENABLE | Enables step counter
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable/disable step activity detection.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables step activity.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables step activity
* BMI2_ENABLE | Enables step activity
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API gives an option to enable offset correction
* feature of gyroscope, either internally or by the host.
*
* @param[in] enable : Enables/Disables self-offset correction.
* @param[in] dev : Structure instance of bmi2_dev.
*
* enable | Description
* -------------|---------------
* BMI2_ENABLE | gyroscope offset correction values are set internally
* BMI2_DISABLE | gyroscope offset correction values has to be set by host
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_gyro_self_offset_corr(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable/disable gyroscope user gain
* feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables gyroscope user gain.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables gyroscope user gain
* BMI2_ENABLE | Enables gyroscope user gain
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API enables the wrist gesture feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables wrist gesture.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables wrist gesture
* BMI2_ENABLE | Enables wrist gesture
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_wrist_gesture(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API enables the wrist wear wake up feature.
*
* @param[in] dev : Structure instance of bmi2_dev.
* @param[in] enable : Enables/Disables wrist wear wake up.
*
* Enable | Description
* -------------|---------------
* BMI2_DISABLE | Disables wrist wear wake up
* BMI2_ENABLE | Enables wrist wear wake up
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_wrist_wear_wake_up(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API sets any-motion configurations like axes select,
* duration, threshold and output-configuration.
*
* @param[in] config : Structure instance of bmi2_any_motion_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
*----------------------------------------------------------------------------
* bmi2_any_motion_config |
* Structure parameters | Description
*--------------------------|--------------------------------------------------
* | Defines the number of consecutive data points for
* | which the threshold condition must be respected,
* | for interrupt assertion. It is expressed in 50 Hz
* duration | samples (20 msec).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* -------------------------|---------------------------------------------------
* | Slope threshold value for in 5.11g format.
* threshold | Range is 0 to 1g.
* | Default value is 0xAA = 83mg.
* -------------------------|---------------------------------------------------
* x_sel, y_sel, z_sel | Selects the feature on a per-axis basis
* -------------------------|---------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API sets no-motion configurations like axes select,
* duration, threshold and output-configuration.
*
* @param[in] config : Structure instance of bmi2_no_motion_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
*----------------------------------------------------------------------------
* bmi2_no_motion_config |
* Structure parameters | Description
*--------------------------|--------------------------------------------------
* | Defines the number of consecutive data points for
* | which the threshold condition must be respected,
* | for interrupt assertion. It is expressed in 50 Hz
* duration | samples (20 msec).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* -------------------------|---------------------------------------------------
* | Slope threshold value for in 5.11g format.
* threshold | Range is 0 to 1g.
* | Default value is 0x90 = 70mg.
* -------------------------|---------------------------------------------------
* x_sel, y_sel, z_sel | Selects the feature on a per-axis basis
* -------------------------|---------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API sets sig-motion configurations like block-size,
* output-configuration and other parameters.
*
* @param[in] config : Structure instance of bmi2_sig_motion_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
*----------------------------------------------------------------------------
* bmi2_sig_motion_config |
* Structure parameters | Description
* -------------------------|---------------------------------------------------
* | Defines the duration after which the significant
* block_size | motion interrupt is triggered. It is expressed in
* | 50 Hz samples (20 ms). Default value is 0xFA=5sec.
*--------------------------|---------------------------------------------------
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_sig_motion_config(const struct bmi2_sig_motion_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API sets step counter parameter configurations.
*
* @param[in] step_count_params : Array that stores parameters 1 to 25.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev);
/*!
* @brief This internal API sets step counter/detector/activity configurations.
*
* @param[in] config : Structure instance of bmi2_step_config.
* @param[in] dev : Structure instance of bmi2_dev.
*
*---------------------------------------------------------------------------
* bmi2_step_config |
* Structure parameters | Description
*--------------------------|--------------------------------------------------
* | The Step-counter will trigger output every time
* | the number of steps are counted. Holds implicitly
* water-mark level | a 20x factor, so the range is 0 to 10230,
* | with resolution of 20 steps.
* -------------------------|---------------------------------------------------
* reset counter | Flag to reset the counted steps.
* -------------------------|---------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API sets wrist gesture configurations like wearable-arm,
* and output-configuration.
*
* @param[in] config : Structure instance of bmi2_wrist_gest_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
* --------------------------------------------------------------------------------------------
* bmi2_wrist_gest_config |
* Structure parameters | Description
* --------------------------------------------------------------------------------------------
* | Device in left (0) or right (1) arm. By default,
* wearable_arm | the wearable device is assumed to be in left arm
* | i.e. default value is 0.
* --------------------------------------------------------------------------------------------
* | Sine of the minimum tilt angle in portrait down
* | direction of the device when wrist is rolled away
* | (roll-out) from user.
* min_flick_peak | The configuration parameter is scaled by 2048
* | i.e. 2048 * sin(angle).
* | Range is 1448 to 1774. Default value is 1774.
* --------------------------------------------------------------------------------------------
* | Value of minimum time difference between wrist
* | roll-out and roll-in movement during flick gesture.
* min_flick_samples | Range is 3 to 5 samples at 50Hz (i.e. 0.06 to 0.1 seconds).
* | Default value is 4 (i.e. 0.08 seconds).
* --------------------------------------------------------------------------------------------
* | Maximum time within which gesture movement has to be completed.
* max_duration | Range is 150 to 250 samples at 50Hz (i.e. 3 to 5 seconds).
* | Default value is 200 (i.e. 4 seconds).
* --------------------------------------------------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_wrist_gest_config(const struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API sets wrist wear wake-up configurations like
* output-configuration.
*
* @param[in] config : Structure instance of
* bmi2_wrist_wear_wake_up_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
*-----------------------------------------------------------------------------
* bmi2_wrist_wear_wake_up_config |
* Structure parameters | Description
*----------------------------------|-------------------------------------------
* | To set the wrist wear wake-up parameters like
* | min_angle_focus, min_angle_nonfocus,
* wrist_wear_wakeup_params | max_tilt_lr, max_tilt_ll,
* | max_tilt_pd and max_tilt_pu.
* ---------------------------------|-------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_wrist_wear_wake_up_config(const struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets any-motion configurations like axes select,
* duration, threshold and output-configuration.
*
* @param[out] config : Structure instance of bmi2_any_motion_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
*----------------------------------------------------------------------------
* bmi2_any_motion_config |
* Structure parameters | Description
*--------------------------|--------------------------------------------------
* | Defines the number of consecutive data points for
* | which the threshold condition must be respected,
* | for interrupt assertion. It is expressed in 50 Hz
* duration | samples (20 msec).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* -------------------------|---------------------------------------------------
* | Slope threshold value for in 5.11g format.
* threshold | Range is 0 to 1g.
* | Default value is 0xAA = 83mg.
* -------------------------|---------------------------------------------------
* select_x, select_y, |
* select_z | Selects the feature on a per-axis basis
* -------------------------|---------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets no-motion configurations like axes select,
* duration, threshold and output-configuration.
*
* @param[out] config : Structure instance of bmi2_no_motion_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
*----------------------------------------------------------------------------
* bmi2_no_motion_config |
* Structure parameters | Description
*--------------------------|--------------------------------------------------
* | Defines the number of consecutive data points for
* | which the threshold condition must be respected,
* | for interrupt assertion. It is expressed in 50 Hz
* duration | samples (20 msec).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* -------------------------|---------------------------------------------------
* | Slope threshold value for in 5.11g format.
* threshold | Range is 0 to 1g.
* | Default value is 0x90 = 70mg.
* -------------------------|---------------------------------------------------
* select_x, select_y, |
* select_z | Selects the feature on a per-axis basis
* -------------------------|---------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets sig-motion configurations like block-size,
* output-configuration and other parameters.
*
* @param[out] config : Structure instance of bmi2_sig_motion_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
*----------------------------------------------------------------------------
* bmi2_sig_motion_config |
* Structure parameters | Description
* -------------------------|---------------------------------------------------
* | Defines the duration after which the significant
* block_size | motion interrupt is triggered. It is expressed in
* | 50 Hz samples (20 ms). Default value is 0xFA=5sec.
*--------------------------|---------------------------------------------------
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_sig_motion_config(struct bmi2_sig_motion_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets step counter parameter configurations.
*
* @param[in] step_count_params : Array that stores parameters 1 to 25.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev);
/*!
* @brief This internal API gets step counter/detector/activity configurations.
*
* @param[out] config : Structure instance of bmi2_step_config.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @verbatim
*----------------------------------------------------------------------------
* bmi2_step_config |
* Structure parameters | Description
*--------------------------|--------------------------------------------------
* | The Step-counter will trigger output every time
* | the number of steps are counted. Holds implicitly
* water-mark level | a 20x factor, so the range is 0 to 20460,
* | with resolution of 20 steps.
* -------------------------|---------------------------------------------------
* reset counter | Flag to reset the counted steps.
* -------------------------|---------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets wrist gesture configurations like wearable-arm,
* and output-configuration.
*
* @param[out] config : Structure instance of bmi2_wrist_gest_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
* --------------------------------------------------------------------------------------------
* bmi2_wrist_gest_config |
* Structure parameters | Description
* --------------------------------------------------------------------------------------------
* | Device in left (0) or right (1) arm. By default,
* wearable_arm | the wearable device is assumed to be in left arm
* | i.e. default value is 0.
* --------------------------------------------------------------------------------------------
* | Sine of the minimum tilt angle in portrait down
* | direction of the device when wrist is rolled away
* | (roll-out) from user.
* min_flick_peak | The configuration parameter is scaled by 2048
* | i.e. 2048 * sin(angle).
* | Range is 1448 to 1774. Default value is 1774.
* --------------------------------------------------------------------------------------------
* | Value of minimum time difference between wrist
* | roll-out and roll-in movement during flick gesture.
* min_flick_samples | Range is 3 to 5 samples at 50Hz (i.e. 0.06 to 0.1 seconds).
* | Default value is 4 (i.e. 0.08 seconds).
* --------------------------------------------------------------------------------------------
* | Maximum time within which gesture movement has to be completed.
* max_duration | Range is 150 to 250 samples at 50Hz (i.e. 3 to 5 seconds).
* | Default value is 200 (i.e. 4 seconds).
* --------------------------------------------------------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_wrist_gest_config(struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets wrist wear wake-up configurations like
* output-configuration.
*
* @param[out] config : Structure instance of
* bmi2_wrist_wear_wake_up_config.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @verbatim
*-----------------------------------------------------------------------------
* bmi2_wrist_wear_wake_up_config |
* Structure parameters | Description
*----------------------------------|-------------------------------------------
* | To set the wrist wear wake-up parameters like
* | min_angle_focus, min_angle_nonfocus,
* wrist_wear_wakeup_params | max_tilt_lr, max_tilt_ll,
* | max_tilt_pd and max_tilt_pu.
* ---------------------------------|-------------------------------------------
* @endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_wrist_wear_wake_up_config(struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev);
/*!
* @brief This internal API gets the output values of wrist gesture.
*
* @param[out] wrist_gest : Pointer to the stored wrist gesture.
* @param[in] dev : Structure instance of bmi2_dev.
*
* *wrist_gest | Output
* -------------|------------
* 0x00 | UNKNOWN
* 0x01 | PUSH_ARM_DOWN
* 0x02 | PIVOT_UP
* 0x03 | WRIST_SHAKE_JIGGLE
* 0x04 | FLICK_IN
* 0x05 | FLICK_OUT
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_wrist_gest_status(uint8_t *wrist_gest, struct bmi2_dev *dev);
/*!
* @brief This internal API gets the output values of step activity.
*
* @param[out] step_act : Pointer to the stored step activity data.
* @param[in] dev : Structure instance of bmi2_dev.
*
* *step_act | Output
* -----------|------------
* 0x00 | STILL
* 0x01 | WALKING
* 0x02 | RUNNING
* 0x03 | UNKNOWN
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fails
*/
static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev);
/*!
* @brief This internal API gets the output values of step counter.
*
* @param[out] step_count : Pointer to the stored step counter data.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev);
/*!
* @brief This internal API gets the error status related to NVM.
*
* @param[out] nvm_err_stat : Stores the NVM error status.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev);
/*!
* @brief This internal API gets the error status related to virtual frames.
*
* @param[out] vfrm_err_stat : Stores the VFRM related error status.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to get enable status of gyroscope user gain
* update.
*
* @param[out] status : Stores status of gyroscope user gain update.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev);
/*!
* @brief This internal API enables/disables compensation of the gain defined
* in the GAIN register.
*
* @param[in] enable : Enables/Disables gain compensation
* @param[in] dev : Structure instance of bmi2_dev.
*
* enable | Description
* -------------|---------------
* BMI2_ENABLE | Enable gain compensation.
* BMI2_DISABLE | Disable gain compensation.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to extract the output feature configuration
* details like page and start address from the look-up table.
*
* @param[out] feat_output : Structure that stores output feature
* configurations.
* @param[in] type : Type of feature or sensor.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Returns the feature found flag.
*
* @retval BMI2_FALSE : Feature not found
* BMI2_TRUE : Feature found
*/
static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output,
uint8_t type,
const struct bmi2_dev *dev);
/*!
* @brief This internal API sets feature configuration to the sensor.
*
* @param[in] sens_cfg : Structure instance of bmi2_sens_config.
* @param[in] loop : Variable to loop the sensor feature.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t set_feat_config(const struct bmi2_sens_config *sens_cfg, uint8_t loop, struct bmi2_dev *dev);
/*!
* @brief This internal API gets feature configuration from the sensor.
*
* @param[in] sens_cfg : Structure instance of bmi2_sens_config.
* @param[in] loop : Variable to loop the sensor feature.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t get_feat_config(struct bmi2_sens_config *sens_cfg, uint8_t loop, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable main sensors like accel, gyro, aux and temperature.
*
* @param[in] sensor_sel : Enables the selected sensor.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t enable_main_sensors(uint64_t sensor_sel, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to enable sensor features.
*
* @param[in] sensor_sel : Enables features of selected sensor.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t enable_sensor_features(uint64_t sensor_sel, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to disable main sensors like accel, gyro, aux and temperature.
*
* @param[in] sensor_sel : Disables the selected sensor.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t disable_main_sensors(uint64_t sensor_sel, struct bmi2_dev *dev);
/*!
* @brief This internal API is used to disable sensor features.
*
* @param[in] sensor_sel : Disables features of selected sensor.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
static int8_t disable_sensor_features(uint64_t sensor_sel, struct bmi2_dev *dev);
/***************************************************************************/
/*! User Interface Definitions
****************************************************************************/
/*!
* @brief This API:
* 1) updates the device structure with address of the configuration file.
* 2) Initializes BMI270 sensor.
* 3) Writes the configuration file.
* 4) Updates the feature offset parameters in the device structure.
* 5) Updates the maximum number of pages, in the device structure.
*/
int8_t bmi270_init(struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if (rslt == BMI2_OK)
{
/* Assign chip id of BMI270 */
dev->chip_id = BMI270_CHIP_ID;
/* get the size of config array */
dev->config_size = sizeof(bmi270_config_file);
/* Enable the variant specific features if any */
dev->variant_feature = BMI2_GYRO_CROSS_SENS_ENABLE | BMI2_CRT_RTOSK_ENABLE;
/* An extra dummy byte is read during SPI read */
if (dev->intf == BMI2_SPI_INTF)
{
dev->dummy_byte = 1;
}
else
{
dev->dummy_byte = 0;
}
/* If configuration file pointer is not assigned any address */
if (!dev->config_file_ptr)
{
/* Give the address of the configuration file array to
* the device pointer
*/
dev->config_file_ptr = bmi270_config_file;
}
/* Initialize BMI2 sensor */
rslt = bmi2_sec_init(dev);
if (rslt == BMI2_OK)
{
/* Assign the offsets of the feature input
* configuration to the device structure
*/
dev->feat_config = bmi270_feat_in;
/* Assign the offsets of the feature output to
* the device structure
*/
dev->feat_output = bmi270_feat_out;
/* Assign the maximum number of pages to the
* device structure
*/
dev->page_max = BMI270_MAX_PAGE_NUM;
/* Assign maximum number of input sensors/
* features to device structure
*/
dev->input_sens = BMI270_MAX_FEAT_IN;
/* Assign maximum number of output sensors/
* features to device structure
*/
dev->out_sens = BMI270_MAX_FEAT_OUT;
/* Assign the offsets of the feature interrupt
* to the device structure
*/
dev->map_int = bmi270_map_int;
/* Assign maximum number of feature interrupts
* to device structure
*/
dev->sens_int_map = BMI270_MAX_INT_MAP;
/* Get the gyroscope cross axis sensitivity */
rslt = bmi2_get_gyro_cross_sense(dev);
}
}
return rslt;
}
/*!
* @brief This API selects the sensors/features to be enabled.
*/
int8_t bmi270_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to select sensor */
uint64_t sensor_sel = 0;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (sens_list != NULL))
{
/* Get the selected sensors */
rslt = select_sensor(sens_list, n_sens, &sensor_sel);
if (rslt == BMI2_OK)
{
/* Enable the selected sensors */
rslt = sensor_enable(sensor_sel, dev);
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API selects the sensors/features to be disabled.
*/
int8_t bmi270_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to select sensor */
uint64_t sensor_sel = 0;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (sens_list != NULL))
{
/* Get the selected sensors */
rslt = select_sensor(sens_list, n_sens, &sensor_sel);
if (rslt == BMI2_OK)
{
/* Disable the selected sensors */
rslt = sensor_disable(sensor_sel, dev);
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API sets the sensor/feature configuration.
*/
int8_t bmi270_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to define loop */
uint8_t loop;
/* Variable to get the status of advance power save */
uint8_t aps_stat = 0;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (sens_cfg != NULL))
{
/* Get status of advance power save mode */
aps_stat = dev->aps_status;
for (loop = 0; loop < n_sens; loop++)
{
if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) ||
(sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE))
{
rslt = bmi2_set_sensor_config(&sens_cfg[loop], 1, dev);
}
else
{
/* Disable Advance power save if enabled for auxiliary
* and feature configurations
*/
if (aps_stat == BMI2_ENABLE)
{
/* Disable advance power save if
* enabled
*/
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev);
}
if (rslt == BMI2_OK)
{
rslt = set_feat_config(sens_cfg, loop, dev);
}
/* Return error if any of the set configurations fail */
else
{
break;
}
}
}
/* Enable Advance power save if disabled while configuring and
* not when already disabled
*/
if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK))
{
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev);
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API gets the sensor/feature configuration.
*/
int8_t bmi270_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to define loop */
uint8_t loop;
/* Variable to get the status of advance power save */
uint8_t aps_stat = 0;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (sens_cfg != NULL))
{
/* Get status of advance power save mode */
aps_stat = dev->aps_status;
for (loop = 0; loop < n_sens; loop++)
{
if ((sens_cfg[loop].type == BMI2_ACCEL) || (sens_cfg[loop].type == BMI2_GYRO) ||
(sens_cfg[loop].type == BMI2_AUX) || (sens_cfg[loop].type == BMI2_GYRO_GAIN_UPDATE))
{
rslt = bmi2_get_sensor_config(&sens_cfg[loop], 1, dev);
}
else
{
/* Disable Advance power save if enabled for auxiliary
* and feature configurations
*/
if ((sens_cfg[loop].type >= BMI2_MAIN_SENS_MAX_NUM) || (sens_cfg[loop].type == BMI2_AUX))
{
if (aps_stat == BMI2_ENABLE)
{
/* Disable advance power save if
* enabled
*/
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev);
}
}
if (rslt == BMI2_OK)
{
rslt = get_feat_config(sens_cfg, loop, dev);
}
/* Return error if any of the get configurations fail */
else
{
break;
}
}
}
/* Enable Advance power save if disabled while configuring and
* not when already disabled
*/
if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK))
{
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev);
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API gets the feature data.
*/
int8_t bmi270_get_feature_data(struct bmi2_feat_sensor_data *feature_data, uint8_t n_sens, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to define loop */
uint8_t loop;
/* Variable to get the status of advance power save */
uint8_t aps_stat = 0;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (feature_data != NULL))
{
/* Get status of advance power save mode */
aps_stat = dev->aps_status;
for (loop = 0; loop < n_sens; loop++)
{
if ((feature_data[loop].type == BMI2_GYRO_GAIN_UPDATE) ||
(feature_data[loop].type == BMI2_GYRO_CROSS_SENSE))
{
rslt = bmi2_get_feature_data(&feature_data[loop], 1, dev);
}
else
{
/* Disable Advance power save if enabled for feature
* configurations
*/
if (feature_data[loop].type >= BMI2_MAIN_SENS_MAX_NUM)
{
if (aps_stat == BMI2_ENABLE)
{
/* Disable advance power save if
* enabled
*/
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev);
}
}
if (rslt == BMI2_OK)
{
switch (feature_data[loop].type)
{
case BMI2_STEP_COUNTER:
/* Get step counter output */
rslt = get_step_counter_output(&feature_data[loop].sens_data.step_counter_output, dev);
break;
case BMI2_STEP_ACTIVITY:
/* Get step activity output */
rslt = get_step_activity_output(&feature_data[loop].sens_data.activity_output, dev);
break;
case BMI2_NVM_STATUS:
/* Get NVM error status */
rslt = get_nvm_error_status(&feature_data[loop].sens_data.nvm_status, dev);
break;
case BMI2_VFRM_STATUS:
/* Get VFRM error status */
rslt = get_vfrm_error_status(&feature_data[loop].sens_data.vfrm_status, dev);
break;
case BMI2_WRIST_GESTURE:
/* Get wrist gesture status */
rslt = get_wrist_gest_status(&feature_data[loop].sens_data.wrist_gesture_output, dev);
break;
default:
rslt = BMI2_E_INVALID_SENSOR;
break;
}
/* Return error if any of the get sensor data fails */
if (rslt != BMI2_OK)
{
break;
}
}
}
/* Enable Advance power save if disabled while
* configuring and not when already disabled
*/
if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK))
{
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev);
}
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API updates the gyroscope user-gain.
*/
int8_t bmi270_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to select sensor */
uint8_t sens_sel[2] = { BMI2_GYRO, BMI2_GYRO_GAIN_UPDATE };
/* Structure to define sensor configurations */
struct bmi2_sens_config sens_cfg;
/* Variable to store status of user-gain update module */
uint8_t status = 0;
/* Variable to define count */
uint8_t count = 100;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (user_gain != NULL))
{
/* Select type of feature */
sens_cfg.type = BMI2_GYRO_GAIN_UPDATE;
/* Get the user gain configurations */
rslt = bmi270_get_sensor_config(&sens_cfg, 1, dev);
if (rslt == BMI2_OK)
{
/* Get the user-defined ratio */
sens_cfg.cfg.gyro_gain_update = *user_gain;
/* Set rate ratio for all axes */
rslt = bmi270_set_sensor_config(&sens_cfg, 1, dev);
}
/* Disable gyroscope */
if (rslt == BMI2_OK)
{
rslt = bmi270_sensor_disable(&sens_sel[0], 1, dev);
}
/* Enable gyroscope user-gain update module */
if (rslt == BMI2_OK)
{
rslt = bmi270_sensor_enable(&sens_sel[1], 1, dev);
}
/* Set the command to trigger the computation */
if (rslt == BMI2_OK)
{
rslt = bmi2_set_command_register(BMI2_USR_GAIN_CMD, dev);
}
if (rslt == BMI2_OK)
{
/* Poll until enable bit of user-gain update is 0 */
while (count--)
{
rslt = get_user_gain_upd_status(&status, dev);
if ((rslt == BMI2_OK) && (status == 0))
{
/* Enable compensation of gain defined
* in the GAIN register
*/
rslt = enable_gyro_gain(BMI2_ENABLE, dev);
/* Enable gyroscope */
if (rslt == BMI2_OK)
{
rslt = bmi270_sensor_enable(&sens_sel[0], 1, dev);
}
break;
}
dev->delay_us(10000, dev->intf_ptr);
}
/* Return error if user-gain update is failed */
if ((rslt == BMI2_OK) && (status != 0))
{
rslt = BMI2_E_GYR_USER_GAIN_UPD_FAIL;
}
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API reads the compensated gyroscope user-gain values.
*/
int8_t bmi270_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to define register data */
uint8_t reg_data[3] = { 0 };
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (gyr_usr_gain != NULL))
{
/* Get the gyroscope compensated gain values */
rslt = bmi2_get_regs(BMI2_GYR_USR_GAIN_0_ADDR, reg_data, 3, dev);
if (rslt == BMI2_OK)
{
/* Gyroscope user gain correction X-axis */
gyr_usr_gain->x = (int8_t)BMI2_GET_BIT_POS0(reg_data[0], BMI2_GYR_USR_GAIN_X);
/* Gyroscope user gain correction Y-axis */
gyr_usr_gain->y = (int8_t)BMI2_GET_BIT_POS0(reg_data[1], BMI2_GYR_USR_GAIN_Y);
/* Gyroscope user gain correction z-axis */
gyr_usr_gain->z = (int8_t)BMI2_GET_BIT_POS0(reg_data[2], BMI2_GYR_USR_GAIN_Z);
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API maps/unmaps feature interrupts to that of interrupt pins.
*/
int8_t bmi270_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to define loop */
uint8_t loop;
/* Null-pointer check */
rslt = null_ptr_check(dev);
if ((rslt == BMI2_OK) && (sens_int != NULL))
{
for (loop = 0; loop < n_sens; loop++)
{
switch (sens_int[loop].type)
{
case BMI2_SIG_MOTION:
case BMI2_WRIST_GESTURE:
case BMI2_ANY_MOTION:
case BMI2_NO_MOTION:
case BMI2_STEP_COUNTER:
case BMI2_STEP_DETECTOR:
case BMI2_STEP_ACTIVITY:
case BMI2_WRIST_WEAR_WAKE_UP:
rslt = bmi2_map_feat_int(sens_int[loop].type, sens_int[loop].hw_int_pin, dev);
break;
default:
rslt = BMI2_E_INVALID_SENSOR;
break;
}
/* Return error if interrupt mapping fails */
if (rslt != BMI2_OK)
{
break;
}
}
}
else
{
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/***************************************************************************/
/*! Local Function Definitions
****************************************************************************/
/*!
* @brief This internal API is used to validate the device structure pointer for
* null conditions.
*/
static int8_t null_ptr_check(const struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
if ((dev == NULL) || (dev->read == NULL) || (dev->write == NULL) || (dev->delay_us == NULL))
{
/* Device structure pointer is not valid */
rslt = BMI2_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This internal API selects the sensor/features to be enabled or
* disabled.
*/
static int8_t select_sensor(const uint8_t *sens_list, uint8_t n_sens, uint64_t *sensor_sel)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
/* Variable to define loop */
uint8_t count;
for (count = 0; count < n_sens; count++)
{
switch (sens_list[count])
{
case BMI2_ACCEL:
*sensor_sel |= BMI2_ACCEL_SENS_SEL;
break;
case BMI2_GYRO:
*sensor_sel |= BMI2_GYRO_SENS_SEL;
break;
case BMI2_AUX:
*sensor_sel |= BMI2_AUX_SENS_SEL;
break;
case BMI2_TEMP:
*sensor_sel |= BMI2_TEMP_SENS_SEL;
break;
case BMI2_SIG_MOTION:
*sensor_sel |= BMI2_SIG_MOTION_SEL;
break;
case BMI2_ANY_MOTION:
*sensor_sel |= BMI2_ANY_MOT_SEL;
break;
case BMI2_NO_MOTION:
*sensor_sel |= BMI2_NO_MOT_SEL;
break;
case BMI2_STEP_DETECTOR:
*sensor_sel |= BMI2_STEP_DETECT_SEL;
break;
case BMI2_STEP_COUNTER:
*sensor_sel |= BMI2_STEP_COUNT_SEL;
break;
case BMI2_STEP_ACTIVITY:
*sensor_sel |= BMI2_STEP_ACT_SEL;
break;
case BMI2_GYRO_GAIN_UPDATE:
*sensor_sel |= BMI2_GYRO_GAIN_UPDATE_SEL;
break;
case BMI2_GYRO_SELF_OFF:
*sensor_sel |= BMI2_GYRO_SELF_OFF_SEL;
break;
case BMI2_WRIST_GESTURE:
*sensor_sel |= BMI2_WRIST_GEST_SEL;
break;
case BMI2_WRIST_WEAR_WAKE_UP:
*sensor_sel |= BMI2_WRIST_WEAR_WAKE_UP_SEL;
break;
default:
rslt = BMI2_E_INVALID_SENSOR;
break;
}
}
return rslt;
}
/*!
* @brief This internal API enables the selected sensor/features.
*/
static int8_t sensor_enable(uint64_t sensor_sel, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to get the status of advance power save */
uint8_t aps_stat = 0;
rslt = enable_main_sensors(sensor_sel, dev);
if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS)))
{
/* Get status of advance power save mode */
aps_stat = dev->aps_status;
if (aps_stat == BMI2_ENABLE)
{
/* Disable advance power save if enabled */
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev);
}
if (rslt == BMI2_OK)
{
rslt = enable_sensor_features(sensor_sel, dev);
/* Enable Advance power save if disabled while
* configuring and not when already disabled
*/
if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK))
{
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev);
}
}
}
return rslt;
}
/*!
* @brief This internal API disables the selected sensors/features.
*/
static int8_t sensor_disable(uint64_t sensor_sel, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to get the status of advance power save */
uint8_t aps_stat = 0;
rslt = disable_main_sensors(sensor_sel, dev);
if ((rslt == BMI2_OK) && (sensor_sel & ~(BMI2_MAIN_SENSORS)))
{
/* Get status of advance power save mode */
aps_stat = dev->aps_status;
if (aps_stat == BMI2_ENABLE)
{
/* Disable advance power save if enabled */
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev);
}
if (rslt == BMI2_OK)
{
rslt = disable_sensor_features(sensor_sel, dev);
/* Enable Advance power save if disabled while
* configuring and not when already disabled
*/
if ((aps_stat == BMI2_ENABLE) && (rslt == BMI2_OK))
{
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev);
}
}
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable any motion feature.
*/
static int8_t set_any_motion(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for any-motion */
struct bmi2_feature_config any_mot_config = { 0, 0, 0 };
/* Search for any-motion feature and extract its configurations details */
feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where any-motion feature resides */
rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of any-motion axes */
idx = any_mot_config.start_addr + BMI2_ANY_MOT_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_ANY_MOT_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_ANY_MOT_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable no-motion feature.
*/
static int8_t set_no_motion(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for no-motion */
struct bmi2_feature_config no_mot_config = { 0, 0, 0 };
/* Search for no-motion feature and extract its configurations details */
feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where any/no-motion feature resides */
rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of no-motion axes */
idx = no_mot_config.start_addr + BMI2_NO_MOT_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_ANY_NO_MOT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_NO_MOT_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_NO_MOT_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable step detector feature.
*/
static int8_t set_step_detector(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for step detector */
struct bmi2_feature_config step_det_config = { 0, 0, 0 };
/* Search for step detector feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_det_config, BMI2_STEP_DETECTOR, dev);
if (feat_found)
{
/* Get the configuration from the page where step detector feature resides */
rslt = bmi2_get_feat_config(step_det_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of step detector */
idx = step_det_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_DET_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_STEP_DETECT_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_STEP_DETECT_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable step counter feature.
*/
static int8_t set_step_counter(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for step counter */
struct bmi2_feature_config step_count_config = { 0, 0, 0 };
/* Search for step counter feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev);
if (feat_found)
{
/* Get the configuration from the page where step-counter feature resides */
rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of step counter */
idx = step_count_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_COUNT_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_STEP_COUNT_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_STEP_COUNT_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable sig-motion feature.
*/
static int8_t set_sig_motion(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for sig-motion */
struct bmi2_feature_config sig_mot_config = { 0, 0, 0 };
/* Search for sig-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where sig-motion feature resides */
rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of sig-motion */
idx = sig_mot_config.start_addr + BMI2_SIG_MOT_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BIT_POS0(feat_config[idx], BMI2_SIG_MOT_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_SIG_MOTION_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_SIG_MOTION_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable step activity detection.
*/
static int8_t set_step_activity(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for step activity */
struct bmi2_feature_config step_act_config = { 0, 0, 0 };
/* Search for step activity feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_act_config, BMI2_STEP_ACTIVITY, dev);
if (feat_found)
{
/* Get the configuration from the page where step-activity
* feature resides
*/
rslt = bmi2_get_feat_config(step_act_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of step activity */
idx = step_act_config.start_addr + BMI2_STEP_COUNT_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_STEP_ACT_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_STEP_ACT_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_STEP_ACT_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gives an option to enable self-offset correction
* feature of gyroscope, either internally or by the host.
*/
static int8_t set_gyro_self_offset_corr(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for self-offset correction */
struct bmi2_feature_config self_off_corr_cfg = { 0, 0, 0 };
/* Search for self-offset correction and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&self_off_corr_cfg, BMI2_GYRO_SELF_OFF, dev);
if (feat_found)
{
/* Get the configuration from the page where self-offset
* correction feature resides
*/
rslt = bmi2_get_feat_config(self_off_corr_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of self-offset correction */
idx = self_off_corr_cfg.start_addr;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_SELF_OFF_CORR_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_GYRO_SELF_OFF_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_GYRO_SELF_OFF_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API enables the wrist gesture feature.
*/
static int8_t set_wrist_gesture(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for wrist gesture */
struct bmi2_feature_config wrist_gest_cfg = { 0, 0, 0 };
/* Search for wrist gesture and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&wrist_gest_cfg, BMI2_WRIST_GESTURE, dev);
if (feat_found)
{
/* Get the configuration from the page where wrist gesture feature resides */
rslt = bmi2_get_feat_config(wrist_gest_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of wrist gesture */
idx = wrist_gest_cfg.start_addr;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_GEST_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_WRIST_GEST_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_WRIST_GEST_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API enables the wrist wear wake up feature.
*/
static int8_t set_wrist_wear_wake_up(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for wrist wear wake up */
struct bmi2_feature_config wrist_wake_up_cfg = { 0, 0, 0 };
/* Search for wrist wear wake up and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_cfg, BMI2_WRIST_WEAR_WAKE_UP, dev);
if (feat_found)
{
/* Get the configuration from the page where wrist wear wake up
* feature resides
*/
rslt = bmi2_get_feat_config(wrist_wake_up_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of wrist wear wake up */
idx = wrist_wake_up_cfg.start_addr;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_WRIST_WEAR_WAKE_UP_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_WRIST_WEAR_WAKE_UP_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_WRIST_WEAR_WAKE_UP_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to enable/disable gyroscope user gain
* feature.
*/
static int8_t set_gyro_user_gain(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for gyroscope user gain */
struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 };
/* Search for user gain feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev);
if (feat_found)
{
/* Get the configuration from the page where user gain feature resides */
rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of user gain */
idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET;
/* Set the feature enable bit */
feat_config[idx] = BMI2_SET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN, enable);
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
if ((rslt == BMI2_OK) && (enable == BMI2_ENABLE))
{
dev->sens_en_stat |= BMI2_GYRO_GAIN_UPDATE_SEL;
}
else
{
dev->sens_en_stat &= ~BMI2_GYRO_GAIN_UPDATE_SEL;
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API sets any-motion configurations like axes select,
* duration, threshold and output-configuration.
*/
static int8_t set_any_motion_config(const struct bmi2_any_motion_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define count */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for any motion */
struct bmi2_feature_config any_mot_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for any-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where any-motion feature resides */
rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for any-motion select */
idx = any_mot_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Set duration */
*(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration);
/* Set x-select */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x);
/* Set y-select */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y);
/* Set z-select */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z);
/* Increment offset by 1 word to set threshold and output configuration */
idx++;
/* Set threshold */
*(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold);
/* Increment offset by 1 more word to get the total length in words */
idx++;
/* Get total length in bytes to copy from local pointer to the array */
idx = (uint8_t)(idx * 2) - any_mot_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < idx; index++)
{
feat_config[any_mot_config.start_addr +
index] = *((uint8_t *) data_p + any_mot_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API sets no-motion configurations like axes select,
* duration, threshold and output-configuration.
*/
static int8_t set_no_motion_config(const struct bmi2_no_motion_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define count */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for no-motion */
struct bmi2_feature_config no_mot_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for no-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where no-motion feature resides */
rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for no-motion select */
idx = no_mot_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Set duration */
*(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_DUR, config->duration);
/* Set x-select */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_X_SEL, config->select_x);
/* Set y-select */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Y_SEL, config->select_y);
/* Set z-select */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_ANY_NO_MOT_Z_SEL, config->select_z);
/* Increment offset by 1 word to set threshold and output configuration */
idx++;
/* Set threshold */
*(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_ANY_NO_MOT_THRES, config->threshold);
/* Increment offset by 1 more word to get the total length in words */
idx++;
/* Get total length in bytes to copy from local pointer to the array */
idx = (uint8_t)(idx * 2) - no_mot_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < idx; index++)
{
feat_config[no_mot_config.start_addr +
index] = *((uint8_t *) data_p + no_mot_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API sets sig-motion configurations like block-size,
* output-configuration and other parameters.
*/
static int8_t set_sig_motion_config(const struct bmi2_sig_motion_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define index */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for sig-motion */
struct bmi2_feature_config sig_mot_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for sig-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where sig-motion feature resides */
rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for sig-motion select */
idx = sig_mot_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Set parameter 1 */
*(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_SIG_MOT_PARAM_1, config->block_size);
/* Increment offset by 1 more word to get the total length in words */
idx++;
/* Get total length in bytes to copy from local pointer to the array */
idx = (uint8_t)(idx * 2) - sig_mot_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < idx; index++)
{
feat_config[sig_mot_config.start_addr +
index] = *((uint8_t *) data_p + sig_mot_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API sets step counter parameter configurations.
*/
static int8_t set_step_count_params_config(const uint16_t *step_count_params, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define index */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for step counter parameters */
struct bmi2_feature_config step_params_config = { 0, 0, 0 };
/* Variable to index the page number */
uint8_t page_idx;
/* Variable to define the start page */
uint8_t start_page;
/* Variable to define start address of the parameters */
uint8_t start_addr;
/* Variable to define number of bytes */
uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2);
/* Variable to store number of pages */
uint8_t n_pages = (n_bytes / 16);
/* Variable to define the end page */
uint8_t end_page;
/* Variable to define the remaining bytes to be read */
uint8_t remain_len;
/* Variable to define the maximum words(16 bytes or 8 words) to be read in a page */
uint8_t max_len = 8;
/* Variable index bytes in a page */
uint8_t page_byte_idx;
/* Variable to index the parameters */
uint8_t param_idx = 0;
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for step counter parameter feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev);
if (feat_found)
{
/* Get the start page for the step counter parameters */
start_page = step_params_config.page;
/* Get the end page for the step counter parameters */
end_page = start_page + n_pages;
/* Get the start address for the step counter parameters */
start_addr = step_params_config.start_addr;
/* Get the remaining length of bytes to be read */
remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr);
for (page_idx = start_page; page_idx <= end_page; page_idx++)
{
/* Get the configuration from the respective page */
rslt = bmi2_get_feat_config(page_idx, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Start from address 0x00 when switched to next page */
if (page_idx > start_page)
{
start_addr = 0;
}
/* Remaining number of words to be read in the page */
if (page_idx == end_page)
{
max_len = (remain_len / 2);
}
/* Get offset in words since all the features are set in words length */
page_byte_idx = start_addr / 2;
for (; page_byte_idx < max_len;)
{
/* Set parameters 1 to 25 */
*(data_p + page_byte_idx) = BMI2_SET_BIT_POS0(*(data_p + page_byte_idx),
BMI2_STEP_COUNT_PARAMS,
step_count_params[param_idx]);
/* Increment offset by 1 word to set to the next parameter */
page_byte_idx++;
/* Increment to next parameter */
param_idx++;
}
/* Get total length in bytes to copy from local pointer to the array */
page_byte_idx = (uint8_t)(page_byte_idx * 2) - step_params_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < page_byte_idx; index++)
{
feat_config[step_params_config.start_addr +
index] = *((uint8_t *) data_p + step_params_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/* @brief This internal API sets step counter configurations like water-mark
* level, reset-counter and output-configuration step detector and activity.
*/
static int8_t set_step_config(const struct bmi2_step_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define index */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for step counter 4 */
struct bmi2_feature_config step_count_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for step counter feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev);
if (feat_found)
{
/* Get the configuration from the page where step counter resides */
rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes */
idx = step_count_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Set water-mark level */
*(data_p + idx) = BMI2_SET_BIT_POS0(*(data_p + idx), BMI2_STEP_COUNT_WM_LEVEL, config->watermark_level);
/* Set reset-counter */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_STEP_COUNT_RST_CNT, config->reset_counter);
/* Increment offset by 1 word to set output
* configuration of step detector and step activity
*/
idx++;
/* Get total length in bytes to copy from local pointer to the array */
idx = (uint8_t)(idx * 2) - step_count_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < idx; index++)
{
feat_config[step_count_config.start_addr +
index] = *((uint8_t *) data_p + step_count_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API sets wrist gesture configurations like wearable-arm,
* and output-configuration.
*/
static int8_t set_wrist_gest_config(const struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define index */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for wrist gesture */
struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for wrist gesture feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE, dev);
if (feat_found)
{
/* Get the configuration from the page where wrist gesture feature resides */
rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for gesture select */
idx = wrist_gest_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Set wearable arm */
*(data_p + idx) = BMI2_SET_BITS(*(data_p + idx), BMI2_WRIST_GEST_WEAR_ARM, config->wearable_arm);
/* Increment offset by 1 more word to set minimum tilt angle (min_flick_peak) */
idx++;
*(data_p + idx) = config->min_flick_peak;
/* Increment offset by 1 more word to set min_flick_samples */
idx++;
*(data_p + idx) = config->min_flick_samples;
/* Increment offset by 1 more word to set max time within gesture moment has to be completed */
idx++;
*(data_p + idx) = config->max_duration;
/* Increment offset by 1 more word to get the total length in words */
idx++;
/* Get total length in bytes to copy from local pointer to the array */
idx = (uint8_t)(idx * 2) - wrist_gest_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < idx; index++)
{
feat_config[wrist_gest_config.start_addr +
index] = *((uint8_t *) data_p + wrist_gest_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API sets wrist wear wake-up configurations like
* output-configuration.
*/
static int8_t set_wrist_wear_wake_up_config(const struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define index */
uint8_t index = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for wrist wear wake-up */
struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for wrist wear wake-up feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP, dev);
if (feat_found)
{
/* Get the configuration from the page where wrist wear wake-up feature resides */
rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for wrist wear wake-up select */
idx = wrist_wake_up_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Increment offset by 1 more word to set min_angle_focus */
idx++;
*(data_p + idx) = config->min_angle_focus;
/* Increment offset by 1 more word to set min_angle_nonfocus */
idx++;
*(data_p + idx) = config->min_angle_nonfocus;
/* Increment offset by 1 more word to set max_tilt_lr */
idx++;
*(data_p + idx) = config->max_tilt_lr;
/* Increment offset by 1 more word to set max_tilt_ll */
idx++;
*(data_p + idx) = config->max_tilt_ll;
/* Increment offset by 1 more word to set max_tilt_pd */
idx++;
*(data_p + idx) = config->max_tilt_pd;
/* Increment offset by 1 more word to set max_tilt_pu */
idx++;
*(data_p + idx) = config->max_tilt_pu;
/* Increment offset by 1 more word to get the total length in words */
idx++;
/* Get total length in bytes to copy from local pointer to the array */
idx = (uint8_t)(idx * 2) - wrist_wake_up_config.start_addr;
/* Copy the bytes to be set back to the array */
for (index = 0; index < idx; index++)
{
feat_config[wrist_wake_up_config.start_addr +
index] = *((uint8_t *) data_p + wrist_wake_up_config.start_addr + index);
}
/* Set the configuration back to the page */
rslt = bmi2_set_regs(BMI2_FEATURES_REG_ADDR, feat_config, BMI2_FEAT_SIZE_IN_BYTES, dev);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets any-motion configurations like axes select,
* duration, threshold and output-configuration.
*/
static int8_t get_any_motion_config(struct bmi2_any_motion_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define LSB */
uint16_t lsb;
/* Variable to define MSB */
uint16_t msb;
/* Variable to define a word */
uint16_t lsb_msb;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for any-motion */
struct bmi2_feature_config any_mot_config = { 0, 0, 0 };
/* Search for any-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&any_mot_config, BMI2_ANY_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where any-motion feature resides */
rslt = bmi2_get_feat_config(any_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for feature enable for any-motion */
idx = any_mot_config.start_addr;
/* Get word to calculate duration, x, y and z select */
lsb = (uint16_t) feat_config[idx++];
msb = ((uint16_t) feat_config[idx++] << 8);
lsb_msb = lsb | msb;
/* Get duration */
config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK;
/* Get x-select */
config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS;
/* Get y-select */
config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS;
/* Get z-select */
config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS;
/* Get word to calculate threshold, output configuration from the same word */
lsb = (uint16_t) feat_config[idx++];
msb = ((uint16_t) feat_config[idx++] << 8);
lsb_msb = lsb | msb;
/* Get threshold */
config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK;
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets no-motion configurations like axes select,
* duration, threshold and output-configuration.
*/
static int8_t get_no_motion_config(struct bmi2_no_motion_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define a word */
uint16_t lsb_msb = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for no-motion */
struct bmi2_feature_config no_mot_config = { 0, 0, 0 };
/* Search for no-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&no_mot_config, BMI2_NO_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where no-motion feature resides */
rslt = bmi2_get_feat_config(no_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for feature enable for no-motion */
idx = no_mot_config.start_addr;
/* Get word to calculate duration, x, y and z select */
lsb = (uint16_t) feat_config[idx++];
msb = ((uint16_t) feat_config[idx++] << 8);
lsb_msb = lsb | msb;
/* Get duration */
config->duration = lsb_msb & BMI2_ANY_NO_MOT_DUR_MASK;
/* Get x-select */
config->select_x = (lsb_msb & BMI2_ANY_NO_MOT_X_SEL_MASK) >> BMI2_ANY_NO_MOT_X_SEL_POS;
/* Get y-select */
config->select_y = (lsb_msb & BMI2_ANY_NO_MOT_Y_SEL_MASK) >> BMI2_ANY_NO_MOT_Y_SEL_POS;
/* Get z-select */
config->select_z = (lsb_msb & BMI2_ANY_NO_MOT_Z_SEL_MASK) >> BMI2_ANY_NO_MOT_Z_SEL_POS;
/* Get word to calculate threshold, output configuration from the same word */
lsb = (uint16_t) feat_config[idx++];
msb = ((uint16_t) feat_config[idx++] << 8);
lsb_msb = lsb | msb;
/* Get threshold */
config->threshold = lsb_msb & BMI2_ANY_NO_MOT_THRES_MASK;
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets sig-motion configurations like block-size,
* output-configuration and other parameters.
*/
static int8_t get_sig_motion_config(struct bmi2_sig_motion_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define a word */
uint16_t lsb_msb = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration sig-motion */
struct bmi2_feature_config sig_mot_config = { 0, 0, 0 };
/* Search for sig-motion feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&sig_mot_config, BMI2_SIG_MOTION, dev);
if (feat_found)
{
/* Get the configuration from the page where sig-motion feature resides */
rslt = bmi2_get_feat_config(sig_mot_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for feature enable for sig-motion */
idx = sig_mot_config.start_addr;
/* Get word to calculate parameter 1 */
lsb = (uint16_t) feat_config[idx++];
msb = ((uint16_t) feat_config[idx++] << 8);
lsb_msb = lsb | msb;
/* Get parameter 1 */
config->block_size = lsb_msb & BMI2_SIG_MOT_PARAM_1_MASK;
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets step counter parameter configurations.
*/
static int8_t get_step_count_params_config(uint16_t *step_count_params, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to set flag */
uint8_t feat_found;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define a word */
uint16_t lsb_msb = 0;
/* Initialize feature configuration for step counter 1 */
struct bmi2_feature_config step_params_config = { 0, 0, 0 };
/* Variable to index the page number */
uint8_t page_idx;
/* Variable to define the start page */
uint8_t start_page;
/* Variable to define start address of the parameters */
uint8_t start_addr;
/* Variable to define number of bytes */
uint8_t n_bytes = (BMI2_STEP_CNT_N_PARAMS * 2);
/* Variable to store number of pages */
uint8_t n_pages = (n_bytes / 16);
/* Variable to define the end page */
uint8_t end_page;
/* Variable to define the remaining bytes to be read */
uint8_t remain_len;
/* Variable to define the maximum words to be read in a page */
uint8_t max_len = BMI2_FEAT_SIZE_IN_BYTES;
/* Variable index bytes in a page */
uint8_t page_byte_idx;
/* Variable to index the parameters */
uint8_t param_idx = 0;
/* Search for step counter parameter feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_params_config, BMI2_STEP_COUNTER_PARAMS, dev);
if (feat_found)
{
/* Get the start page for the step counter parameters */
start_page = step_params_config.page;
/* Get the end page for the step counter parameters */
end_page = start_page + n_pages;
/* Get the start address for the step counter parameters */
start_addr = step_params_config.start_addr;
/* Get the remaining length of bytes to be read */
remain_len = (uint8_t)((n_bytes - (n_pages * 16)) + start_addr);
for (page_idx = start_page; page_idx <= end_page; page_idx++)
{
/* Get the configuration from the respective page */
rslt = bmi2_get_feat_config(page_idx, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Start from address 0x00 when switched to next page */
if (page_idx > start_page)
{
start_addr = 0;
}
/* Remaining number of bytes to be read in the page */
if (page_idx == end_page)
{
max_len = remain_len;
}
/* Get the offset */
page_byte_idx = start_addr;
while (page_byte_idx < max_len)
{
/* Get word to calculate the parameter*/
lsb = (uint16_t) feat_config[page_byte_idx++];
if (page_byte_idx < max_len)
{
msb = ((uint16_t) feat_config[page_byte_idx++] << 8);
}
lsb_msb = lsb | msb;
/* Get parameters 1 to 25 */
step_count_params[param_idx] = lsb_msb & BMI2_STEP_COUNT_PARAMS_MASK;
/* Increment to next parameter */
param_idx++;
}
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets step counter/detector/activity configurations.
*/
static int8_t get_step_config(struct bmi2_step_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define a word */
uint16_t lsb_msb = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for step counter */
struct bmi2_feature_config step_count_config = { 0, 0, 0 };
/* Search for step counter 4 feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&step_count_config, BMI2_STEP_COUNTER, dev);
if (feat_found)
{
/* Get the configuration from the page where step counter 4 parameter resides */
rslt = bmi2_get_feat_config(step_count_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for feature enable for step counter/detector/activity */
idx = step_count_config.start_addr;
/* Get word to calculate water-mark level and reset counter */
lsb = (uint16_t) feat_config[idx++];
msb = ((uint16_t) feat_config[idx++] << 8);
lsb_msb = lsb | msb;
/* Get water-mark level */
config->watermark_level = lsb_msb & BMI2_STEP_COUNT_WM_LEVEL_MASK;
/* Get reset counter */
config->reset_counter = (lsb_msb & BMI2_STEP_COUNT_RST_CNT_MASK) >> BMI2_STEP_COUNT_RST_CNT_POS;
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets wrist gesture configurations like wearable-arm,
* and output-configuration.
*/
static int8_t get_wrist_gest_config(struct bmi2_wrist_gest_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for wrist gesture */
struct bmi2_feature_config wrist_gest_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for wrist gesture feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&wrist_gest_config, BMI2_WRIST_GESTURE, dev);
if (feat_found)
{
/* Get the configuration from the page where wrist gesture feature resides */
rslt = bmi2_get_feat_config(wrist_gest_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for wrist gesture select */
idx = wrist_gest_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Get wearable arm */
config->wearable_arm = (*(data_p + idx) & BMI2_WRIST_GEST_WEAR_ARM_MASK) >> BMI2_WRIST_GEST_WEAR_ARM_POS;
/* Increment the offset by 1 word to get min_flick_peak */
idx++;
config->min_flick_peak = *(data_p + idx);
/* Increment the offset by 1 word to get min_flick_samples */
idx++;
config->min_flick_samples = *(data_p + idx);
/* Increment the offset by 1 word to get max_duration */
idx++;
config->max_duration = *(data_p + idx);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets wrist wear wake-up configurations like
* output-configuration.
*/
static int8_t get_wrist_wear_wake_up_config(struct bmi2_wrist_wear_wake_up_config *config, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature configuration for wrist wear wake-up */
struct bmi2_feature_config wrist_wake_up_config = { 0, 0, 0 };
/* Copy the feature configuration address to a local pointer */
uint16_t *data_p = (uint16_t *) (void *)feat_config;
/* Search for wrist wear wake-up feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&wrist_wake_up_config, BMI2_WRIST_WEAR_WAKE_UP, dev);
if (feat_found)
{
/* Get the configuration from the page where wrist wear wake-up feature resides */
rslt = bmi2_get_feat_config(wrist_wake_up_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for wrist wear wake-up select */
idx = wrist_wake_up_config.start_addr;
/* Get offset in words since all the features are set in words length */
idx = idx / 2;
/* Increment the offset value by 1 word to get min_angle_focus */
idx++;
config->min_angle_focus = *(data_p + idx);
/* Increment the offset value by 1 word to get min_angle_nonfocus */
idx++;
config->min_angle_nonfocus = *(data_p + idx);
/* Increment the offset value by 1 word to get max_tilt_lr */
idx++;
config->max_tilt_lr = *(data_p + idx);
/* Increment the offset value by 1 word to get max_tilt_ll */
idx++;
config->max_tilt_ll = *(data_p + idx);
/* Increment the offset value by 1 word to get max_tilt_pd */
idx++;
config->max_tilt_pd = *(data_p + idx);
/* Increment the offset value by 1 word to get max_tilt_pu */
idx++;
config->max_tilt_pu = *(data_p + idx);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets the output values of the wrist gesture.
*/
static int8_t get_wrist_gest_status(uint8_t *wrist_gest, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variables to define index */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature output for wrist gesture */
struct bmi2_feature_config wrist_gest_out_config = { 0, 0, 0 };
/* Search for wrist gesture feature and extract its configuration details */
feat_found = extract_output_feat_config(&wrist_gest_out_config, BMI2_WRIST_GESTURE, dev);
if (feat_found)
{
/* Get the feature output configuration for wrist gesture */
rslt = bmi2_get_feat_config(wrist_gest_out_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for wrist gesture output */
idx = wrist_gest_out_config.start_addr;
/* Get the wrist gesture output */
*wrist_gest = feat_config[idx];
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets the output values of step counter.
*/
static int8_t get_step_counter_output(uint32_t *step_count, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variables to define index */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature output for step counter */
struct bmi2_feature_config step_cnt_out_config = { 0, 0, 0 };
/* Search for step counter output feature and extract its configuration details */
feat_found = extract_output_feat_config(&step_cnt_out_config, BMI2_STEP_COUNTER, dev);
if (feat_found)
{
/* Get the feature output configuration for step-counter */
rslt = bmi2_get_feat_config(step_cnt_out_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for step counter output */
idx = step_cnt_out_config.start_addr;
/* Get the step counter output in 4 bytes */
*step_count = (uint32_t) feat_config[idx++];
*step_count |= ((uint32_t) feat_config[idx++] << 8);
*step_count |= ((uint32_t) feat_config[idx++] << 16);
*step_count |= ((uint32_t) feat_config[idx++] << 24);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets the error status related to NVM.
*/
static int8_t get_nvm_error_status(struct bmi2_nvm_err_status *nvm_err_stat, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variables to define index */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature output for NVM error status */
struct bmi2_feature_config nvm_err_cfg = { 0, 0, 0 };
/* Search for NVM error status feature and extract its configuration details */
feat_found = extract_output_feat_config(&nvm_err_cfg, BMI2_NVM_STATUS, dev);
if (feat_found)
{
/* Get the feature output configuration for NVM error status */
rslt = bmi2_get_feat_config(nvm_err_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for NVM error status */
idx = nvm_err_cfg.start_addr;
/* Increment index to get the error status */
idx++;
/* Error when NVM load action fails */
nvm_err_stat->load_error = BMI2_GET_BIT_POS0(feat_config[idx], BMI2_NVM_LOAD_ERR_STATUS);
/* Error when NVM program action fails */
nvm_err_stat->prog_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PROG_ERR_STATUS);
/* Error when NVM erase action fails */
nvm_err_stat->erase_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_ERASE_ERR_STATUS);
/* Error when NVM program limit is exceeded */
nvm_err_stat->exceed_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_END_EXCEED_STATUS);
/* Error when NVM privilege mode is not acquired */
nvm_err_stat->privil_error = BMI2_GET_BITS(feat_config[idx], BMI2_NVM_PRIV_ERR_STATUS);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API is used to get enable status of gyroscope user gain
* update.
*/
static int8_t get_user_gain_upd_status(uint8_t *status, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variable to define the array offset */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Variable to check APS status */
uint8_t aps_stat = 0;
/* Initialize feature configuration for gyroscope user gain */
struct bmi2_feature_config gyr_user_gain_cfg = { 0, 0, 0 };
/* Search for user gain feature and extract its configuration details */
feat_found = bmi2_extract_input_feat_config(&gyr_user_gain_cfg, BMI2_GYRO_GAIN_UPDATE, dev);
if (feat_found)
{
/* Disable advance power save */
aps_stat = dev->aps_status;
if (aps_stat == BMI2_ENABLE)
{
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, dev);
}
if (rslt == BMI2_OK)
{
/* Get the configuration from the page where user gain feature resides */
rslt = bmi2_get_feat_config(gyr_user_gain_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset for enable/disable of user gain */
idx = gyr_user_gain_cfg.start_addr + BMI2_GYR_USER_GAIN_FEAT_EN_OFFSET;
/* Set the feature enable status */
*status = BMI2_GET_BITS(feat_config[idx], BMI2_GYR_USER_GAIN_FEAT_EN);
}
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
/* Enable Advance power save if disabled while configuring and not when already disabled */
if ((rslt == BMI2_OK) && (aps_stat == BMI2_ENABLE))
{
rslt = bmi2_set_adv_power_save(BMI2_ENABLE, dev);
}
return rslt;
}
/*!
* @brief This internal API gets the output values of step activity.
*/
static int8_t get_step_activity_output(uint8_t *step_act, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variables to define index */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature output for step activity */
struct bmi2_feature_config step_act_out_config = { 0, 0, 0 };
/* Search for step activity output feature and extract its configuration details */
feat_found = extract_output_feat_config(&step_act_out_config, BMI2_STEP_ACTIVITY, dev);
if (feat_found)
{
/* Get the feature output configuration for step-activity */
rslt = bmi2_get_feat_config(step_act_out_config.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for step activity output */
idx = step_act_out_config.start_addr;
/* Get the step activity output */
*step_act = feat_config[idx];
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API gets the error status related to virtual frames.
*/
static int8_t get_vfrm_error_status(struct bmi2_vfrm_err_status *vfrm_err_stat, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Array to define the feature configuration */
uint8_t feat_config[BMI2_FEAT_SIZE_IN_BYTES] = { 0 };
/* Variables to define index */
uint8_t idx = 0;
/* Variable to set flag */
uint8_t feat_found;
/* Initialize feature output for VFRM error status */
struct bmi2_feature_config vfrm_err_cfg = { 0, 0, 0 };
/* Search for VFRM error status feature and extract its configuration details */
feat_found = extract_output_feat_config(&vfrm_err_cfg, BMI2_VFRM_STATUS, dev);
if (feat_found)
{
/* Get the feature output configuration for VFRM error status */
rslt = bmi2_get_feat_config(vfrm_err_cfg.page, feat_config, dev);
if (rslt == BMI2_OK)
{
/* Define the offset in bytes for VFRM error status */
idx = vfrm_err_cfg.start_addr;
/* Increment index to get the error status */
idx++;
/* Internal error while acquiring lock for FIFO */
vfrm_err_stat->lock_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_LOCK_ERR_STATUS);
/* Internal error while writing byte into FIFO */
vfrm_err_stat->write_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_WRITE_ERR_STATUS);
/* Internal error while writing into FIFO */
vfrm_err_stat->fatal_error = BMI2_GET_BITS(feat_config[idx], BMI2_VFRM_FATAL_ERR_STATUS);
}
}
else
{
rslt = BMI2_E_INVALID_SENSOR;
}
return rslt;
}
/*!
* @brief This internal API enables/disables compensation of the gain defined
* in the GAIN register.
*/
static int8_t enable_gyro_gain(uint8_t enable, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to define register data */
uint8_t reg_data = 0;
rslt = bmi2_get_regs(BMI2_GYR_OFF_COMP_6_ADDR, &reg_data, 1, dev);
if (rslt == BMI2_OK)
{
reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_GAIN_EN, enable);
rslt = bmi2_set_regs(BMI2_GYR_OFF_COMP_6_ADDR, &reg_data, 1, dev);
}
return rslt;
}
/*!
* @brief This internal API is used to extract the output feature configuration
* details from the look-up table.
*/
static uint8_t extract_output_feat_config(struct bmi2_feature_config *feat_output,
uint8_t type,
const struct bmi2_dev *dev)
{
/* Variable to define loop */
uint8_t loop = 0;
/* Variable to set flag */
uint8_t feat_found = BMI2_FALSE;
/* Search for the output feature from the output configuration array */
while (loop < dev->out_sens)
{
if (dev->feat_output[loop].type == type)
{
*feat_output = dev->feat_output[loop];
feat_found = BMI2_TRUE;
break;
}
loop++;
}
/* Return flag */
return feat_found;
}
/*!
* @brief This internal API sets feature configuration to the sensor.
*/
static int8_t set_feat_config(const struct bmi2_sens_config *sens_cfg, uint8_t loop, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
switch (sens_cfg[loop].type)
{
/* Set any motion configuration */
case BMI2_ANY_MOTION:
rslt = set_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev);
break;
/* Set no motion configuration */
case BMI2_NO_MOTION:
rslt = set_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev);
break;
/* Set sig-motion configuration */
case BMI2_SIG_MOTION:
rslt = set_sig_motion_config(&sens_cfg[loop].cfg.sig_motion, dev);
break;
/* Set the step counter parameters */
case BMI2_STEP_COUNTER_PARAMS:
rslt = set_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev);
break;
/* Set step counter/detector/activity configuration */
case BMI2_STEP_DETECTOR:
case BMI2_STEP_COUNTER:
case BMI2_STEP_ACTIVITY:
rslt = set_step_config(&sens_cfg[loop].cfg.step_counter, dev);
break;
/* Set the wrist gesture configuration */
case BMI2_WRIST_GESTURE:
rslt = set_wrist_gest_config(&sens_cfg[loop].cfg.wrist_gest, dev);
break;
/* Set the wrist wear wake-up configuration */
case BMI2_WRIST_WEAR_WAKE_UP:
rslt = set_wrist_wear_wake_up_config(&sens_cfg[loop].cfg.wrist_wear_wake_up, dev);
break;
default:
rslt = BMI2_E_INVALID_SENSOR;
break;
}
return rslt;
}
/*!
* @brief This internal API gets feature configuration from the sensor.
*/
static int8_t get_feat_config(struct bmi2_sens_config *sens_cfg, uint8_t loop, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
switch (sens_cfg[loop].type)
{
/* Get sig-motion configuration */
case BMI2_SIG_MOTION:
rslt = get_sig_motion_config(&sens_cfg[loop].cfg.sig_motion, dev);
break;
/* Get any motion configuration */
case BMI2_ANY_MOTION:
rslt = get_any_motion_config(&sens_cfg[loop].cfg.any_motion, dev);
break;
/* Get no motion configuration */
case BMI2_NO_MOTION:
rslt = get_no_motion_config(&sens_cfg[loop].cfg.no_motion, dev);
break;
/* Set the step counter parameters */
case BMI2_STEP_COUNTER_PARAMS:
rslt = get_step_count_params_config(sens_cfg[loop].cfg.step_counter_params, dev);
break;
/* Get step counter/detector/activity configuration */
case BMI2_STEP_DETECTOR:
case BMI2_STEP_COUNTER:
case BMI2_STEP_ACTIVITY:
rslt = get_step_config(&sens_cfg[loop].cfg.step_counter, dev);
break;
/* Get the wrist gesture configuration */
case BMI2_WRIST_GESTURE:
rslt = get_wrist_gest_config(&sens_cfg[loop].cfg.wrist_gest, dev);
break;
/* Get the wrist wear wake-up configuration */
case BMI2_WRIST_WEAR_WAKE_UP:
rslt = get_wrist_wear_wake_up_config(&sens_cfg[loop].cfg.wrist_wear_wake_up, dev);
break;
default:
rslt = BMI2_E_INVALID_SENSOR;
break;
}
return rslt;
}
/*!
* @brief This internal API is used to enable main sensors like accel, gyro, aux and temperature.
*/
static int8_t enable_main_sensors(uint64_t sensor_sel, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to store register values */
uint8_t reg_data;
rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, &reg_data, 1, dev);
if (rslt == BMI2_OK)
{
/* Enable accelerometer */
if (sensor_sel & BMI2_ACCEL_SENS_SEL)
{
reg_data = BMI2_SET_BITS(reg_data, BMI2_ACC_EN, BMI2_ENABLE);
}
/* Enable gyroscope */
if (sensor_sel & BMI2_GYRO_SENS_SEL)
{
reg_data = BMI2_SET_BITS(reg_data, BMI2_GYR_EN, BMI2_ENABLE);
}
/* Enable auxiliary sensor */
if (sensor_sel & BMI2_AUX_SENS_SEL)
{
reg_data = BMI2_SET_BIT_POS0(reg_data, BMI2_AUX_EN, BMI2_ENABLE);
}
/* Enable temperature sensor */
if (sensor_sel & BMI2_TEMP_SENS_SEL)
{
reg_data = BMI2_SET_BITS(reg_data, BMI2_TEMP_EN, BMI2_ENABLE);
}
/* Enable the sensors that are set in the power control register */
if (sensor_sel & BMI2_MAIN_SENSORS)
{
rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, &reg_data, 1, dev);
}
}
return rslt;
}
/*!
* @brief This internal API is used to enable sensor features.
*/
static int8_t enable_sensor_features(uint64_t sensor_sel, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
/* Enable sig-motion feature */
if (sensor_sel & BMI2_SIG_MOTION_SEL)
{
rslt = set_sig_motion(BMI2_ENABLE, dev);
}
/* Enable any motion feature */
if (sensor_sel & BMI2_ANY_MOT_SEL)
{
rslt = set_any_motion(BMI2_ENABLE, dev);
}
/* Enable no motion feature */
if (sensor_sel & BMI2_NO_MOT_SEL)
{
rslt = set_no_motion(BMI2_ENABLE, dev);
}
/* Enable step detector feature */
if (sensor_sel & BMI2_STEP_DETECT_SEL)
{
rslt = set_step_detector(BMI2_ENABLE, dev);
}
/* Enable step counter feature */
if (sensor_sel & BMI2_STEP_COUNT_SEL)
{
rslt = set_step_counter(BMI2_ENABLE, dev);
}
/* Enable step activity feature */
if (sensor_sel & BMI2_STEP_ACT_SEL)
{
rslt = set_step_activity(BMI2_ENABLE, dev);
}
/* Enable gyroscope user gain */
if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL)
{
rslt = set_gyro_user_gain(BMI2_ENABLE, dev);
}
/* Enable gyroscope self-offset correction feature */
if (sensor_sel & BMI2_GYRO_SELF_OFF_SEL)
{
rslt = set_gyro_self_offset_corr(BMI2_ENABLE, dev);
}
/* Enable wrist gesture feature for wearable variant */
if (sensor_sel & BMI2_WRIST_GEST_SEL)
{
rslt = set_wrist_gesture(BMI2_ENABLE, dev);
}
/* Enable wrist wear wake-up feature */
if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_SEL)
{
rslt = set_wrist_wear_wake_up(BMI2_ENABLE, dev);
}
return rslt;
}
/*!
* @brief This internal API is used to disable main sensors like accel, gyro, aux and temperature.
*/
static int8_t disable_main_sensors(uint64_t sensor_sel, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt;
/* Variable to store register values */
uint8_t reg_data;
rslt = bmi2_get_regs(BMI2_PWR_CTRL_ADDR, &reg_data, 1, dev);
if (rslt == BMI2_OK)
{
/* Disable accelerometer */
if (sensor_sel & BMI2_ACCEL_SENS_SEL)
{
reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_ACC_EN);
}
/* Disable gyroscope */
if (sensor_sel & BMI2_GYRO_SENS_SEL)
{
reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_GYR_EN);
}
/* Disable auxiliary sensor */
if (sensor_sel & BMI2_AUX_SENS_SEL)
{
reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_AUX_EN);
}
/* Disable temperature sensor */
if (sensor_sel & BMI2_TEMP_SENS_SEL)
{
reg_data = BMI2_SET_BIT_VAL0(reg_data, BMI2_TEMP_EN);
}
/* Disable the sensors that are set in the power control register */
if (sensor_sel & BMI2_MAIN_SENSORS)
{
rslt = bmi2_set_regs(BMI2_PWR_CTRL_ADDR, &reg_data, 1, dev);
}
}
return rslt;
}
/*!
* @brief This internal API is used to disable sensor features.
*/
static int8_t disable_sensor_features(uint64_t sensor_sel, struct bmi2_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMI2_OK;
/* Disable sig-motion feature */
if (sensor_sel & BMI2_SIG_MOTION_SEL)
{
rslt = set_sig_motion(BMI2_DISABLE, dev);
}
/* Disable any-motion feature */
if (sensor_sel & BMI2_ANY_MOT_SEL)
{
rslt = set_any_motion(BMI2_DISABLE, dev);
}
/* Disable no-motion feature */
if (sensor_sel & BMI2_NO_MOT_SEL)
{
rslt = set_no_motion(BMI2_DISABLE, dev);
}
/* Disable step detector feature */
if (sensor_sel & BMI2_STEP_DETECT_SEL)
{
rslt = set_step_detector(BMI2_DISABLE, dev);
}
/* Disable step counter feature */
if (sensor_sel & BMI2_STEP_COUNT_SEL)
{
rslt = set_step_counter(BMI2_DISABLE, dev);
}
/* Disable step activity feature */
if (sensor_sel & BMI2_STEP_ACT_SEL)
{
rslt = set_step_activity(BMI2_DISABLE, dev);
}
/* Disable gyroscope user gain */
if (sensor_sel & BMI2_GYRO_GAIN_UPDATE_SEL)
{
rslt = set_gyro_user_gain(BMI2_DISABLE, dev);
}
/* Disable gyroscope self-offset correction feature */
if (sensor_sel & BMI2_GYRO_SELF_OFF_SEL)
{
rslt = set_gyro_self_offset_corr(BMI2_DISABLE, dev);
}
/* Disable wrist gesture feature for wearable variant*/
if (sensor_sel & BMI2_WRIST_GEST_SEL)
{
rslt = set_wrist_gesture(BMI2_DISABLE, dev);
}
/* Enable wrist wear wake-up feature */
if (sensor_sel & BMI2_WRIST_WEAR_WAKE_UP_SEL)
{
rslt = set_wrist_wear_wake_up(BMI2_DISABLE, dev);
}
return rslt;
}
/**
* Copyright (c) 2023 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 bmi270.h
* @date 2023-05-03
* @version v2.86.1
*
*/
/**
* \ingroup bmi2xy
* \defgroup bmi270 BMI270
* @brief Sensor driver for BMI270 sensor
*/
#ifndef BMI270_H_
#define BMI270_H_
/*! CPP guard */
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************/
/*! Header files
****************************************************************************/
#include "bmi2.h"
/***************************************************************************/
/*! Macro definitions
****************************************************************************/
/*! @name BMI270 Chip identifier */
#define BMI270_CHIP_ID UINT8_C(0x24)
/*! @name BMI270 feature input start addresses */
#define BMI270_CONFIG_ID_STRT_ADDR UINT8_C(0x00)
#define BMI270_MAX_BURST_LEN_STRT_ADDR UINT8_C(0x02)
#define BMI270_CRT_GYRO_SELF_TEST_STRT_ADDR UINT8_C(0x03)
#define BMI270_ABORT_STRT_ADDR UINT8_C(0x03)
#define BMI270_AXIS_MAP_STRT_ADDR UINT8_C(0x04)
#define BMI270_GYRO_SELF_OFF_STRT_ADDR UINT8_C(0x05)
#define BMI270_NVM_PROG_PREP_STRT_ADDR UINT8_C(0x05)
#define BMI270_GYRO_GAIN_UPDATE_STRT_ADDR UINT8_C(0x06)
#define BMI270_ANY_MOT_STRT_ADDR UINT8_C(0x0C)
#define BMI270_NO_MOT_STRT_ADDR UINT8_C(0x00)
#define BMI270_SIG_MOT_STRT_ADDR UINT8_C(0x04)
#define BMI270_STEP_CNT_1_STRT_ADDR UINT8_C(0x00)
#define BMI270_STEP_CNT_4_STRT_ADDR UINT8_C(0x02)
#define BMI270_WRIST_GEST_STRT_ADDR UINT8_C(0x06)
#define BMI270_WRIST_WEAR_WAKE_UP_STRT_ADDR UINT8_C(0x00)
/*! @name BMI270 feature output start addresses */
#define BMI270_STEP_CNT_OUT_STRT_ADDR UINT8_C(0x00)
#define BMI270_STEP_ACT_OUT_STRT_ADDR UINT8_C(0x04)
#define BMI270_WRIST_GEST_OUT_STRT_ADDR UINT8_C(0x06)
#define BMI270_GYR_USER_GAIN_OUT_STRT_ADDR UINT8_C(0x08)
#define BMI270_GYRO_CROSS_SENSE_STRT_ADDR UINT8_C(0x0C)
#define BMI270_NVM_VFRM_OUT_STRT_ADDR UINT8_C(0x0E)
/*! @name Defines maximum number of pages */
#define BMI270_MAX_PAGE_NUM UINT8_C(8)
/*! @name Defines maximum number of feature input configurations */
#define BMI270_MAX_FEAT_IN UINT8_C(17)
/*! @name Defines maximum number of feature outputs */
#define BMI270_MAX_FEAT_OUT UINT8_C(7)
/*! @name Mask definitions for feature interrupt status bits */
#define BMI270_SIG_MOT_STATUS_MASK UINT8_C(0x01)
#define BMI270_STEP_CNT_STATUS_MASK UINT8_C(0x02)
#define BMI270_STEP_ACT_STATUS_MASK UINT8_C(0x04)
#define BMI270_WRIST_WAKE_UP_STATUS_MASK UINT8_C(0x08)
#define BMI270_WRIST_GEST_STATUS_MASK UINT8_C(0x10)
#define BMI270_NO_MOT_STATUS_MASK UINT8_C(0x20)
#define BMI270_ANY_MOT_STATUS_MASK UINT8_C(0x40)
/*! @name Mask definitions for feature interrupt mapping bits */
#define BMI270_INT_SIG_MOT_MASK UINT8_C(0x01)
#define BMI270_INT_STEP_COUNTER_MASK UINT8_C(0x02)
#define BMI270_INT_STEP_DETECTOR_MASK UINT8_C(0x02)
#define BMI270_INT_STEP_ACT_MASK UINT8_C(0x04)
#define BMI270_INT_WRIST_WEAR_WAKEUP_MASK UINT8_C(0x08)
#define BMI270_INT_WRIST_GEST_MASK UINT8_C(0x10)
#define BMI270_INT_NO_MOT_MASK UINT8_C(0x20)
#define BMI270_INT_ANY_MOT_MASK UINT8_C(0x40)
/*! @name Defines maximum number of feature interrupts */
#define BMI270_MAX_INT_MAP UINT8_C(8)
/***************************************************************************/
/*! BMI270 User Interface function prototypes
****************************************************************************/
/**
* \ingroup bmi270
* \defgroup bmi270ApiInit Initialization
* @brief Initialize the sensor and device structure
*/
/*!
* \ingroup bmi270ApiInit
* \page bmi270_api_bmi270_init bmi270_init
* \code
* int8_t bmi270_init(struct bmi2_dev *dev);
* \endcode
* @details This API:
* 1) updates the device structure with address of the configuration file.
* 2) Initializes BMI270 sensor.
* 3) Writes the configuration file.
* 4) Updates the feature offset parameters in the device structure.
* 5) Updates the maximum number of pages, in the device structure.
*
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_init(struct bmi2_dev *dev);
/**
* \ingroup bmi270
* \defgroup bmi270ApiSensor Feature Set
* @brief Enable / Disable features of the sensor
*/
/*!
* \ingroup bmi270ApiSensor
* \page bmi270_api_bmi270_sensor_enable bmi270_sensor_enable
* \code
* int8_t bmi270_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API selects the sensors/features to be enabled.
*
* @param[in] sens_list : Pointer to select the sensor/feature.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features that can be enabled.
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_ACCEL | 0
* BMI2_GYRO | 1
* BMI2_AUX | 2
* BMI2_SIG_MOTION | 3
* BMI2_ANY_MOTION | 4
* BMI2_NO_MOTION | 5
* BMI2_STEP_DETECTOR | 6
* BMI2_STEP_COUNTER | 7
* BMI2_STEP_ACTIVITY | 8
* BMI2_GYRO_GAIN_UPDATE | 9
* BMI2_WRIST_GESTURE | 19
* BMI2_WRIST_WEAR_WAKE_UP | 20
* BMI2_GYRO_SELF_OFF | 33
*@endverbatim
*
* @note :
* example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO};
* uint8_t n_sens = 2;
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_sensor_enable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
/*!
* \ingroup bmi270ApiSensor
* \page bmi270_api_bmi270_sensor_disable bmi270_sensor_disable
* \code
* int8_t bmi270_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API selects the sensors/features to be disabled.
*
* @param[in] sens_list : Pointer to select the sensor/feature.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features that can be disabled.
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_ACCEL | 0
* BMI2_GYRO | 1
* BMI2_AUX | 2
* BMI2_SIG_MOTION | 3
* BMI2_ANY_MOTION | 4
* BMI2_NO_MOTION | 5
* BMI2_STEP_DETECTOR | 6
* BMI2_STEP_COUNTER | 7
* BMI2_STEP_ACTIVITY | 8
* BMI2_GYRO_GAIN_UPDATE | 9
* BMI2_WRIST_GESTURE | 19
* BMI2_WRIST_WEAR_WAKE_UP | 20
* BMI2_GYRO_SELF_OFF | 33
*@endverbatim
*
* @note :
* example uint8_t sens_list[2] = {BMI2_ACCEL, BMI2_GYRO};
* uint8_t n_sens = 2;
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_sensor_disable(const uint8_t *sens_list, uint8_t n_sens, struct bmi2_dev *dev);
/**
* \ingroup bmi270
* \defgroup bmi270ApiSensorC Sensor Configuration
* @brief Enable / Disable feature configuration of the sensor
*/
/*!
* \ingroup bmi270ApiSensorC
* \page bmi270_api_bmi270_set_sensor_config bmi270_set_sensor_config
* \code
* int8_t bmi270_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API sets the sensor/feature configuration.
*
* @param[in] sens_cfg : Structure instance of bmi2_sens_config.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features that can be configured
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_SIG_MOTION | 3
* BMI2_ANY_MOTION | 4
* BMI2_NO_MOTION | 5
* BMI2_STEP_DETECTOR | 6
* BMI2_STEP_COUNTER | 7
* BMI2_STEP_ACTIVITY | 8
* BMI2_WRIST_GESTURE | 19
* BMI2_WRIST_WEAR_WAKE_UP | 20
* BMI2_STEP_COUNTER_PARAMS | 28
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_set_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
/*!
* \ingroup bmi270ApiSensorC
* \page bmi270_api_bmi270_get_sensor_config bmi270_get_sensor_config
* \code
* int8_t bmi270_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API gets the sensor/feature configuration.
*
* @param[in] sens_cfg : Structure instance of bmi2_sens_config.
* @param[in] n_sens : Number of sensors selected.
* @param[in, out] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features whose configurations can be read.
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_SIG_MOTION | 3
* BMI2_ANY_MOTION | 4
* BMI2_NO_MOTION | 5
* BMI2_STEP_DETECTOR | 6
* BMI2_STEP_COUNTER | 7
* BMI2_STEP_ACTIVITY | 8
* BMI2_WRIST_GESTURE | 19
* BMI2_WRIST_WEAR_WAKE_UP | 20
* BMI2_STEP_COUNTER_PARAMS | 28
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_get_sensor_config(struct bmi2_sens_config *sens_cfg, uint8_t n_sens, struct bmi2_dev *dev);
/**
* \ingroup bmi270
* \defgroup bmi270ApiSensorD Feature Sensor Data
* @brief Get feature sensor data
*/
/*!
* \ingroup bmi270ApiSensorD
* \page bmi270_api_bmi270_get_feature_data bmi270_get_feature_data
* \code
* int8_t bmi270_get_feature_data(struct bmi2_feat_sensor_data *feature_data, uint8_t n_sens, struct bmi2_dev *dev);
* \endcode
* @details This API gets the feature data.
*
* @param[out] feature_data : Structure instance of bmi2_feat_sensor_data.
* @param[in] n_sens : Number of sensors selected.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @note Sensors/features whose data can be read
*
*@verbatim
* sens_list | Values
* ----------------------------|-----------
* BMI2_STEP_COUNTER | 7
* BMI2_STEP_ACTIVITY | 8
* BMI2_WRIST_GESTURE | 19
* BMI2_NVM_STATUS | 38
* BMI2_VFRM_STATUS | 39
*@endverbatim
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_get_feature_data(struct bmi2_feat_sensor_data *feature_data, uint8_t n_sens, struct bmi2_dev *dev);
/**
* \ingroup bmi270
* \defgroup bmi270ApiGyroUG Gyro User Gain
* @brief Set / Get Gyro User Gain of the sensor
*/
/*!
* \ingroup bmi270ApiGyroUG
* \page bmi270_api_bmi270_update_gyro_user_gain bmi270_update_gyro_user_gain
* \code
* int8_t bmi270_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev);
* \endcode
* @details This API updates the gyroscope user-gain.
*
* @param[in] user_gain : Structure that stores user-gain configurations.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_update_gyro_user_gain(const struct bmi2_gyro_user_gain_config *user_gain, struct bmi2_dev *dev);
/*!
* \ingroup bmi270ApiGyroUG
* \page bmi270_api_bmi270_read_gyro_user_gain bmi270_read_gyro_user_gain
* \code
* int8_t bmi270_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, const struct bmi2_dev *dev);
* \endcode
* @details This API reads the compensated gyroscope user-gain values.
*
* @param[out] gyr_usr_gain : Structure that stores gain values.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_read_gyro_user_gain(struct bmi2_gyro_user_gain_data *gyr_usr_gain, struct bmi2_dev *dev);
/*!
* \ingroup bmi270ApiInt
* \page bmi270_api_bmi270_map_feat_int bmi270_map_feat_int
* \code
* int8_t bmi270_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev)
* \endcode
* @details This API maps/unmaps feature interrupts to that of interrupt pins.
*
* @param[in] sens_int : Structure instance of bmi2_sens_int_config.
* @param[in] n_sens : Number of interrupts to be mapped.
* @param[in] dev : Structure instance of bmi2_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bmi270_map_feat_int(const struct bmi2_sens_int_config *sens_int, uint8_t n_sens, struct bmi2_dev *dev);
/******************************************************************************/
/*! @name C++ Guard Macros */
/******************************************************************************/
#ifdef __cplusplus
}
#endif /* End of CPP guard */
#endif /* BMI270_H_ */