added dependable build for interface choice in menuconfig

This commit is contained in:
Lurkars
2020-12-17 10:21:10 +01:00
parent 45444bb8c5
commit 7e82c695ea
56 changed files with 483 additions and 522 deletions
+32 -25
View File
@@ -1,33 +1,40 @@
set(priv_requires "ena" "ena-eke-proxy" "display" "rtc" "wifi-controller" )
set(src_list
"interface.c"
"interface-main.c"
"interface-data.c"
"interface-datetime.c"
"interface-info.c"
"interface-input.c"
"interface-label.c"
"interface-report.c"
"interface-settings.c"
"interface-wifi.c")
if(CONFIG_ENA_INTERFACE_CUSTOM)
list(APPEND priv_requires "display-custom-ssd1306" "rtc-custom-ds3231")
elseif(CONFIG_ENA_INTERFACE_M5STICKC)
list(APPEND priv_requires "display-m5-st7735s" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192")
elseif(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
list(APPEND priv_requires "display-m5-st7789" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192")
set(include_list ".")
if(CONFIG_ENA_INTERFACE_INPUT_CUSTOM)
list(APPEND src_list "custom-input/custom-input.c")
list(APPEND include_list "custom-input")
elseif(CONFIG_ENA_INTERFACE_M5STICKC OR CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
list(APPEND src_list "m5-input/m5-input.c" "m5-mpu6886/mpu6886.c")
list(APPEND include_list "m5-input" "m5-mpu6886")
elseif(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
list(APPEND priv_requires "display-ttgo-st7735" "imu-ttgo-lsm9ds1")
list(APPEND src_list "ttgo-input/ttgo-input.c" "ttgo-lsm9ds1/lsm9ds1.c")
list(APPEND include_list "ttgo-input" "ttgo-lsm9ds1")
else()
list(APPEND priv_requires "display-custom-ssd1306" "rtc-custom-ds3231") # uncomment for custom device with SSD1306 und DS3231
# list(APPEND priv_requires "display-m5-st7735s" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192") # uncomment for M5StickC
# list(APPEND priv_requires "display-m5-st7789" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192") # uncomment for M5StickC PLUS
# list(APPEND priv_requires "display-ttgo-st7735" "imu-ttgo-lsm9ds1") # uncomment for TTGO T-Wristband
list(APPEND src_list "dummy.c")
endif()
idf_component_register(
SRCS
"interface.c"
"interface-main.c"
"interface-data.c"
"interface-datetime.c"
"interface-debug.c"
"interface-info.c"
"interface-input.c"
"interface-label.c"
"interface-report.c"
"interface-settings.c"
"interface-wifi.c"
INCLUDE_DIRS "."
PRIV_REQUIRES ${priv_requires}
${src_list}
INCLUDE_DIRS
${include_list}
PRIV_REQUIRES
"ena"
"ena-eke-proxy"
"display"
"rtc"
"wifi-controller"
"i2c-main"
)
+44 -5
View File
@@ -5,17 +5,56 @@ menu "ENA Interface"
int "Seconds after display turns off on inactivity"
default 15
config ENA_INTERFACE_DEBUG
bool "Adds a debug interface for additional information for device"
default false
choice ENA_INTERFACE_DEVICE
prompt "Choose device"
default ENA_INTERFACE_CUSTOM
config ENA_INTERFACE_CUSTOM
bool "Custom"
choice ENA_INTERFACE_CUSTOM_DISPLAY
depends on ENA_INTERFACE_CUSTOM
prompt "Choose custom display"
default ENA_INTERFACE_DISPLAY_SSD1306
config ENA_INTERFACE_DISPLAY_SSD1306
bool "SSD1306"
config ENA_INTERFACE_DISPLAY_NONE
bool "none"
endchoice
choice ENA_INTERFACE_CUSTOM_RTC
depends on ENA_INTERFACE_CUSTOM
prompt "Choose custom rtc"
default ENA_INTERFACE_RTC_DS3231
config ENA_INTERFACE_RTC_DS3231
bool "DS3231"
config ENA_INTERFACE_RTC_NONE
bool "none"
endchoice
choice ENA_INTERFACE_CUSTOM_INPUT
depends on ENA_INTERFACE_CUSTOM
prompt "Choose custom input"
default ENA_INTERFACE_INPUT_CUSTOM
config ENA_INTERFACE_INPUT_CUSTOM
bool "7-Button input"
config ENA_INTERFACE_INPUT_NONE
bool "none"
endchoice
menu "Custom I²C"
depends on ENA_INTERFACE_CUSTOM
config I2C_SDA_PIN
int "I²C sda pin"
default 21
config I2C_SCL_PIN
int "I²C scl pin"
default 22
endmenu
config ENA_INTERFACE_M5STICKC
bool "M5StickC"
@@ -0,0 +1,128 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "interface.h"
#include "custom-input.h"
static float input_states[INTERFACE_COMMANDS_SIZE];
static float input_trigger_state[INTERFACE_COMMANDS_SIZE];
static int input_command_mapping[INTERFACE_COMMANDS_SIZE];
void custom_input_check(interface_command_t command)
{
int button_level = gpio_get_level(input_command_mapping[command]);
if (button_level == 0)
{
input_states[command] = input_states[command] + ((float)INTERFACE_INPUT_TICKS_MS / 1000);
if (command == INTERFACE_COMMAND_SET && input_states[command] > INTERFACE_LONG_STATE_SECONDS)
{
input_states[command] = 0;
input_states[INTERFACE_COMMAND_SET_LONG] = input_states[INTERFACE_COMMAND_SET_LONG] + 1;
interface_execute_command(INTERFACE_COMMAND_SET_LONG);
}
else if (command == INTERFACE_COMMAND_RST && input_states[command] > INTERFACE_LONG_STATE_SECONDS)
{
input_states[command] = 0;
input_states[INTERFACE_COMMAND_RST_LONG] = input_states[INTERFACE_COMMAND_RST_LONG] + 1;
interface_execute_command(INTERFACE_COMMAND_RST_LONG);
}
else if (input_states[command] > input_trigger_state[command])
{
input_trigger_state[command] = input_trigger_state[command] - (input_trigger_state[command] / 8);
if (input_trigger_state[command] <= ((float)INTERFACE_INPUT_TICKS_MS / 200))
{
input_trigger_state[command] = ((float)INTERFACE_INPUT_TICKS_MS / 200);
}
input_states[command] = 0;
interface_execute_command_trigger(command);
}
}
else if (button_level == 1 && input_states[command] > 0)
{
input_states[command] = 0;
input_trigger_state[command] = INTERFACE_LONG_STATE_SECONDS;
if (command == INTERFACE_COMMAND_SET && input_states[INTERFACE_COMMAND_SET_LONG] > 0)
{
input_states[INTERFACE_COMMAND_SET_LONG] = 0;
}
else if (command == INTERFACE_COMMAND_RST && input_states[INTERFACE_COMMAND_RST_LONG] > 0)
{
input_states[INTERFACE_COMMAND_RST_LONG] = 0;
}
else
{
interface_execute_command(command);
}
}
else if (button_level == 1)
{
input_trigger_state[command] = INTERFACE_LONG_STATE_SECONDS;
}
}
void custom_input_task(void *pvParameter)
{
while (1)
{
custom_input_check(INTERFACE_COMMAND_SET);
if (!interface_is_idle())
{
custom_input_check(INTERFACE_COMMAND_RST);
custom_input_check(INTERFACE_COMMAND_MID);
custom_input_check(INTERFACE_COMMAND_RHT);
custom_input_check(INTERFACE_COMMAND_LFT);
custom_input_check(INTERFACE_COMMAND_DWN);
custom_input_check(INTERFACE_COMMAND_UP);
}
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
}
}
void interface_input_start(void)
{
gpio_config_t io_conf;
io_conf.pin_bit_mask = (1ULL << BUTTON_RST) | (1ULL << BUTTON_SET) |
(1ULL << BUTTON_MID) | (1ULL << BUTTON_RHT) |
(1ULL << BUTTON_LFT) | (1ULL << BUTTON_DWN) |
(1ULL << BUTTON_UP);
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_config(&io_conf);
input_command_mapping[INTERFACE_COMMAND_RST] = BUTTON_RST;
input_command_mapping[INTERFACE_COMMAND_SET] = BUTTON_SET;
input_command_mapping[INTERFACE_COMMAND_MID] = BUTTON_MID;
input_command_mapping[INTERFACE_COMMAND_RHT] = BUTTON_RHT;
input_command_mapping[INTERFACE_COMMAND_LFT] = BUTTON_LFT;
input_command_mapping[INTERFACE_COMMAND_DWN] = BUTTON_DWN;
input_command_mapping[INTERFACE_COMMAND_UP] = BUTTON_UP;
for (int i = 0; i < INTERFACE_COMMANDS_SIZE; i++)
{
input_trigger_state[i] = INTERFACE_LONG_STATE_SECONDS;
}
xTaskCreate(&custom_input_task, "custom_input_task", 4096, NULL, 5, NULL);
}
@@ -0,0 +1,31 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file
*
* @brief execute interface commands via simple push buttons
*
*/
#ifndef _button_input_H_
#define _button_input_H_
#define BUTTON_RST GPIO_NUM_32
#define BUTTON_SET GPIO_NUM_33
#define BUTTON_MID GPIO_NUM_25
#define BUTTON_RHT GPIO_NUM_26
#define BUTTON_LFT GPIO_NUM_27
#define BUTTON_DWN GPIO_NUM_14
#define BUTTON_UP GPIO_NUM_12
#endif
+19
View File
@@ -0,0 +1,19 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "interface.h"
void interface_input_start(void)
{
}
-4
View File
@@ -109,11 +109,7 @@ void interface_data_lft(void)
void interface_data_rht(void)
{
#if defined(CONFIG_ENA_INTERFACE_DEBUG)
interface_debug_start();
#else
interface_info_start();
#endif
}
void interface_data_mid(void)
-168
View File
@@ -1,168 +0,0 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "display.h"
#include "display-gfx.h"
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
#include "mpu6886.h"
#include "axp192.h"
#endif
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
#include "lsm9ds1.h"
#endif
#include "interface.h"
static bool runTask = true;
static TaskHandle_t debugTaskHandle = NULL;
void interface_debug_set(void)
{
runTask = false;
vTaskDelay(100 / portTICK_PERIOD_MS);
vTaskSuspend(debugTaskHandle);
interface_main_start();
}
void interface_debug_rst(void)
{
}
void interface_debug_lft(void)
{
runTask = false;
vTaskDelay(100 / portTICK_PERIOD_MS);
vTaskSuspend(debugTaskHandle);
interface_data_start();
}
void interface_debug_rht(void)
{
runTask = false;
vTaskDelay(100 / portTICK_PERIOD_MS);
vTaskSuspend(debugTaskHandle);
interface_info_start();
}
void interface_debug_mid(void)
{
}
void interface_debug_up(void)
{
}
void interface_debug_dwn(void)
{
}
void interface_debug_task(void *pvParameter)
{
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS) || defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
float ax = 0;
float ay = 0;
float az = 0;
float gx = 0;
float gy = 0;
float gz = 0;
#endif
while (1)
{
if (!interface_is_idle() && runTask)
{
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
mpu6886_get_accel_data(&ax, &ay, &az);
mpu6886_get_gyro_data(&gx, &gy, &gz);
#endif
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
lsm9ds1_get_accel_data(&ax, &ay, &az);
lsm9ds1_get_gyro_data(&gx, &gy, &gz);
#endif
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS) || defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
char data_chars[32];
sprintf(data_chars, "acc x:%3.2f", ax);
display_text_line(data_chars, 1, false);
sprintf(data_chars, "acc y:%3.2f", ay);
display_text_line(data_chars, 2, false);
sprintf(data_chars, "acc z:%3.2f", az);
display_text_line(data_chars, 3, false);
sprintf(data_chars, "gyr x:%3.2f", gx);
display_text_line(data_chars, 4, false);
sprintf(data_chars, "gyr y:%3.2f", gy);
display_text_line(data_chars, 5, false);
sprintf(data_chars, "gyr z:%3.2f", gz);
display_text_line(data_chars, 6, false);
#endif
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
float bat_v = axp192_get_bat_voltage();
sprintf(data_chars, "Battery: %.2f V", bat_v);
display_text_line(data_chars, 7, false);
#endif
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void interface_debug_start(void)
{
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
lsm9ds1_start();
#endif
interface_register_command_callback(INTERFACE_COMMAND_RST, &interface_debug_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_debug_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_debug_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_debug_rht);
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_debug_mid);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_debug_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_debug_dwn);
interface_register_command_callback(INTERFACE_COMMAND_RST_LONG, NULL);
interface_register_command_callback(INTERFACE_COMMAND_SET_LONG, NULL);
interface_set_display_function(NULL);
display_menu_headline(interface_get_label_text(&interface_text_headline_debug), true, 0);
if (debugTaskHandle == NULL)
{
xTaskCreate(&interface_debug_task, "interface_debug_task", 4096 * 2, NULL, 5, &debugTaskHandle);
}
else
{
vTaskResume(debugTaskHandle);
}
runTask = true;
}
+93 -42
View File
@@ -24,9 +24,20 @@
#include "ena-storage.h"
#include "ena-exposure.h"
#include "ena-bluetooth-scan.h"
#include "interface.h"
typedef enum
{
INTERFACE_INFO_STATUS_EXPOSURE = 0,
INTERFACE_INFO_STATUS_BEACONS,
INTERFACE_INFO_STATUS_SCAN,
INTERFACE_INFO_STATUS_SYSTEM
} info_status_e;
static int current_info_status = INTERFACE_INFO_STATUS_EXPOSURE;
void interface_info_set(void)
{
interface_main_start();
@@ -38,11 +49,7 @@ void interface_info_rst(void)
void interface_info_lft(void)
{
#if defined(CONFIG_ENA_INTERFACE_DEBUG)
interface_debug_start();
#else
interface_data_start();
#endif
}
void interface_info_rht(void)
@@ -56,10 +63,20 @@ void interface_info_mid(void)
void interface_info_up(void)
{
current_info_status--;
if (current_info_status < INTERFACE_INFO_STATUS_EXPOSURE)
{
current_info_status = INTERFACE_INFO_STATUS_SYSTEM;
}
}
void interface_info_dwn(void)
{
current_info_status++;
if (current_info_status > INTERFACE_INFO_STATUS_SYSTEM)
{
current_info_status = INTERFACE_INFO_STATUS_EXPOSURE;
}
}
int interface_info_num_offset(int num)
@@ -80,50 +97,84 @@ int interface_info_num_offset(int num)
void interface_info_display(void)
{
ena_exposure_summary_t *current_exposure_summary = ena_exposure_current_summary();
char data_chars[16];
display_clear();
char char_buffer[64];
display_menu_headline(interface_get_label_text(&interface_text_headline_info), true, 0);
display_text_line_column(interface_get_label_text(&interface_text_info_num_keys), 2, 1, false);
display_data(display_gfx_arrow_up, 8, 1, 60, false);
int num = ena_storage_beacons_count();
sprintf(data_chars, "%u", num);
display_text_line_column(data_chars, 2, interface_info_num_offset(num), false);
display_text_line_column(interface_get_label_text(&interface_text_info_last_keys), 3, 1, false);
time_t current_timstamp;
time(&current_timstamp);
int min = ena_expore_check_find_min((uint32_t)current_timstamp - 60 * 30);
int last30 = num - min;
if (last30 >= 0)
if (current_info_status == INTERFACE_INFO_STATUS_EXPOSURE)
{
ena_exposure_summary_t *current_exposure_summary = ena_exposure_current_summary();
display_text_line_column(interface_get_label_text(&interface_text_info_exp_days), 3, 1, false);
int last = current_exposure_summary->days_since_last_exposure;
if (last >= 0)
{
sprintf(char_buffer, "%d", last);
display_text_line_column(char_buffer, 3, interface_info_num_offset(last), false);
}
display_text_line_column(interface_get_label_text(&interface_text_info_exp_num), 4, 1, false);
sprintf(char_buffer, "%d", current_exposure_summary->num_exposures);
display_text_line_column(char_buffer, 4, interface_info_num_offset(current_exposure_summary->num_exposures), false);
display_text_line_column(interface_get_label_text(&interface_text_info_exp_max), 5, 1, false);
sprintf(char_buffer, "%d", current_exposure_summary->max_risk_score);
display_text_line_column(char_buffer, 5, interface_info_num_offset(current_exposure_summary->max_risk_score), false);
display_text_line_column(interface_get_label_text(&interface_text_info_exp_sum), 6, 1, false);
sprintf(char_buffer, "%d", current_exposure_summary->risk_score_sum);
display_text_line_column(char_buffer, 6, interface_info_num_offset(current_exposure_summary->risk_score_sum), false);
}
else if (current_info_status == INTERFACE_INFO_STATUS_BEACONS)
{
display_text_line_column(interface_get_label_text(&interface_text_info_num_keys), 3, 1, false);
int num = ena_storage_beacons_count();
sprintf(char_buffer, "%u", num);
display_text_line_column(char_buffer, 3, interface_info_num_offset(num), false);
display_text_line_column(interface_get_label_text(&interface_text_info_last_keys), 4, 1, false);
time_t current_timstamp;
time(&current_timstamp);
int min = ena_expore_check_find_min((uint32_t)current_timstamp - 60 * 30);
int last30 = num - min;
if (last30 >= 0)
{
sprintf(char_buffer, "%d", last30);
display_text_line_column(char_buffer, 4, interface_info_num_offset(last30), false);
}
}
else if (current_info_status == INTERFACE_INFO_STATUS_SCAN)
{
int current_scan = ena_bluetooth_scan_get_last_num();
switch (ena_bluetooth_scan_get_status())
{
case ENA_SCAN_STATUS_SCANNING:
display_text_line_column(interface_get_label_text(&interface_text_info_scan_status_scanning), 3, 1, false);
break;
case ENA_SCAN_STATUS_NOT_SCANNING:
display_text_line_column(interface_get_label_text(&interface_text_info_scan_status_notscanning), 3, 1, false);
break;
case ENA_SCAN_STATUS_WAITING:
display_text_line_column(interface_get_label_text(&interface_text_info_scan_status_waiting), 3, 1, false);
break;
}
display_text_line_column(interface_get_label_text(&interface_text_info_scan_last), 5, 1, false);
sprintf(char_buffer, "%d", current_scan);
display_text_line_column(char_buffer, 5, interface_info_num_offset(current_scan), false);
}
else if (current_info_status == INTERFACE_INFO_STATUS_SYSTEM)
{
sprintf(data_chars, "%d", last30);
display_text_line_column(data_chars, 3, interface_info_num_offset(last30), false);
}
display_text_line_column(interface_get_label_text(&interface_text_info_exp_days), 4, 1, false);
int last = current_exposure_summary->days_since_last_exposure;
if (last >= 0)
{
sprintf(data_chars, "%d", last);
display_text_line_column(data_chars, 4, interface_info_num_offset(last), false);
}
display_text_line_column(interface_get_label_text(&interface_text_info_exp_num), 5, 1, false);
sprintf(data_chars, "%d", current_exposure_summary->num_exposures);
display_text_line_column(data_chars, 5, interface_info_num_offset(current_exposure_summary->num_exposures), false);
display_text_line_column(interface_get_label_text(&interface_text_info_exp_max), 6, 1, false);
sprintf(data_chars, "%d", current_exposure_summary->max_risk_score);
display_text_line_column(data_chars, 6, interface_info_num_offset(current_exposure_summary->max_risk_score), false);
display_text_line_column(interface_get_label_text(&interface_text_info_exp_sum), 7, 1, false);
sprintf(data_chars, "%d", current_exposure_summary->risk_score_sum);
display_text_line_column(data_chars, 7, interface_info_num_offset(current_exposure_summary->risk_score_sum), false);
display_data(display_gfx_arrow_down, 8, 7, 60, false);
}
void interface_info_start(void)
+10
View File
@@ -58,6 +58,11 @@ void interface_init_label(void)
interface_text_info_exp_max.text[EN] = "Score:";
interface_text_info_exp_sum.text[EN] = "Scores:";
interface_text_info_scan_status_scanning.text[EN] = "Scanning...";
interface_text_info_scan_status_notscanning.text[EN] = "Not scanning.";
interface_text_info_scan_status_waiting.text[EN] = "Waiting for scan";
interface_text_info_scan_last.text[EN] = "Last scan:";
interface_text_report_pending.text[EN] = "Uploading...";
interface_text_report_success.text[EN] = "Upload succeed!";
interface_text_report_fail.text[EN] = "Upload failed!";
@@ -124,6 +129,11 @@ void interface_init_label(void)
interface_text_info_exp_max.text[DE] = "Score:";
interface_text_info_exp_sum.text[DE] = "Scores:";
interface_text_info_scan_status_scanning.text[DE] = "Scannen...";
interface_text_info_scan_status_notscanning.text[DE] = "Kein Scan.";
interface_text_info_scan_status_waiting.text[DE] = "Warten auf Scan.";
interface_text_info_scan_last.text[DE] = "letz. Scan:";
interface_text_report_pending.text[DE] = "Hochladen...";
interface_text_report_success.text[DE] = "Erfolgreich!";
interface_text_report_fail.text[DE] = "Fehlgeschlagen!";
+2
View File
@@ -145,6 +145,8 @@ void interface_start(void)
display_clear();
xTaskCreate(&interface_display_task, "interface_display_task", 4096, NULL, 5, NULL);
interface_input_start();
}
void interface_flipped(bool flipped)
+14 -5
View File
@@ -93,6 +93,10 @@ interface_label_t interface_text_info_exp_days;
interface_label_t interface_text_info_exp_num;
interface_label_t interface_text_info_exp_max;
interface_label_t interface_text_info_exp_sum;
interface_label_t interface_text_info_scan_status_scanning;
interface_label_t interface_text_info_scan_status_notscanning;
interface_label_t interface_text_info_scan_status_waiting;
interface_label_t interface_text_info_scan_last;
interface_label_t interface_text_report_pending;
interface_label_t interface_text_report_success;
@@ -127,6 +131,16 @@ typedef void (*interface_display_function)(void);
*/
typedef void (*interface_text_callback)(char *text, uint8_t cursor);
/**
* @brief start input routine
*
* MUST BE DEFINED DEVICE SPECIFIC
*
*/
void interface_input_start(void);
/**
* @brief is interface in idle mode
*
@@ -268,11 +282,6 @@ void interface_settings_start(void);
*/
void interface_info_start(void);
/**
* @brief start debug interface
*/
void interface_debug_start(void);
/**
* @brief start interface for input
*
+163
View File
@@ -0,0 +1,163 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "mpu6886.h"
#include "interface.h"
#include "m5-input.h"
static float input_states[INTERFACE_COMMANDS_SIZE];
static float input_trigger_state[INTERFACE_COMMANDS_SIZE];
static int input_command_mapping[INTERFACE_COMMANDS_SIZE];
static bool flipped = false;
void button_input_check(interface_command_t command)
{
int button_level = gpio_get_level(input_command_mapping[command]);
if (button_level == 0)
{
input_states[command] = input_states[command] + ((float)INTERFACE_INPUT_TICKS_MS / 1000);
if (command == INTERFACE_COMMAND_SET && input_states[command] > INTERFACE_LONG_STATE_SECONDS)
{
input_states[command] = 0;
input_states[INTERFACE_COMMAND_SET_LONG] = input_states[INTERFACE_COMMAND_SET_LONG] + 1;
interface_execute_command(INTERFACE_COMMAND_SET_LONG);
}
else if (command == INTERFACE_COMMAND_RST && input_states[command] > INTERFACE_LONG_STATE_SECONDS)
{
input_states[command] = 0;
input_states[INTERFACE_COMMAND_RST_LONG] = input_states[INTERFACE_COMMAND_RST_LONG] + 1;
interface_execute_command(INTERFACE_COMMAND_RST_LONG);
}
}
else if (button_level == 1 && input_states[command] > 0)
{
input_states[command] = 0;
if (command == INTERFACE_COMMAND_SET && input_states[INTERFACE_COMMAND_SET_LONG] > 0)
{
input_states[INTERFACE_COMMAND_SET_LONG] = 0;
}
else if (command == INTERFACE_COMMAND_RST && input_states[INTERFACE_COMMAND_RST_LONG] > 0)
{
input_states[INTERFACE_COMMAND_RST_LONG] = 0;
}
else
{
if (!interface_is_idle() && flipped)
{
if (command == INTERFACE_COMMAND_SET)
{
command = INTERFACE_COMMAND_RST;
}
else if (command == INTERFACE_COMMAND_RST)
{
command = INTERFACE_COMMAND_SET;
}
}
interface_execute_command(command);
}
}
}
void accel_input(float axis, interface_command_t command, float tresh)
{
if (axis > tresh)
{
input_states[command] = input_states[command] + ((float)INTERFACE_INPUT_TICKS_MS / 1000);
if (input_states[command] > input_trigger_state[command])
{
input_trigger_state[command] = input_trigger_state[command] - (input_trigger_state[command] / 8);
if (input_trigger_state[command] <= ((float)INTERFACE_INPUT_TICKS_MS / 200))
{
input_trigger_state[command] = ((float)INTERFACE_INPUT_TICKS_MS / 200);
}
input_states[command] = 0;
interface_execute_command_trigger(command);
}
}
else if (input_states[command] > 0)
{
input_states[command] = 0;
input_trigger_state[command] = INTERFACE_LONG_STATE_SECONDS;
interface_execute_command(command);
}
}
void m5_input_task(void *pvParameter)
{
float ax = 0;
float ay = 0;
float az = 0;
while (1)
{
button_input_check(INTERFACE_COMMAND_SET);
if (!interface_is_idle())
{
button_input_check(INTERFACE_COMMAND_RST);
mpu6886_get_accel_data(&ax, &ay, &az);
accel_input(flipped ? ax : -ax, INTERFACE_COMMAND_UP, 0.3);
accel_input(flipped ? ay : -ay, INTERFACE_COMMAND_LFT, 0.5);
accel_input(flipped ? -ax : ax, INTERFACE_COMMAND_DWN, 0.5);
accel_input(flipped ? -ay : ay, INTERFACE_COMMAND_RHT, 0.3);
if (ax >= 0.95)
{
flipped = false;
interface_flipped(flipped);
}
else if (ax <= -0.95)
{
flipped = true;
interface_flipped(flipped);
}
}
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
}
}
void interface_input_start(void)
{
gpio_config_t io_conf;
io_conf.pin_bit_mask = (1ULL << BUTTON_RST) | (1ULL << BUTTON_SET);
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_config(&io_conf);
input_command_mapping[INTERFACE_COMMAND_RST] = BUTTON_RST;
input_command_mapping[INTERFACE_COMMAND_SET] = BUTTON_SET;
mpu6886_start();
for (int i = 0; i < INTERFACE_COMMANDS_SIZE; i++)
{
input_trigger_state[i] = INTERFACE_LONG_STATE_SECONDS;
}
xTaskCreate(&m5_input_task, "m5_input_task", 4096, NULL, 5, NULL);
}
+26
View File
@@ -0,0 +1,26 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file
*
* @brief execute interface commands via simple push buttons
*
*/
#ifndef _m5_input_H_
#define _m5_input_H_
#define BUTTON_RST GPIO_NUM_37
#define BUTTON_SET GPIO_NUM_39
#endif
+260
View File
@@ -0,0 +1,260 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <time.h>
#include "driver/i2c.h"
#include "esp_log.h"
#include "i2c-main.h"
#include "mpu6886.h"
int Gyscale = GFS_2000DPS;
int Acscale = AFS_8G;
float aRes, gRes;
void mpu6886_i2c_read_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *read_buffer)
{
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, start_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd, read_buffer, number_Bytes, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
}
void mpu6886_i2c_write_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *write_buffer)
{
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, start_addr, true);
i2c_master_write(cmd, write_buffer, number_Bytes, true);
i2c_master_stop(cmd);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
}
void mpu6886_getGres()
{
switch (Gyscale)
{
// Possible gyro scales (and their register bit settings) are:
case GFS_250DPS:
gRes = 250.0 / 32768.0;
break;
case GFS_500DPS:
gRes = 500.0 / 32768.0;
break;
case GFS_1000DPS:
gRes = 1000.0 / 32768.0;
break;
case GFS_2000DPS:
gRes = 2000.0 / 32768.0;
break;
}
}
void mpu6886_getAres()
{
switch (Acscale)
{
// Possible accelerometer scales (and their register bit settings) are:
// 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11).
// Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
case AFS_2G:
aRes = 2.0 / 32768.0;
break;
case AFS_4G:
aRes = 4.0 / 32768.0;
break;
case AFS_8G:
aRes = 8.0 / 32768.0;
break;
case AFS_16G:
aRes = 16.0 / 32768.0;
break;
}
}
int mpu6886_start(void)
{
unsigned char tempdata[1];
unsigned char regdata;
if (!i2c_is_initialized())
{
i2c_main_init();
}
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_WHOAMI, 1, tempdata);
if (tempdata[0] != 0x19)
return -1;
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x00;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, &regdata);
vTaskDelay(10 / portTICK_PERIOD_MS);;
regdata = (0x01 << 7);
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, &regdata);
vTaskDelay(10 / portTICK_PERIOD_MS);;
regdata = (0x01 << 0);
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, &regdata);
vTaskDelay(10 / portTICK_PERIOD_MS);;
regdata = 0x10;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x18;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_GYRO_CONFIG, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x01;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_CONFIG, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x05;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_SMPLRT_DIV, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x00;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_INT_ENABLE, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x00;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG2, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x00;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_USER_CTRL, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x00;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_FIFO_EN, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x22;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_INT_PIN_CFG, 1, &regdata);
vTaskDelay(1 / portTICK_PERIOD_MS);;
regdata = 0x01;
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_INT_ENABLE, 1, &regdata);
vTaskDelay(100 / portTICK_PERIOD_MS);;
mpu6886_getGres();
mpu6886_getAres();
return 0;
}
void mpu6886_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az)
{
uint8_t buf[6];
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_XOUT_H, 6, buf);
*ax = ((int16_t)buf[0] << 8) | buf[1];
*ay = ((int16_t)buf[2] << 8) | buf[3];
*az = ((int16_t)buf[4] << 8) | buf[5];
}
void mpu6886_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz)
{
uint8_t buf[6];
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_GYRO_XOUT_H, 6, buf);
*gx = ((uint16_t)buf[0] << 8) | buf[1];
*gy = ((uint16_t)buf[2] << 8) | buf[3];
*gz = ((uint16_t)buf[4] << 8) | buf[5];
}
void mpu6886_get_temp_adc(int16_t *t)
{
uint8_t buf[2];
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_TEMP_OUT_H, 2, buf);
*t = ((uint16_t)buf[0] << 8) | buf[1];
}
void mpu6886_set_gyro_fsr(int scale)
{
//return IIC_Write_Byte(MPU_GYRO_CFG_REG,scale<<3);//设置陀螺仪满量程范围
unsigned char regdata;
regdata = (scale << 3);
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_GYRO_CONFIG, 1, &regdata);
vTaskDelay(10 / portTICK_PERIOD_MS);;
Gyscale = scale;
mpu6886_getGres();
}
void mpu6886_set_accel_fsr(int scale)
{
unsigned char regdata;
regdata = (scale << 3);
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG, 1, &regdata);
vTaskDelay(10 / portTICK_PERIOD_MS);;
Acscale = scale;
mpu6886_getAres();
}
void mpu6886_get_accel_data(float *ax, float *ay, float *az)
{
int16_t accX = 0;
int16_t accY = 0;
int16_t accZ = 0;
mpu6886_get_accel_adc(&accX, &accY, &accZ);
*ax = (float)accX * aRes;
*ay = (float)accY * aRes;
*az = (float)accZ * aRes;
}
void mpu6886_get_gyro_data(float *gx, float *gy, float *gz)
{
int16_t gyroX = 0;
int16_t gyroY = 0;
int16_t gyroZ = 0;
mpu6886_get_gyro_adc(&gyroX, &gyroY, &gyroZ);
*gx = (float)gyroX * gRes;
*gy = (float)gyroY * gRes;
*gz = (float)gyroZ * gRes;
}
void mpu6886_get_temp_data(float *t)
{
int16_t temp = 0;
mpu6886_get_temp_adc(&temp);
*t = (float)temp / 326.8 + 25.0;
}
+78
View File
@@ -0,0 +1,78 @@
/*
Note: The MPU6886 is an I2C sensor and uses the Arduino Wire library.
Because the sensor is not 5V tolerant, we are using a 3.3 V 8 MHz Pro Mini or
a 3.3 V Teensy 3.1. We have disabled the internal pull-ups used by the Wire
library in the Wire.h/twi.c utility file. We are also using the 400 kHz fast
I2C mode by setting the TWI_FREQ to 400000L /twi.h utility file.
*/
#ifndef _IMU_MPU6886_H_
#define _IMU_MPU6886_H_
#include "stdio.h"
#define MPU6886_ADDRESS 0x68
#define MPU6886_WHOAMI 0x75
#define MPU6886_ACCEL_INTEL_CTRL 0x69
#define MPU6886_SMPLRT_DIV 0x19
#define MPU6886_INT_PIN_CFG 0x37
#define MPU6886_INT_ENABLE 0x38
#define MPU6886_ACCEL_XOUT_H 0x3B
#define MPU6886_ACCEL_XOUT_L 0x3C
#define MPU6886_ACCEL_YOUT_H 0x3D
#define MPU6886_ACCEL_YOUT_L 0x3E
#define MPU6886_ACCEL_ZOUT_H 0x3F
#define MPU6886_ACCEL_ZOUT_L 0x40
#define MPU6886_TEMP_OUT_H 0x41
#define MPU6886_TEMP_OUT_L 0x42
#define MPU6886_GYRO_XOUT_H 0x43
#define MPU6886_GYRO_XOUT_L 0x44
#define MPU6886_GYRO_YOUT_H 0x45
#define MPU6886_GYRO_YOUT_L 0x46
#define MPU6886_GYRO_ZOUT_H 0x47
#define MPU6886_GYRO_ZOUT_L 0x48
#define MPU6886_USER_CTRL 0x6A
#define MPU6886_PWR_MGMT_1 0x6B
#define MPU6886_PWR_MGMT_2 0x6C
#define MPU6886_CONFIG 0x1A
#define MPU6886_GYRO_CONFIG 0x1B
#define MPU6886_ACCEL_CONFIG 0x1C
#define MPU6886_ACCEL_CONFIG2 0x1D
#define MPU6886_FIFO_EN 0x23
//#define G (9.8)
#define RtA 57.324841
#define AtR 0.0174533
#define Gyro_Gr 0.0010653
enum Ascale
{
AFS_2G = 0,
AFS_4G,
AFS_8G,
AFS_16G
} ;
enum Gscale
{
GFS_250DPS = 0,
GFS_500DPS,
GFS_1000DPS,
GFS_2000DPS
};
int mpu6886_start(void);
void mpu6886_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az);
void mpu6886_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz);
void mpu6886_get_temp_adc(int16_t *t);
void mpu6886_get_accel_data(float *ax, float *ay, float *az);
void mpu6886_get_gyro_data(float *gx, float *gy, float *gz);
void mpu6886_get_temp_data(float *t);
void mpu6886_set_gyro_fsr(int scale);
void mpu6886_set_accel_fsr(int scale);
#endif
@@ -0,0 +1,44 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "lsm9ds1.h"
#include "interface.h"
#include "ttgo-input.h"
void ttgo_input_task(void *pvParameter)
{
float ax = 0;
float ay = 0;
float az = 0;
while (1)
{
lsm9ds1_get_accel_data(&ax, &ay, &az);
// ESP_LOGI(INTERFACE_LOG, "ax: %f ay:%f az:%f", ax, ay, az);
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
}
}
void interface_input_start(void)
{
lsm9ds1_start();
xTaskCreate(&ttgo_input_task, "ttgo_input_task", 4096, NULL, 5, NULL);
}
@@ -0,0 +1,23 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file
*
* @brief execute interface commands via simple push buttons
*
*/
#ifndef _ttgo_input_H_
#define _ttgo_input_H_
#endif
+132
View File
@@ -0,0 +1,132 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <time.h>
#include "driver/i2c.h"
#include "esp_log.h"
#include "i2c-main.h"
#include "lsm9ds1.h"
float aRes, gRes;
void lsm9ds1_i2c_read_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *read_buffer)
{
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, start_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd, read_buffer, number_Bytes, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
}
void lsm9ds1_i2c_write_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *write_buffer)
{
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, start_addr, true);
i2c_master_write(cmd, write_buffer, number_Bytes, true);
i2c_master_stop(cmd);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
}
int lsm9ds1_start(void)
{
if (!i2c_is_initialized())
{
i2c_main_init();
}
unsigned char regdata;
// init ACC
regdata = 0x38;
lsm9ds1_i2c_write_bytes(ACC_ADDR, CTRL_REG5_A, 1, &regdata);
regdata = 0xC0;
lsm9ds1_i2c_write_bytes(ACC_ADDR, CTRL_REG6_A, 1, &regdata);
lsm9ds1_i2c_read_bytes(ACC_ADDR, CTRL_REG6_A, 1, &regdata);
regdata &= ~(0b00011000);
regdata |= ACCELRANGE_16G;
lsm9ds1_i2c_write_bytes(ACC_ADDR, CTRL_REG6_A, 1, &regdata);
// init gyr
regdata = 0xC0;
lsm9ds1_i2c_write_bytes(GYR_ADDR, CTRL_REG1_G, 1, &regdata);
lsm9ds1_i2c_read_bytes(GYR_ADDR, CTRL_REG1_G, 1, &regdata);
regdata &= ~(0b00011000);
regdata |= GYROSCALE_500DPS;
lsm9ds1_i2c_write_bytes(GYR_ADDR, CTRL_REG1_G, 1, &regdata);
aRes = 16.0 / 32768.0;
gRes = 500.0 / 32768.0;
return 0;
}
void lsm9ds1_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az)
{
uint8_t buf[6];
lsm9ds1_i2c_read_bytes(ACC_ADDR, OUT_X_L_A, 6, buf);
*ax = ((int16_t)buf[0] << 8) | buf[1];
*ay = ((int16_t)buf[2] << 8) | buf[3];
*az = ((int16_t)buf[4] << 8) | buf[5];
}
void lsm9ds1_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz)
{
uint8_t buf[6];
lsm9ds1_i2c_read_bytes(GYR_ADDR, OUT_X_L_G, 6, buf);
*gx = ((uint16_t)buf[0] << 8) | buf[1];
*gy = ((uint16_t)buf[2] << 8) | buf[3];
*gz = ((uint16_t)buf[4] << 8) | buf[5];
}
void lsm9ds1_get_accel_data(float *ax, float *ay, float *az)
{
int16_t accX = 0;
int16_t accY = 0;
int16_t accZ = 0;
lsm9ds1_get_accel_adc(&accX, &accY, &accZ);
*ax = (float)accX * aRes;
*ay = (float)accY * aRes;
*az = (float)accZ * aRes;
}
void lsm9ds1_get_gyro_data(float *gx, float *gy, float *gz)
{
int16_t gyroX = 0;
int16_t gyroY = 0;
int16_t gyroZ = 0;
lsm9ds1_get_gyro_adc(&gyroX, &gyroY, &gyroZ);
*gx = (float)gyroX * gRes;
*gy = (float)gyroY * gRes;
*gz = (float)gyroZ * gRes;
}
+138
View File
@@ -0,0 +1,138 @@
/*
Note: The MPU6886 is an I2C sensor and uses the Arduino Wire library.
Because the sensor is not 5V tolerant, we are using a 3.3 V 8 MHz Pro Mini or
a 3.3 V Teensy 3.1. We have disabled the internal pull-ups used by the Wire
library in the Wire.h/twi.c utility file. We are also using the 400 kHz fast
I2C mode by setting the TWI_FREQ to 400000L /twi.h utility file.
*/
#ifndef _IMU_LSM9DS1_H_
#define _IMU_LSM9DS1_H_
#include "stdio.h"
#define ID_AG 0x6F
#define ID_A 0x6F
#define ID_G 0x6F
#define ID_M 0x3D
#define FILENAME "/dev/i2c-1"
#define MAG_ADDR 0x1E
#define ACC_ADDR 0x6B
#define GYR_ADDR 0x6B
// Shared Accelerometer/Gyroscope Addresses
#define WHO_AM_I_AG 0x0F
#define CTRL_REG1_AG 0x10
#define CTRL_REG2_AG 0x11
#define CTRL_REG3_AG 0x12
#define OUT_TEMP_L_AG 0x15
#define OUT_TEMP_H_AG 0x16
#define REG_STATUS_REG_AG 0x17
#define CTRL_REG4_AG 0x1E
#define CTRL_REG5_AG 0x1F
#define CTRL_REG6_AG 0x20
#define CTRL_REG7_AG 0x21
#define CTRL_REG8_AG 0x22
#define CTRL_REG9_AG 0x23
#define CTRL_REG10_AG 0x24
// Gyroscope addresses
#define WHO_AM_I_G 0x0F
#define CTRL_REG1_G 0x10
#define CTRL_REG2_G 0x11
#define CTRL_REG3_G 0x12
#define OUT_X_L_G 0x18
#define OUT_X_H_G 0x19
#define OUT_Y_L_G 0x1A
#define OUT_Y_H_G 0x1B
#define OUT_Z_L_G 0x1C
#define OUT_Z_H_G 0x1D
// Accelerometer addresses
#define WHO_AM_I_A 0x0F
#define CTRL_REG5_A 0x1F
#define CTRL_REG6_A 0x20
#define CTRL_REG7_A 0x21
#define OUT_X_L_A 0x28
#define OUT_X_H_A 0x29
#define OUT_Y_L_A 0x2A
#define OUT_Y_H_A 0x2B
#define OUT_Z_L_A 0x2C
#define OUT_Z_H_A 0x2D
// Magnetometer addresses
#define WHO_AM_I_M 0x0F
#define CTRL_REG1_M 0x20
#define CTRL_REG2_M 0x21
#define CTRL_REG3_M 0x22
#define CTRL_REG4_M 0x23
#define CTRL_REG5_M 0x24
#define REG_STATUS_REG_M 0x27
#define OUT_X_L_M 0x28
#define OUT_X_H_M 0x29
#define OUT_Y_L_M 0x2A
#define OUT_Y_H_M 0x2B
#define OUT_Z_L_M 0x2C
#define OUT_Z_H_M 0x2D
#define REG_CFG_M 0x30
#define INT_SRC_M 0x31
// Settings
#define ACCELRANGE_2G 0x0 << 3
#define ACCELRANGE_16G 0x1 << 3
#define ACCELRANGE_4G 0x2 << 3
#define ACCELRANGE_8G 0x3 << 3
#define ACCELDATARATE_POWERDOWN 0x0 << 4
#define ACCELDATARATE_3_125HZ 0x1 << 4
#define ACCELDATARATE_6_25HZ 0x2 << 4
#define ACCELDATARATE_12_5HZ 0x3 << 4
#define ACCELDATARATE_25HZ 0x4 << 4
#define ACCELDATARATE_50HZ 0x5 << 4
#define ACCELDATARATE_100HZ 0x6 << 4
#define ACCELDATARATE_200HZ 0x7 << 4
#define ACCELDATARATE_400HZ 0x8 << 4
#define ACCELDATARATE_800HZ 0x9 << 4
#define ACCELDATARATE_1600HZ 0xa << 4
#define MAGGAIN_4GAUSS 0x0 << 5
#define MAGGAIN_8GAUSS 0x1 << 5
#define MAGGAIN_12GAUSS 0x2 << 5
#define MAGGAIN_16GAUSS 0x3 << 5
#define MAGDATARATE_3_125HZ 0x0 << 2
#define MAGDATARATE_6_25HZ 0x1 << 2
#define MAGDATARATE_12_5HZ 0x2 << 2
#define MAGDATARATE_25HZ 0x3 << 2
#define MAGDATARATE_50HZ 0x4 << 2
#define MAGDATARATE_100HZ 0x5 << 2
#define GYROSCALE_245DPS 0x0 << 4
#define GYROSCALE_500DPS 0x1 << 4
#define GYROSCALE_2000DPS 0x2 << 4
/* Conversions */
#define GRAVITY (9.80665F)
#define ACCEL_MG_LSB_2G (0.061F)
#define ACCEL_MG_LSB_4G (0.122F)
#define ACCEL_MG_LSB_8G (0.244F)
#define ACCEL_MG_LSB_16G (0.732F) // Is this right? Was expecting 0.488F
#define MAG_MGAUSS_4GAUSS (0.16F)
#define MAG_MGAUSS_8GAUSS (0.32F)
#define MAG_MGAUSS_12GAUSS (0.48F)
#define MAG_MGAUSS_16GAUSS (0.58F)
#define GYRO_DPS_DIGIT_245DPS (0.00875F)
#define GYRO_DPS_DIGIT_500DPS (0.01750F)
#define GYRO_DPS_DIGIT_2000DPS (0.07000F)
int lsm9ds1_start(void);
void lsm9ds1_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az);
void lsm9ds1_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz);
void lsm9ds1_get_accel_data(float *ax, float *ay, float *az);
void lsm9ds1_get_gyro_data(float *gx, float *gy, float *gz);
#endif