add/update interface

This commit is contained in:
Lurkars
2020-08-16 16:40:05 +02:00
parent 628ee8fe39
commit b473e88be1
46 changed files with 2785 additions and 1463 deletions
+11 -3
View File
@@ -1,10 +1,18 @@
idf_component_register(
SRCS
"interface.c"
"interface-main.c"
"interface-data.c"
"interface-datetime.c"
"interface-menu.c"
"interface-status.c"
INCLUDE_DIRS "include"
"interface-input.c"
"interface-label.c"
"interface-report.c"
"interface-settings.c"
"interface-wifi.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
ena
ssd1306
ds3231
wifi-controller
)
@@ -1,37 +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.
/**
* @file
*
* @brief interface for changing current date and time
*
*/
#ifndef _interface__DATETIME_H_
#define _interface__DATETIME_H_
typedef enum
{
INTERFACE_DATETIME_STATE_YEAR = 0,
INTERFACE_DATETIME_STATE_MONTH,
INTERFACE_DATETIME_STATE_DAY,
INTERFACE_DATETIME_STATE_HOUR,
INTERFACE_DATETIME_STATE_MINUTE,
INTERFACE_DATETIME_STATE_SECONDS,
} interface_datetime_state_t;
void interface_datetime_start(void);
int interface_datetime_state(void);
#endif
@@ -1,35 +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.
/**
* @file
*
* @brief interface menu to navigate through interface
*
*/
#ifndef _interface__MENU_H_
#define _interface__MENU_H_
typedef enum
{
INTERFACE_MENU_STATE_IDLE = 0,
INTERFACE_MENU_STATE_SELECT_TIME,
INTERFACE_MENU_STATE_SELECT_DEBUG,
INTERFACE_MENU_STATE_SELECT_STATUS,
} interface_menu_state_t;
void interface_menu_start(void);
int interface_menu_get_state(void);
#endif
@@ -1,25 +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.
/**
* @file
*
* @brief interface to show current ENA status (infection risk etc.)
*
*/
#ifndef _interface__STATUS_H_
#define _interface__STATUS_H_
void interface_status_start(void);
#endif
-79
View File
@@ -1,79 +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.
/**
* @file
*
* @brief interface functionality via touch pads for control and setup
*
*/
#ifndef _interface__H_
#define _interface__H_
#define INTERFACE_LOG "INTERFACE" // TAG for Logging
#define TOUCHPAD_FILTER_TOUCH_PERIOD (10)
#define TOUCH_PAD_COUNT (4)
#define TOUCH_PAD_ESC (TOUCH_PAD_NUM0)
#define TOUCH_PAD_OK (TOUCH_PAD_NUM6)
#define TOUCH_PAD_UP (TOUCH_PAD_NUM4)
#define TOUCH_PAD_DOWN (TOUCH_PAD_NUM3)
/**
* @brief different interface states
*/
typedef enum
{
INTERFACE_STATE_IDLE = 0, // ilde state, do nothing
INTERFACE_STATE_MENU, // main menu
INTERFACE_STATE_SET_DATETIME, // set current date and time
INTERFACE_STATE_STATUS, // current status
} interface_state_t;
/**
* @brief callback function on touch event
*/
typedef void (*interface_touch_callback)(void);
/**
* @brief register a callback function for touch event
*
* @param[in] touch_pad id of the touchpad to listen touch
* @param[in] callback callback function
*/
void interface_register_touch_callback(int touch_pad, interface_touch_callback callback);
/**
* @brief get current interface state
*
* @return
* current state the interface is in
*/
int interface_get_state(void);
/**
* @brief set current interface state
*
* @param[in] state new state to set
*/
void interface_set_state(interface_state_t state);
/**
* @brief start interface logic
*
* This will initialize the touch controls and start a task to listen to touch
* inputs and calling the callbacks
*/
void interface_start(void);
#endif
+195
View File
@@ -0,0 +1,195 @@
// 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 "ssd1306.h"
#include "ssd1306-gfx.h"
#include "ena-storage.h"
#include "interface.h"
typedef enum
{
INTERFACE_DATA_DEL_TEK = 0,
INTERFACE_DATA_DEL_EXPOSURE_INFO,
INTERFACE_DATA_DEL_TEMP_RPI,
INTERFACE_DATA_DEL_RPI,
INTERFACE_DATA_DEL_LAST_EXPOSURE,
INTERFACE_DATA_DEL_ALL,
} interface_data_state_t;
static int current_interface_data_state;
static int current_data_index;
static bool confirm_current;
void interface_data_set(void)
{
if (!confirm_current)
{
interface_main_start();
}
else
{
confirm_current = false;
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
}
}
void interface_data_rst(void)
{
if (confirm_current)
{
switch (current_interface_data_state)
{
case INTERFACE_DATA_DEL_TEK:
ena_storage_erase_tek();
break;
case INTERFACE_DATA_DEL_EXPOSURE_INFO:
ena_storage_erase_exposure_information();
break;
case INTERFACE_DATA_DEL_TEMP_RPI:
ena_storage_erase_temporary_beacon();
break;
case INTERFACE_DATA_DEL_RPI:
ena_storage_erase_beacon();
break;
case INTERFACE_DATA_DEL_LAST_EXPOSURE:
ena_storage_write_last_exposure_date(0);
break;
case INTERFACE_DATA_DEL_ALL:
ena_storage_erase();
break;
}
confirm_current = false;
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
}
}
void interface_data_lft(void)
{
interface_wifi_start();
}
void interface_data_rht(void)
{
interface_settings_start();
}
void interface_data_mid(void)
{
if (!confirm_current)
{
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
confirm_current = true;
}
}
void interface_data_up(void)
{
current_interface_data_state--;
if (current_interface_data_state < INTERFACE_DATA_DEL_TEK)
{
current_interface_data_state = INTERFACE_DATA_DEL_ALL;
current_data_index = 3;
}
else if (current_interface_data_state < current_data_index)
{
current_data_index--;
}
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
}
void interface_data_dwn(void)
{
current_interface_data_state++;
if (current_interface_data_state > INTERFACE_DATA_DEL_ALL)
{
current_interface_data_state = INTERFACE_DATA_DEL_TEK;
current_data_index = 0;
}
else if (current_interface_data_state >= (current_data_index + 3))
{
current_data_index++;
}
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
}
void interface_data_display(void)
{
ssd1306_menu_headline(SSD1306_ADDRESS, interface_get_label_text(&interface_text_headline_data), true, 0);
if (confirm_current)
{
ssd1306_text_line_column(SSD1306_ADDRESS, interface_get_label_text(&interface_text_data_del[current_interface_data_state]), 2, 2, false);
ssd1306_text_line_column(SSD1306_ADDRESS, "?", 2, strlen(interface_get_label_text(&interface_text_data_del[current_interface_data_state])) + 2, false);
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_cancel), true, false);
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_ok), false, true);
}
else
{
ssd1306_clear_line(SSD1306_ADDRESS, 5, false);
ssd1306_clear_line(SSD1306_ADDRESS, 7, false);
for (int i = 0; i < 3; i++)
{
int index = i + current_data_index;
if (index <= INTERFACE_DATA_DEL_ALL)
{
if (index == current_interface_data_state)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_right, 8, i * 2 + 2, 8, false);
}
ssd1306_text_line_column(SSD1306_ADDRESS, interface_get_label_text(&interface_text_data_del[index]), i * 2 + 2, 2, false);
}
}
}
}
void interface_data_start(void)
{
current_interface_data_state = INTERFACE_DATA_DEL_TEK;
interface_register_button_callback(INTERFACE_BUTTON_RST, &interface_data_rst);
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_data_set);
interface_register_button_callback(INTERFACE_BUTTON_LFT, &interface_data_lft);
interface_register_button_callback(INTERFACE_BUTTON_RHT, &interface_data_rht);
interface_register_button_callback(INTERFACE_BUTTON_MID, &interface_data_mid);
interface_register_button_callback(INTERFACE_BUTTON_UP, &interface_data_up);
interface_register_button_callback(INTERFACE_BUTTON_DWN, &interface_data_dwn);
interface_set_display_function(&interface_data_display);
ESP_LOGD(INTERFACE_LOG, "start delete data interface");
}
+122 -27
View File
@@ -11,33 +11,58 @@
// 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 <string.h>
#include <time.h>
#include <sys/time.h>
#include "esp_log.h"
#include "driver/gpio.h"
#include "ds3231.h"
#include "ssd1306.h"
#include "ssd1306-gfx.h"
#include "interface.h"
#include "driver/touch_pad.h"
#include "interface-menu.h"
#include "interface-datetime.h"
static int current_interface_datetime_state = INTERFACE_DATETIME_STATE_YEAR;
const uint32_t interface_datetime_steps[6] = {
31557600, 2629800, 86400, 3600, 60, 1};
void interface_datetime_esc(void)
typedef enum
{
interface_menu_start();
INTERFACE_DATETIME_STATE_HOUR = 0,
INTERFACE_DATETIME_STATE_MINUTE,
INTERFACE_DATETIME_STATE_SECONDS,
INTERFACE_DATETIME_STATE_DAY,
INTERFACE_DATETIME_STATE_MONTH,
INTERFACE_DATETIME_STATE_YEAR,
} interface_datetime_state_t;
static int current_interface_datetime_state;
const uint32_t interface_datetime_steps[6] = {3600, 60, 1, 86400, 2629800, 31557600};
int interface_datetime_state(void)
{
return current_interface_datetime_state;
}
void interface_datetime_ok(void)
void interface_datetime_set(void)
{
interface_main_start();
}
void interface_datetime_lft(void)
{
interface_settings_start();
}
void interface_datetime_rht(void)
{
interface_wifi_start();
}
void interface_datetime_mid(void)
{
current_interface_datetime_state++;
if (current_interface_datetime_state > INTERFACE_DATETIME_STATE_SECONDS)
if (current_interface_datetime_state > INTERFACE_DATETIME_STATE_YEAR)
{
current_interface_datetime_state = INTERFACE_DATETIME_STATE_YEAR;
current_interface_datetime_state = INTERFACE_DATETIME_STATE_HOUR;
}
ESP_LOGD(INTERFACE_LOG, "datetime to %d", current_interface_datetime_state);
}
@@ -49,30 +74,100 @@ void interface_datetime_up(void)
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
ds3231_set_time(gmtime(&curtime));
ESP_LOGD(INTERFACE_LOG, "increment %d about %u %s", current_interface_datetime_state, interface_datetime_steps[current_interface_datetime_state], ctime(&curtime));
}
void interface_datetime_down(void)
void interface_datetime_dwn(void)
{
time_t curtime = time(NULL);
curtime -= interface_datetime_steps[current_interface_datetime_state];
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
ds3231_set_time(gmtime(&curtime));
ESP_LOGD(INTERFACE_LOG, "decrement %d about %u %s", current_interface_datetime_state, interface_datetime_steps[current_interface_datetime_state], ctime(&curtime));
}
void interface_datetime_display(void)
{
static time_t current_timstamp;
static struct tm *current_tm;
static char time_buffer[9];
static char date_buffer[32];
ssd1306_menu_headline(SSD1306_ADDRESS, interface_get_label_text(&interface_text_headline_time), true, 0);
static char edit_char[3];
static int edit_line = 3;
int edit_length = 2;
int edit_offset = 0;
ssd1306_clear_line(SSD1306_ADDRESS, edit_line - 1, false);
ssd1306_clear_line(SSD1306_ADDRESS, edit_line + 1, false);
time(&current_timstamp);
current_tm = localtime(&current_timstamp);
strftime(time_buffer, 16, INTERFACE_FORMAT_TIME, current_tm);
ssd1306_text_line_column(SSD1306_ADDRESS, time_buffer, 3, 4, false);
sprintf(date_buffer, "%02d %s %02d",
current_tm->tm_mday,
interface_get_label_text(&interface_texts_month[current_tm->tm_mon]),
current_tm->tm_year - 100);
ssd1306_text_line_column(SSD1306_ADDRESS, date_buffer, 6, 4, false);
switch (interface_datetime_state())
{
case INTERFACE_DATETIME_STATE_YEAR:
memcpy(&edit_char, &date_buffer[7], edit_length);
edit_line = 6;
edit_offset = 11;
break;
case INTERFACE_DATETIME_STATE_DAY:
memcpy(&edit_char, &date_buffer[0], edit_length);
edit_line = 6;
edit_offset = 4;
break;
case INTERFACE_DATETIME_STATE_MONTH:
edit_length = 3;
memcpy(&edit_char, &date_buffer[3], edit_length);
edit_line = 6;
edit_offset = 7;
break;
case INTERFACE_DATETIME_STATE_HOUR:
memcpy(&edit_char, &time_buffer[0], edit_length);
edit_line = 3;
edit_offset = 4;
break;
case INTERFACE_DATETIME_STATE_MINUTE:
memcpy(&edit_char, &time_buffer[3], edit_length);
edit_line = 3;
edit_offset = 7;
break;
case INTERFACE_DATETIME_STATE_SECONDS:
memcpy(&edit_char, &time_buffer[6], edit_length);
edit_line = 3;
edit_offset = 10;
break;
}
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_up, 8, edit_line - 1, edit_offset * 8 + 4, false);
ssd1306_chars(SSD1306_ADDRESS, edit_char, edit_length, edit_line, edit_offset, true);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_down, 8, edit_line + 1, edit_offset * 8 + 4, false);
}
void interface_datetime_start(void)
{
interface_set_state(INTERFACE_STATE_SET_DATETIME);
interface_register_touch_callback(TOUCH_PAD_ESC, &interface_datetime_esc);
interface_register_touch_callback(TOUCH_PAD_OK, &interface_datetime_ok);
interface_register_touch_callback(TOUCH_PAD_UP, &interface_datetime_up);
interface_register_touch_callback(TOUCH_PAD_DOWN, &interface_datetime_down);
current_interface_datetime_state = INTERFACE_DATETIME_STATE_HOUR;
interface_register_button_callback(INTERFACE_BUTTON_LFT, &interface_datetime_lft);
interface_register_button_callback(INTERFACE_BUTTON_RHT, &interface_datetime_rht);
interface_register_button_callback(INTERFACE_BUTTON_MID, &interface_datetime_mid);
interface_register_button_callback(INTERFACE_BUTTON_UP, &interface_datetime_up);
interface_register_button_callback(INTERFACE_BUTTON_DWN, &interface_datetime_dwn);
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_datetime_set);
interface_register_button_callback(INTERFACE_BUTTON_RST, NULL);
interface_set_display_function(&interface_datetime_display);
ESP_LOGD(INTERFACE_LOG, "start datetime interface");
}
int interface_datetime_state(void)
{
return current_interface_datetime_state;
}
+318
View File
@@ -0,0 +1,318 @@
// 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 "ssd1306.h"
#include "ssd1306-gfx.h"
#include "interface.h"
static interface_input_callback current_input_callback_rst;
static interface_input_callback current_input_callback_set;
static char current_text[255];
static uint8_t current_cursor;
static char current_char_set[32];
static uint8_t current_char_index;
static uint8_t current_limit;
static uint8_t current_max_index;
static char char_set_uppercase[32];
static char char_set_lowercase[32];
static char char_set_numeric[32];
static char char_set_special1[32];
static char char_set_special_uppercasecase[32];
static char char_set_special_lowercase[32];
void interface_input_set_char_set(void)
{
char *ret;
char cur_char = current_text[current_cursor];
if ((ret = strchr(char_set_lowercase, cur_char)) != NULL)
{
strcpy(current_char_set, char_set_lowercase);
current_char_index = strlen(current_char_set) - strlen(ret);
}
else if ((ret = strchr(char_set_numeric, cur_char)) != NULL)
{
strcpy(current_char_set, char_set_numeric);
current_char_index = strlen(current_char_set) - strlen(ret);
}
else if ((ret = strchr(char_set_special1, cur_char)) != NULL)
{
strcpy(current_char_set, char_set_special1);
current_char_index = strlen(current_char_set) - strlen(ret);
}
else if ((ret = strchr(char_set_special_uppercasecase, cur_char)) != NULL)
{
strcpy(current_char_set, char_set_special_uppercasecase);
current_char_index = strlen(current_char_set) - strlen(ret);
}
else if ((ret = strchr(char_set_special_lowercase, cur_char)) != NULL)
{
strcpy(current_char_set, char_set_special_lowercase);
current_char_index = strlen(current_char_set) - strlen(ret);
}
else if ((ret = strchr(char_set_uppercase, cur_char)) != NULL)
{
strcpy(current_char_set, char_set_uppercase);
current_char_index = strlen(current_char_set) - strlen(ret);
}
printf("current_char_set: %d %s\n", strlen(current_char_set), current_char_set);
}
void interface_input_set(void)
{
if (current_input_callback_rst != NULL)
{
(*current_input_callback_rst)(current_text, current_cursor);
}
}
void interface_input_rst(void)
{
if (current_input_callback_set != NULL)
{
(*current_input_callback_set)(current_text, current_cursor);
}
}
void interface_input_lft(void)
{
if (current_cursor > 0)
{
current_cursor--;
interface_input_set_char_set();
}
}
void interface_input_rht(void)
{
if (current_cursor < current_limit)
{
current_cursor++;
if (current_cursor > current_max_index)
{
current_max_index = current_cursor;
strcpy(current_char_set, char_set_uppercase);
current_char_index = 0;
current_text[current_cursor] = current_char_set[current_char_index];
}
else
{
interface_input_set_char_set();
}
}
}
void interface_input_mid(void)
{
if (current_char_set[0] == char_set_uppercase[0])
{
strcpy(current_char_set, char_set_lowercase);
}
else if (current_char_set[0] == char_set_lowercase[0])
{
strcpy(current_char_set, char_set_numeric);
}
else if (current_char_set[0] == char_set_numeric[0])
{
strcpy(current_char_set, char_set_special1);
}
else if (current_char_set[0] == char_set_special1[0])
{
strcpy(current_char_set, char_set_special_uppercasecase);
}
else if (current_char_set[0] == char_set_special_uppercasecase[0])
{
strcpy(current_char_set, char_set_special_lowercase);
}
else if (current_char_set[0] == char_set_special_lowercase[0])
{
strcpy(current_char_set, char_set_uppercase);
}
current_char_index = 0;
current_text[current_cursor] = current_char_set[current_char_index];
printf("current_char_set: %d %s\n", strlen(current_char_set), current_char_set);
}
void interface_input_up(void)
{
if (current_char_index == 0)
{
current_char_index = strlen(current_char_set) - 1;
}
else
{
current_char_index--;
}
current_text[current_cursor] = current_char_set[current_char_index];
}
void interface_input_dwn(void)
{
if (current_char_index == strlen(current_char_set) - 1)
{
current_char_index = 0;
}
else
{
current_char_index++;
}
current_text[current_cursor] = current_char_set[current_char_index];
}
void interface_input_display(void)
{
// buttons
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_cancel), true, false);
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_ok), false, true);
size_t start = 0;
uint8_t display_cursor = current_cursor + 1;
if (current_cursor > 13)
{
start = current_cursor - 13;
display_cursor = 14;
}
// arrow
if (current_cursor > 0)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_left, 8, 2, 0, false);
}
else
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_clear, 8, 2, 0, false);
}
// bounday
ssd1306_text_line_column(SSD1306_ADDRESS, "______________", 2, 1, false);
// arrow
if (current_cursor < current_limit)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_right, 8, 2, 15 * 8, false);
}
else
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_clear, 8, 2, 15 * 8, false);
}
// text
size_t text_length = strlen(current_text);
if (strlen(current_text) > 14)
{
text_length = 14;
}
size_t length = text_length * 8;
uint8_t *textdata = calloc(length, sizeof(uint8_t));
for (uint8_t i = 0; i < text_length; i++)
{
memcpy(&textdata[i * 8], ssd1306_gfx_font[(uint8_t)current_text[i + start] - 32], 8);
}
ssd1306_data(SSD1306_ADDRESS, textdata, length, 2, 8, true);
free(textdata);
// clear
ssd1306_clear_line(SSD1306_ADDRESS, 0, false);
ssd1306_clear_line(SSD1306_ADDRESS, 1, false);
ssd1306_clear_line(SSD1306_ADDRESS, 3, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
uint8_t current_char = (uint8_t)current_char_set[current_char_index] - 32;
uint8_t prev_char = (uint8_t)current_char_set[current_char_index - 1] - 32;
uint8_t next_char = (uint8_t)current_char_set[current_char_index + 1] - 32;
if (current_char_index == 0)
{
prev_char = (uint8_t)current_char_set[strlen(current_char_set) - 1] - 32;
}
if (current_char_index == strlen(current_char_set) - 1)
{
next_char = (uint8_t)current_char_set[0] - 32;
}
// arrow
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_up, 8, 0, display_cursor * 8, false);
// upper char
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_font[prev_char], 8, 1, display_cursor * 8, false);
// sel char
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_font[current_char], 8, 2, display_cursor * 8, false);
// lower char
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_font[next_char], 8, 3, display_cursor * 8, false);
// arrow
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_down, 8, 4, display_cursor * 8, false);
}
void interface_input_set_text(char *text)
{
ssd1306_utf8_to_ascii(text, current_text);
current_cursor = strlen(current_text) - 1;
current_max_index = current_cursor;
interface_input_set_char_set();
}
void interface_input(interface_input_callback callback_rst, interface_input_callback callback_set, uint8_t limit)
{
current_input_callback_rst = callback_rst;
current_input_callback_set = callback_set;
current_cursor = 0;
current_limit = limit - 1;
ssd1306_utf8_to_ascii("ABCDEFGHIJKLMNOPQRSTUVWXYZ", char_set_uppercase);
ssd1306_utf8_to_ascii("abcdefghijklmnopqrstuvwxyz", char_set_lowercase);
ssd1306_utf8_to_ascii(" !\"#$%&'()*+,-,&:;<=>@[\\]^_´`{}", char_set_special1);
ssd1306_utf8_to_ascii("0123456789", char_set_numeric);
ssd1306_utf8_to_ascii("ÄÖÜ", char_set_special_uppercasecase);
ssd1306_utf8_to_ascii("äöü", char_set_special_lowercase);
strcpy(current_char_set, char_set_uppercase);
printf("char_set_uppercase: %d %s\n", strlen(char_set_uppercase), char_set_uppercase);
printf("char_set_lowercase: %d %s\n", strlen(char_set_lowercase), char_set_lowercase);
printf("char_set_numeric: %d %s\n", strlen(char_set_numeric), char_set_numeric);
printf("char_set_special1: %d %s\n", strlen(char_set_special1), char_set_special1);
printf("char_set_special_uppercasecase: %d %s\n", strlen(char_set_special_uppercasecase), char_set_special_uppercasecase);
printf("char_set_special_lowercase: %d %s\n", strlen(char_set_special_lowercase), char_set_special_lowercase);
current_char_index = 0;
current_max_index = 0;
if (current_limit == 0)
{
current_limit = 255;
}
current_text[current_cursor] = current_char_set[current_char_index];
interface_register_button_callback(INTERFACE_BUTTON_RST, &interface_input_rst);
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_input_set);
interface_register_button_callback(INTERFACE_BUTTON_LFT, &interface_input_lft);
interface_register_button_callback(INTERFACE_BUTTON_RHT, &interface_input_rht);
interface_register_button_callback(INTERFACE_BUTTON_MID, &interface_input_mid);
interface_register_button_callback(INTERFACE_BUTTON_UP, &interface_input_up);
interface_register_button_callback(INTERFACE_BUTTON_DWN, &interface_input_dwn);
interface_set_display_function(&interface_input_display);
ESP_LOGD(INTERFACE_LOG, "start input interface");
}
+139
View File
@@ -0,0 +1,139 @@
// 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 texts for intefaces
*
*/
#include <string.h>
#include "interface.h"
static interface_locale_t current_locale = EN;
void interface_init_label(void)
{
// EN
interface_text_button_cancel.text[EN] = "CANCEL";
interface_text_button_ok.text[EN] = "OK";
interface_text_button_menu.text[EN] = "MENU";
interface_text_button_report.text[EN] = "REPORT";
interface_text_headline_tan.text[EN] = "ENTER TAN";
interface_text_headline_wifi.text[EN] = "WIFI";
interface_text_headline_time.text[EN] = "TIME/DATE";
interface_text_headline_data.text[EN] = "DEL DATA";
interface_text_headline_settings.text[EN] = "SETTING";
interface_text_headline_debug.text[EN] = "DEBUG";
interface_text_settings_locale.text[EN] = "Language:";
interface_text_settings_locales[EN].text[EN] = "EN";
interface_text_settings_locales[DE].text[EN] = "DE";
interface_text_settings_timezone.text[EN] = "Timezone:";
interface_text_wifi_scanning.text[EN] = "Scanning...";
interface_text_data_del[0].text[EN] = "DEL TEK";
interface_text_data_del[1].text[EN] = "DEL Exp Info";
interface_text_data_del[2].text[EN] = "DEL Tmp RPI";
interface_text_data_del[3].text[EN] = "DEL RPI";
interface_text_data_del[4].text[EN] = "DEL Lst Upd.";
interface_text_data_del[5].text[EN] = "DEL All Data";
interface_texts_weekday[0].text[EN] = "Sun";
interface_texts_weekday[1].text[EN] = "Mon";
interface_texts_weekday[2].text[EN] = "Tue";
interface_texts_weekday[3].text[EN] = "Wed";
interface_texts_weekday[4].text[EN] = "Thu";
interface_texts_weekday[5].text[EN] = "Fri";
interface_texts_weekday[6].text[EN] = "Sat";
interface_texts_month[0].text[EN] = "Jan";
interface_texts_month[1].text[EN] = "Feb";
interface_texts_month[2].text[EN] = "Mar";
interface_texts_month[3].text[EN] = "Apr";
interface_texts_month[4].text[EN] = "May";
interface_texts_month[5].text[EN] = "Jun";
interface_texts_month[6].text[EN] = "Jul";
interface_texts_month[7].text[EN] = "Aug";
interface_texts_month[8].text[EN] = "Sep";
interface_texts_month[9].text[EN] = "Oct";
interface_texts_month[10].text[EN] = "Nov";
interface_texts_month[11].text[EN] = "Dec";
// DE
interface_text_button_cancel.text[DE] = "ZURÜCK";
interface_text_button_ok.text[DE] = "OK";
interface_text_button_menu.text[DE] = "MENU";
interface_text_button_report.text[DE] = "MELDEN";
interface_text_headline_tan.text[DE] = "TAN EING.";
interface_text_headline_wifi.text[DE] = "WLAN";
interface_text_headline_time.text[DE] = "ZEIT/DATUM";
interface_text_headline_data.text[DE] = "DATEN ENTF";
interface_text_headline_settings.text[DE] = "EINSTEL.";
interface_text_headline_debug.text[DE] = "DEBUG";
interface_text_settings_locale.text[DE] = "Sprache:";
interface_text_settings_locales[EN].text[DE] = "EN";
interface_text_settings_locales[DE].text[DE] = "DE";
interface_text_settings_timezone.text[DE] = "Zeitzone:";
interface_text_wifi_scanning.text[DE] = "Scannen...";
interface_text_data_del[0].text[DE] = "ENTF TEK";
interface_text_data_del[1].text[DE] = "ENTF Exp Info";
interface_text_data_del[2].text[DE] = "ENTF Tmp RPI";
interface_text_data_del[3].text[DE] = "ENTF RPI";
interface_text_data_del[4].text[DE] = "ENTF letz. Up";
interface_text_data_del[5].text[DE] = "ENTF Daten";
interface_texts_weekday[0].text[DE] = "So.";
interface_texts_weekday[1].text[DE] = "Mo.";
interface_texts_weekday[2].text[DE] = "Di.";
interface_texts_weekday[3].text[DE] = "Mi.";
interface_texts_weekday[4].text[DE] = "Do.";
interface_texts_weekday[5].text[DE] = "Fr.";
interface_texts_weekday[6].text[DE] = "Sa.";
interface_texts_month[0].text[DE] = "Jan";
interface_texts_month[1].text[DE] = "Feb";
interface_texts_month[2].text[DE] = "Mär";
interface_texts_month[3].text[DE] = "Apr";
interface_texts_month[4].text[DE] = "Mai";
interface_texts_month[5].text[DE] = "Jun";
interface_texts_month[6].text[DE] = "Jul";
interface_texts_month[7].text[DE] = "Aug";
interface_texts_month[8].text[DE] = "Sep";
interface_texts_month[9].text[DE] = "Okt";
interface_texts_month[10].text[DE] = "Nov";
interface_texts_month[11].text[DE] = "Dez";
}
interface_locale_t interface_get_locale(void)
{
return current_locale;
}
void interface_set_locale(interface_locale_t locale)
{
current_locale = locale;
}
char *interface_get_label_text(interface_label_t *label)
{
return label->text[current_locale];
}
+143
View File
@@ -0,0 +1,143 @@
// 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 "esp_log.h"
#include "driver/gpio.h"
#include "ds3231.h"
#include "ssd1306.h"
#include "ssd1306-gfx.h"
#include "wifi-controller.h"
#include "ena-storage.h"
#include "ena-exposure.h"
#include "interface.h"
static time_t current_timstamp;
static struct tm *current_tm;
static char time_buffer[32];
static char text_buffer[32];
static bool wifi_connected;
void interface_main_set(void)
{
interface_datetime_start();
}
void interface_main_rst(void)
{
interface_report_start();
}
void interface_main_display(void)
{
if (wifi_connected)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_wifi, 8, 0, 0, false);
}
else
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_cross, 8, 0, 0, false);
}
time(&current_timstamp);
current_tm = localtime(&current_timstamp);
// curent date
sprintf(text_buffer, "%s %s %d",
interface_get_label_text(&interface_texts_weekday[current_tm->tm_wday]),
interface_get_label_text(&interface_texts_month[current_tm->tm_mon]),
current_tm->tm_mday);
ssd1306_text_line_column(SSD1306_ADDRESS, text_buffer, 0, 16 - strlen(text_buffer), false);
// current time
strftime(time_buffer, 16, INTERFACE_FORMAT_TIME, current_tm);
ssd1306_text_line_column(SSD1306_ADDRESS, time_buffer, 1, 16 - strlen(time_buffer), false);
}
void interface_main_start(void)
{
interface_register_button_callback(INTERFACE_BUTTON_RST, &interface_main_rst);
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_main_set);
interface_register_button_callback(INTERFACE_BUTTON_LFT, NULL);
interface_register_button_callback(INTERFACE_BUTTON_RHT, NULL);
interface_register_button_callback(INTERFACE_BUTTON_MID, NULL);
interface_register_button_callback(INTERFACE_BUTTON_UP, NULL);
interface_register_button_callback(INTERFACE_BUTTON_DWN, NULL);
if (wifi_controller_connection() != NULL)
{
wifi_connected = true;
}
else
{
wifi_connected = false;
}
interface_set_display_function(&interface_main_display);
ena_exposure_summary_t *current_exposure_summary = ena_exposure_current_summary();
time(&current_timstamp);
uint32_t last_update = ena_storage_read_last_exposure_date();
// status unknown if no update or last update older than two days
if (last_update == 0 || ((current_timstamp - last_update) / (60 * 60 * 24)) > 2)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_question[0], 24, 0, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_question[1], 24, 1, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_question[2], 24, 2, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_question[3], 24, 3, 12, false);
}
else if (current_exposure_summary->max_risk_score < 100)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_smile[0], 24, 0, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_smile[1], 24, 1, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_smile[2], 24, 2, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_smile[3], 24, 3, 12, false);
}
else
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_sad[0], 24, 0, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_sad[1], 24, 1, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_sad[2], 24, 2, 12, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_sad[3], 24, 3, 12, false);
}
// clock icon
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_clock, 8, 4, 8, false);
// last update
struct tm *last_update_tm = localtime((time_t*) &last_update);
sprintf(time_buffer, "%02d %s %02d:%02d",
last_update_tm->tm_mday,
interface_get_label_text(&interface_texts_month[last_update_tm->tm_mon]),
last_update_tm->tm_hour,
last_update_tm->tm_min);
if (last_update != 0)
{
ssd1306_text_line_column(SSD1306_ADDRESS, time_buffer, 4, 3, false);
}
// buttons
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_menu), true, false);
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_report), false, true);
ESP_LOGD(INTERFACE_LOG, "start main interface");
}
-88
View File
@@ -1,88 +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 <stdio.h>
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "interface.h"
#include "interface-datetime.h"
#include "interface-status.h"
#include "interface-menu.h"
static int current_interface_menu_state = INTERFACE_MENU_STATE_IDLE;
void interface_menu_ok(void)
{
if (current_interface_menu_state == INTERFACE_MENU_STATE_SELECT_TIME)
{
interface_datetime_start();
}
else if (current_interface_menu_state == INTERFACE_MENU_STATE_SELECT_STATUS)
{
interface_status_start();
}
else if (current_interface_menu_state == INTERFACE_MENU_STATE_SELECT_DEBUG)
{
}
else if (current_interface_menu_state == INTERFACE_MENU_STATE_IDLE)
{
if (interface_get_state() == INTERFACE_STATE_MENU)
{
interface_set_state(INTERFACE_STATE_IDLE);
interface_register_touch_callback(TOUCH_PAD_UP, NULL);
interface_register_touch_callback(TOUCH_PAD_DOWN, NULL);
}
else
{
interface_menu_start();
}
}
}
void interface_menu_up(void)
{
current_interface_menu_state--;
if (current_interface_menu_state < INTERFACE_MENU_STATE_IDLE)
{
current_interface_menu_state = INTERFACE_MENU_STATE_SELECT_STATUS;
}
ESP_LOGD(INTERFACE_LOG, "menu up to %d", current_interface_menu_state);
}
void interface_menu_down(void)
{
current_interface_menu_state++;
if (current_interface_menu_state > INTERFACE_MENU_STATE_SELECT_STATUS)
{
current_interface_menu_state = INTERFACE_MENU_STATE_IDLE;
}
ESP_LOGD(INTERFACE_LOG, "menu down to %d", current_interface_menu_state);
}
void interface_menu_start(void)
{
interface_set_state(INTERFACE_STATE_MENU);
interface_register_touch_callback(TOUCH_PAD_ESC, NULL);
interface_register_touch_callback(TOUCH_PAD_OK, &interface_menu_ok);
interface_register_touch_callback(TOUCH_PAD_UP, &interface_menu_up);
interface_register_touch_callback(TOUCH_PAD_DOWN, &interface_menu_down);
ESP_LOGD(INTERFACE_LOG, "start menu interface");
}
int interface_menu_get_state(void)
{
return current_interface_menu_state;
}
+177
View File
@@ -0,0 +1,177 @@
// 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 "ssd1306.h"
#include "ssd1306-gfx.h"
#include "wifi-controller.h"
#include "interface.h"
static int interface_report_tan[10] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
static int interface_report_tan_index = 0;
void interface_report_set(void)
{
interface_main_start();
}
void interface_report_rst(void)
{
// TODO: REPORT here, check tan etc.
}
void interface_report_lft(void)
{
if (interface_report_tan_index > 0)
{
interface_report_tan_index--;
}
ESP_LOGD(INTERFACE_LOG, "tan index %d", interface_report_tan_index);
}
void interface_report_rht(void)
{
if (interface_report_tan_index < 9)
{
interface_report_tan_index++;
}
ESP_LOGD(INTERFACE_LOG, "tan index %d", interface_report_tan_index);
}
void interface_report_up(void)
{
if (interface_report_tan[interface_report_tan_index] > 0)
{
interface_report_tan[interface_report_tan_index]--;
}
else
{
interface_report_tan[interface_report_tan_index] = 9;
}
}
void interface_report_dwn(void)
{
if (interface_report_tan[interface_report_tan_index] < 9)
{
interface_report_tan[interface_report_tan_index]++;
}
else
{
interface_report_tan[interface_report_tan_index] = 0;
}
}
void interface_report_display(void)
{
ssd1306_menu_headline(SSD1306_ADDRESS, interface_get_label_text(&interface_text_headline_tan), false, 0);
// buttons
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_cancel), true, false);
ssd1306_set_button(SSD1306_ADDRESS, interface_get_label_text(&interface_text_button_ok), false, true);
static char tan_buffer[10] = {0};
if (interface_report_tan_index > 0)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_left, 8, 3, 8, false);
}
else
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_clear, 8, 3, 8, false);
}
if (interface_report_tan_index < 9)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_right, 8, 3, 112, false);
}
else
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_clear, 8, 3, 112, false);
}
for (int i = 0; i < interface_report_tan_index + 1; i++)
{
sprintf(&tan_buffer[i], "%d", interface_report_tan[i]);
}
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_text_line_column(SSD1306_ADDRESS, "-", 3, 5, false);
ssd1306_text_line_column(SSD1306_ADDRESS, "-", 3, 9, false);
ssd1306_text_line_column(SSD1306_ADDRESS, "___", 3, 2, false);
ssd1306_text_line_column(SSD1306_ADDRESS, "___", 3, 6, false);
ssd1306_text_line_column(SSD1306_ADDRESS, "____", 3, 10, false);
int offset = 2;
for (int i = 0; i < 3; i++)
{
if (i < interface_report_tan_index)
{
ssd1306_chars(SSD1306_ADDRESS, &tan_buffer[i], 1, 3, i + offset, true);
}
}
if (interface_report_tan_index > 2)
{
offset = 3;
for (int i = 3; i < 6; i++)
{
if (i < interface_report_tan_index)
{
ssd1306_chars(SSD1306_ADDRESS, &tan_buffer[i], 1, 3, i + offset, true);
}
}
}
if (interface_report_tan_index > 5)
{
offset = 4;
for (int i = 6; i < 10; i++)
{
if (i < interface_report_tan_index)
{
ssd1306_chars(SSD1306_ADDRESS, &tan_buffer[i], 1, 3, i + offset, true);
}
}
}
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_up, 8, 2, interface_report_tan_index * 8 + offset * 8, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_down, 8, 4, interface_report_tan_index * 8 + offset * 8, false);
ssd1306_chars(SSD1306_ADDRESS, &tan_buffer[interface_report_tan_index], 1, 3, interface_report_tan_index + offset, false);
}
void interface_report_start(void)
{
interface_register_button_callback(INTERFACE_BUTTON_RST, &interface_report_rst);
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_report_set);
interface_register_button_callback(INTERFACE_BUTTON_LFT, &interface_report_lft);
interface_register_button_callback(INTERFACE_BUTTON_RHT, &interface_report_rht);
interface_register_button_callback(INTERFACE_BUTTON_UP, &interface_report_up);
interface_register_button_callback(INTERFACE_BUTTON_DWN, &interface_report_dwn);
interface_register_button_callback(INTERFACE_BUTTON_MID, NULL);
interface_set_display_function(&interface_report_display);
ESP_LOGD(INTERFACE_LOG, "start report interface");
}
+147
View File
@@ -0,0 +1,147 @@
// 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 "ssd1306.h"
#include "ssd1306-gfx.h"
#include "ena-storage.h"
#include "interface.h"
typedef enum
{
INTERFACE_SETTINGS_LOCALE = 0,
INTERFACE_SETTINGS_TIMEZONE,
} interface_settings_state_t;
static int current_interface_settings_state;
void interface_settings_set(void)
{
interface_main_start();
}
void interface_settings_rst(void)
{
}
void interface_settings_lft(void)
{
interface_data_start();
}
void interface_settings_rht(void)
{
interface_datetime_start();
}
void interface_settings_mid(void)
{
current_interface_settings_state++;
if (current_interface_settings_state > INTERFACE_SETTINGS_TIMEZONE)
{
current_interface_settings_state = INTERFACE_SETTINGS_LOCALE;
}
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 3, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 5, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
ssd1306_clear_line(SSD1306_ADDRESS, 7, false);
}
void interface_settings_up(void)
{
if (current_interface_settings_state == INTERFACE_SETTINGS_LOCALE)
{
if (interface_get_locale() == 0)
{
interface_set_locale(INTERFACE_NUM_LOCALE - 1);
}
else
{
interface_set_locale(interface_get_locale() - 1);
}
}
}
void interface_settings_dwn(void)
{
if (current_interface_settings_state == INTERFACE_SETTINGS_LOCALE)
{
if (interface_get_locale() + 1 == INTERFACE_NUM_LOCALE)
{
interface_set_locale(0);
}
else
{
interface_set_locale(interface_get_locale() + 1);
}
}
}
void interface_settings_display(void)
{
ssd1306_menu_headline(SSD1306_ADDRESS, interface_get_label_text(&interface_text_headline_settings), true, 0);
ssd1306_text_line_column(SSD1306_ADDRESS, interface_get_label_text(&interface_text_settings_locale), 3, 1, false);
ssd1306_text_line_column(SSD1306_ADDRESS, interface_get_label_text(&interface_text_settings_timezone), 6, 1, false);
if (current_interface_settings_state == INTERFACE_SETTINGS_LOCALE)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_up, 8, 2, 12 * 8 + 4, false);
ssd1306_text_line_column(SSD1306_ADDRESS,
interface_get_label_text(&interface_text_settings_locales[interface_get_locale()]), 3, 12, true);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_down, 8, 4, 12 * 8 + 4, false);
}
else
{
ssd1306_text_line_column(SSD1306_ADDRESS,
interface_get_label_text(&interface_text_settings_locales[interface_get_locale()]), 3, 12, true);
}
if (current_interface_settings_state == INTERFACE_SETTINGS_TIMEZONE)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_up, 8, 5, 12 * 8 + 4, false);
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_down, 8, 7, 12 * 8 + 4, false);
}
}
void interface_settings_start(void)
{
current_interface_settings_state = INTERFACE_SETTINGS_LOCALE;
interface_register_button_callback(INTERFACE_BUTTON_RST, &interface_settings_rst);
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_settings_set);
interface_register_button_callback(INTERFACE_BUTTON_LFT, &interface_settings_lft);
interface_register_button_callback(INTERFACE_BUTTON_RHT, &interface_settings_rht);
interface_register_button_callback(INTERFACE_BUTTON_MID, &interface_settings_mid);
interface_register_button_callback(INTERFACE_BUTTON_UP, &interface_settings_up);
interface_register_button_callback(INTERFACE_BUTTON_DWN, &interface_settings_dwn);
interface_set_display_function(&interface_settings_display);
ESP_LOGD(INTERFACE_LOG, "start settings interface");
}
-37
View File
@@ -1,37 +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 <stdio.h>
#include "esp_log.h"
#include "driver/touch_pad.h"
#include "interface.h"
#include "interface-menu.h"
#include "interface-status.h"
void interface_status_esc(void)
{
interface_menu_start();
}
void interface_status_start(void)
{
interface_set_state(INTERFACE_STATE_STATUS);
interface_register_touch_callback(TOUCH_PAD_ESC, &interface_status_esc);
interface_register_touch_callback(TOUCH_PAD_OK, NULL);
interface_register_touch_callback(TOUCH_PAD_UP, NULL);
interface_register_touch_callback(TOUCH_PAD_DOWN, NULL);
ESP_LOGD(INTERFACE_LOG, "start status interface");
}
+183
View File
@@ -0,0 +1,183 @@
// 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 "ssd1306.h"
#include "ssd1306-gfx.h"
#include "wifi-controller.h"
#include "interface.h"
#define APS_TO_DISPLAY 3
wifi_ap_record_t ap_info[10];
uint16_t ap_count = 0;
int ap_index = 0;
int ap_selected = 0;
static wifi_config_t current_wifi_config;
void interface_wifi_input_rst(char *text, uint8_t cursor)
{
interface_wifi_start();
}
void interface_wifi_input_set(char *text, uint8_t cursor)
{
memcpy(current_wifi_config.sta.password, text, cursor + 1);
ESP_LOGD(INTERFACE_LOG, "ssid: '%s' password '%s'", current_wifi_config.sta.ssid, current_wifi_config.sta.password);
if (wifi_controller_connect(current_wifi_config) == ESP_OK)
{
interface_main_start();
}
else
{
// what happens here?
interface_wifi_start();
}
}
void interface_wifi_set(void)
{
interface_main_start();
}
void interface_wifi_lft(void)
{
interface_datetime_start();
}
void interface_wifi_rht(void)
{
interface_data_start();
}
void interface_wifi_mid(void)
{
memset(&current_wifi_config, 0, sizeof(wifi_config_t));
memcpy(current_wifi_config.sta.ssid, ap_info[ap_selected].ssid, strlen((char *)ap_info[ap_selected].ssid));
interface_input(&interface_wifi_input_rst, &interface_wifi_input_set, 64);
}
void interface_wifi_up(void)
{
ap_selected--;
if (ap_selected < 0)
{
ap_selected = ap_count - 1;
if (ap_count - APS_TO_DISPLAY < 0)
{
ap_index = 0;
}
else
{
ap_index = ap_count - APS_TO_DISPLAY;
}
}
else if (ap_selected < ap_index)
{
ap_index--;
}
}
void interface_wifi_dwn(void)
{
ap_selected++;
if (ap_selected >= ap_count)
{
ap_selected = 0;
ap_index = 0;
}
else if (ap_selected >= (ap_index + APS_TO_DISPLAY))
{
ap_index++;
}
}
void interface_wifi_display(void)
{
ssd1306_menu_headline(SSD1306_ADDRESS, interface_get_label_text(&interface_text_headline_wifi), true, 0);
if (ap_count > 0)
{
ssd1306_clear_line(SSD1306_ADDRESS, 2, false);
ssd1306_clear_line(SSD1306_ADDRESS, 4, false);
ssd1306_clear_line(SSD1306_ADDRESS, 6, false);
for (int i = 0; i < 3; i++)
{
int index = i + ap_index;
if (index < ap_count)
{
if (index == ap_selected)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_arrow_right, 8, i * 2 + 2, 8, false);
}
if (sizeof(ap_info[i].ssid) > 0)
{
ssd1306_text_line_column(SSD1306_ADDRESS, (char *)ap_info[index].ssid, i * 2 + 2, 2, false);
}
else
{
ssd1306_text_line_column(SSD1306_ADDRESS, " / ", i * 2 + 2, 2, false);
}
if (ap_info[index].rssi >= -67)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_wifi, 8, i * 2 + 2, 112, false);
}
else if (ap_info[index].rssi >= -80)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_wifi_low, 8, i * 2 + 2, 112, false);
}
else if (ap_info[index].rssi >= -90)
{
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_wifi_lowest, 8, i * 2 + 2, 112, false);
}
}
}
}
else
{
ssd1306_text_line_column(SSD1306_ADDRESS, interface_get_label_text(&interface_text_wifi_scanning), 4, 1, false);
}
}
void interface_wifi_start(void)
{
interface_register_button_callback(INTERFACE_BUTTON_SET, &interface_wifi_set);
interface_register_button_callback(INTERFACE_BUTTON_LFT, &interface_wifi_lft);
interface_register_button_callback(INTERFACE_BUTTON_RHT, &interface_wifi_rht);
interface_register_button_callback(INTERFACE_BUTTON_MID, &interface_wifi_mid);
interface_register_button_callback(INTERFACE_BUTTON_UP, &interface_wifi_up);
interface_register_button_callback(INTERFACE_BUTTON_DWN, &interface_wifi_dwn);
interface_register_button_callback(INTERFACE_BUTTON_RST, NULL);
interface_set_display_function(&interface_wifi_display);
ESP_LOGD(INTERFACE_LOG, "start wifi interface and scanning");
memset(ap_info, 0, sizeof(ap_info));
ap_count = 0;
ap_index = 0;
ap_selected = 0;
wifi_controller_scan(ap_info, &ap_count);
}
+75 -59
View File
@@ -14,85 +14,101 @@
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/touch_pad.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "ssd1306-gfx.h"
#include "interface.h"
static int current_interface_state = INTERFACE_STATE_IDLE;
static int old_button_states[GPIO_PIN_COUNT];
static int button_states[GPIO_PIN_COUNT];
static interface_button_callback button_callbacks[GPIO_PIN_COUNT];
static interface_display_function current_display_function;
static int touch_mapping[TOUCH_PAD_COUNT] = {0};
static bool touch_status[TOUCH_PAD_COUNT] = {0};
static interface_touch_callback touch_callbacks[TOUCH_PAD_MAX];
void interface_register_touch_callback(int touch_pad, interface_touch_callback callback)
void interface_register_button_callback(int button_gpio, interface_button_callback callback)
{
touch_callbacks[touch_pad] = callback;
button_callbacks[button_gpio] = callback;
}
void interface_run(void *pvParameter)
void interface_set_display_function(interface_display_function display_function)
{
ssd1306_clear(SSD1306_ADDRESS);
current_display_function = display_function;
}
void interface_input_check(uint8_t gpio)
{
button_states[gpio] = gpio_get_level(gpio);
if (old_button_states[gpio] != 0 && old_button_states[gpio] != 1)
{
old_button_states[gpio] = 1;
}
if (button_states[gpio] == 0 && button_states[gpio] != old_button_states[gpio] && button_callbacks[gpio] != NULL)
{
ssd1306_clear(SSD1306_ADDRESS);
(*button_callbacks[gpio])();
}
old_button_states[gpio] = button_states[gpio];
}
void interface_input_task(void *pvParameter)
{
static uint16_t touch_value;
static uint16_t touch_thresh;
static bool touch_status_current[TOUCH_PAD_MAX] = {0};
while (1)
{
for (int i = 0; i < TOUCH_PAD_COUNT; i++)
interface_input_check(INTERFACE_BUTTON_RST);
interface_input_check(INTERFACE_BUTTON_SET);
interface_input_check(INTERFACE_BUTTON_LFT);
interface_input_check(INTERFACE_BUTTON_RHT);
interface_input_check(INTERFACE_BUTTON_MID);
interface_input_check(INTERFACE_BUTTON_UP);
interface_input_check(INTERFACE_BUTTON_DWN);
vTaskDelay(20 / portTICK_PERIOD_MS);
}
}
void interface_display_task(void *pvParameter)
{
while (1)
{
if (current_display_function != NULL)
{
ESP_ERROR_CHECK_WITHOUT_ABORT(touch_pad_read_filtered(touch_mapping[i], &touch_value));
ESP_ERROR_CHECK_WITHOUT_ABORT(touch_pad_get_thresh(touch_mapping[i], &touch_thresh));
touch_status_current[i] = touch_value < touch_thresh;
if (!touch_status[i] & touch_status_current[i])
{
ESP_LOGD(INTERFACE_LOG, "touch %u at %d (thresh %u)", touch_value, touch_mapping[i], touch_thresh);
if (touch_callbacks[touch_mapping[i]] != NULL)
{
(*touch_callbacks[touch_mapping[i]])();
}
}
touch_status[i] = touch_status_current[i];
(*current_display_function)();
}
vTaskDelay(10 / portTICK_PERIOD_MS);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void interface_start(void)
{
ESP_ERROR_CHECK(touch_pad_init());
ESP_ERROR_CHECK(touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V));
ESP_ERROR_CHECK(touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW));
touch_mapping[0] = TOUCH_PAD_ESC;
touch_mapping[1] = TOUCH_PAD_OK;
touch_mapping[2] = TOUCH_PAD_UP;
touch_mapping[3] = TOUCH_PAD_DOWN;
gpio_config_t io_conf;
for (int i = 0; i < TOUCH_PAD_COUNT; i++)
io_conf.pin_bit_mask = (1ULL << INTERFACE_BUTTON_RST) | (1ULL << INTERFACE_BUTTON_SET) |
(1ULL << INTERFACE_BUTTON_MID) | (1ULL << INTERFACE_BUTTON_RHT) |
(1ULL << INTERFACE_BUTTON_LFT) | (1ULL << INTERFACE_BUTTON_DWN) |
(1ULL << INTERFACE_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);
xTaskCreate(&interface_input_task, "interface_input_task", 4096, NULL, 5, NULL);
xTaskCreate(&interface_display_task, "interface_display_task", 4096, NULL, 5, NULL);
// init label
interface_init_label();
ssd1306_start(SSD1306_ADDRESS);
ssd1306_clear(SSD1306_ADDRESS);
for (int i = 0; i < 8; i++)
{
ESP_ERROR_CHECK(touch_pad_config(touch_mapping[i], 0));
ssd1306_data(SSD1306_ADDRESS, ssd1306_gfx_logo[i], 64, i, 32, false);
}
ESP_ERROR_CHECK(touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD));
uint16_t touch_value;
for (int i = 0; i < TOUCH_PAD_COUNT; i++)
{
ESP_ERROR_CHECK(touch_pad_read_filtered(touch_mapping[i], &touch_value));
ESP_ERROR_CHECK(touch_pad_set_thresh(touch_mapping[i], touch_value * 2 / 3));
ESP_LOGD(INTERFACE_LOG, "calibrate %u at %u (thresh %u)", touch_mapping[i], touch_value, (touch_value * 2 / 3));
}
xTaskCreate(&interface_run, "interface_run", 4096, NULL, 5, NULL);
}
int interface_get_state(void)
{
return current_interface_state;
}
void interface_set_state(interface_state_t state)
{
current_interface_state = state;
}
+193
View File
@@ -0,0 +1,193 @@
// 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 interface functionality via input buttons for control and setup
*
*/
#ifndef _interface_H_
#define _interface_H_
#include "driver/gpio.h"
#define INTERFACE_LOG "INTERFACE" // TAG for Logging
#define INTERFACE_BUTTON_RST GPIO_NUM_32
#define INTERFACE_BUTTON_SET GPIO_NUM_33
#define INTERFACE_BUTTON_MID GPIO_NUM_25
#define INTERFACE_BUTTON_RHT GPIO_NUM_26
#define INTERFACE_BUTTON_LFT GPIO_NUM_27
#define INTERFACE_BUTTON_DWN GPIO_NUM_14
#define INTERFACE_BUTTON_UP GPIO_NUM_12
#define INTERFACE_FORMAT_TIME "%X"
#define INTERFACE_NUM_LOCALE 2
/**
* @brief available locales
*/
typedef enum
{
EN = 0,
DE,
} interface_locale_t;
typedef struct
{
char *text[INTERFACE_NUM_LOCALE];
} interface_label_t;
// label variables
interface_label_t interface_text_button_cancel;
interface_label_t interface_text_button_ok;
interface_label_t interface_text_button_menu;
interface_label_t interface_text_button_report;
interface_label_t interface_text_headline_tan;
interface_label_t interface_text_headline_wifi;
interface_label_t interface_text_headline_time;
interface_label_t interface_text_headline_data;
interface_label_t interface_text_headline_settings;
interface_label_t interface_text_headline_debug;
interface_label_t interface_text_settings_locale;
interface_label_t interface_text_settings_locales[INTERFACE_NUM_LOCALE];
interface_label_t interface_text_settings_timezone;
interface_label_t interface_text_wifi_scanning;
interface_label_t interface_text_data_del[5];
interface_label_t interface_texts_weekday[7];
interface_label_t interface_texts_month[12];
/**
* @brief callback function for button press
*/
typedef void (*interface_button_callback)(void);
/**
* @brief current display function
*/
typedef void (*interface_display_function)(void);
/**
* @brief callback function for text_input
*
* @param[in] text the text from input
* @param[in] cursor current cursor position
*/
typedef void (*interface_input_callback)(char *text, uint8_t cursor);
/**
* @brief init label
*/
void interface_init_label(void);
/**
* @brief get text from label for set locale
*
* @param[in] label the label to get the text from
*/
char *interface_get_label_text(interface_label_t *label);
/**
* @brief set locale for interface
*
* @return
* interface_locale_t current locale
*/
interface_locale_t interface_get_locale(void);
/**
* @brief set locale for interface
*
* @param[in] locale the locale to set
*/
void interface_set_locale(interface_locale_t locale);
/**
* @brief register a callback function for button event
*
* @param[in] button_gpio id of the button to listen to
* @param[in] callback callback function
*/
void interface_register_button_callback(int button_gpio, interface_button_callback callback);
/**
* @brief set the display function
*
* @param[in] display_function display function
*/
void interface_set_display_function(interface_display_function display_function);
/**
* @brief start interface logic
*
* This will initialize the controls and start a task to listen to button inputs and calling the callbacks.
*/
void interface_start(void);
/**
* @brief start delete data interface
*/
void interface_data_start(void);
/**
* @brief start datetime interface
*/
void interface_datetime_start(void);
/**
* @brief start main interface
*/
void interface_main_start(void);
/**
* @brief start report interface
*/
void interface_report_start(void);
/**
* @brief start wifi interface
*/
void interface_wifi_start(void);
/**
* @brief start settings interface
*/
void interface_settings_start(void);
/**
* @brief start interface for input
*
* @param[in] callback_rst function to call on RST
* @param[in] callback_set function to call on SET
* @param[in] limit max character allowed (0=255)
*/
void interface_input(interface_input_callback callback_rst, interface_input_callback callback_set, uint8_t limit);
/**
* @brief set text for input interface
*
* @param[in] text the text to set
*/
void interface_input_set_text(char *text);
#endif