create component branch

This commit is contained in:
Lurkars 2020-09-29 20:05:55 +02:00
parent 43ecb0a42e
commit 5ba07ae442
41 changed files with 4 additions and 3904 deletions

View File

@ -1,6 +0,0 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp-ena)

View File

@ -3,7 +3,7 @@
Implementation of contact tracing with the Covid-19 Exposure Notification API by Apple and Google on an ESP32 (with [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/index.html)). Implementation of contact tracing with the Covid-19 Exposure Notification API by Apple and Google on an ESP32 (with [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/index.html)).
More information about the Covid-19 Exposure Notification at [Apple](https://www.apple.com/covid19/contacttracing/) and [Google](https://www.google.com/covid19/exposurenotifications/). This is fully compatible with the official API and is meant for people without smartphone or without access to Apples/Googles implementation. More information about the Covid-19 Exposure Notification at [Apple](https://www.apple.com/covid19/contacttracing/) and [Google](https://www.google.com/covid19/exposurenotifications/). This is fully compatible with the official API and is meant for people without smartphone or without access to Apples/Googles implementation.
The main source (the Exposure Notification API) is a separate branch in [**component**](https://github.com/Lurkars/esp-ena/tree/component). This is the main source (the Exposure Notification API). Full device is in the [**main branch**](https://github.com/Lurkars/esp-ena/).
This implementation fully covers the BLE part including the cryptography specifications needed and the exposure check. This implementation fully covers the BLE part including the cryptography specifications needed and the exposure check.
@ -21,23 +21,6 @@ The following acronyms will be used in code and comments:
* parsing of Exposure Key export binaries as defined in [Exposure Key export file format and verification](https://developers.google.com/android/exposure-notifications/exposure-key-file-format) (big thanks to [nanopb](https://github.com/nanopb/nanopb) for making this easier than I thought!) * parsing of Exposure Key export binaries as defined in [Exposure Key export file format and verification](https://developers.google.com/android/exposure-notifications/exposure-key-file-format) (big thanks to [nanopb](https://github.com/nanopb/nanopb) for making this easier than I thought!)
* calculating exposure risks/scores (after adding reported keys and storing exposure information) as defined in [ENExposureConfiguration (Apple)](https://developer.apple.com/documentation/exposurenotification/enexposureconfiguration/calculating_the_exposure_risk_value_in_exposurenotification_version_1) * calculating exposure risks/scores (after adding reported keys and storing exposure information) as defined in [ENExposureConfiguration (Apple)](https://developer.apple.com/documentation/exposurenotification/enexposureconfiguration/calculating_the_exposure_risk_value_in_exposurenotification_version_1)
Additional features for full ENA device
* RTC support with DS3231 (for correct system time)
* display support with SSD1306
* interface with a 7 button control (joystick up,down,left,right,enter,cancel,ok) to
* show exposure status
* set time
* connect to wifi
* delete data
* set language
* enter tan for infection status (dummy for now)
### Features in development
* automatically receive Exposure Key export from web (started with [Corona Warn App](https://github.com/corona-warn-app))
* send infected status (will test [Corona Warn App](https://github.com/corona-warn-app))
* battery support
* 3d print case
### Limitations/Problems/Questions ### Limitations/Problems/Questions
* WiFi or other external connection needed for infections status (auto-connect to open WiFis?) * WiFi or other external connection needed for infections status (auto-connect to open WiFis?)
* obtaining accessibility * obtaining accessibility
@ -72,51 +55,9 @@ So on average it is possible to meet 38 (24 on a lower boundary) different devic
### Hardware Required ### Hardware Required
For base functionality just an ESP32 is required. DS3231 RTC, SSD1306 Display and 7 buttons are required for a complete device. For base functionality just an ESP32 is required.
### Configure the project ### Include into project
```
idf.py menuconfig
```
required
* enable bluetooth (BLE)
* add partition-table for storage (currently hardcoded name "ena")
* mbedTLS enable HKDF
recommended
* BLE *Scan Duplicate* (By Device Address and Advertising Data)
debug options
* Log output set to Debug
* Exposure Notification API / Storage enable *Dump storage*
### Build and Flash
May flash partition table:
```
idf.py partition_table-flash
```
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
## Troubleshooting
Sometimes I get errors from BT-stack of ESP-IDF printed. Didn't affect functionality for now, but I also could not find out what it caused and what it means.
```
E (909164) BT_HCI: btu_hcif_hdl_command_complete opcode 0x2005 status 0xc
```
## Structure ## Structure
@ -137,38 +78,6 @@ The ena module contains the main functions of eps-ena with bluetooth scanning an
Module to decode Exposure Key export. Module to decode Exposure Key export.
### ena-cwa
Connection to german Exposure App ([Corona Warn App](https://github.com/corona-warn-app)) for download Exposure Key export (and maybe later report infection).
### interface
Adds interface functionality for control and setup.
### display
General module for display and gfx.
### rtc
General module for set/get time from RTC.
### i2c-main
Just start I2C driver for display and RTC.
### interface-input-buttons
Interface with 7 button input
### rtc-ds3231
I2C driver for a DS3231 RTC, implementation of [rtc](#-rtc) module
### display-ssd1306
I2C driver for a SSD1306 display, implementation of [display](#-display) module
### nanopb ### nanopb
[Nanopb](https://github.com/nanopb/nanopb) for reading Protocol Buffers of Exposure Key export. Including already generated Headers from *.proto files. [Nanopb](https://github.com/nanopb/nanopb) for reading Protocol Buffers of Exposure Key export. Including already generated Headers from *.proto files.

View File

@ -1,8 +0,0 @@
idf_component_register(
SRCS
"ssd1306.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
display
i2c-main
)

View File

@ -1,337 +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 "driver/i2c.h"
#include "esp_log.h"
#include "i2c-main.h"
#include "display.h"
#include "display-gfx.h"
#include "ssd1306.h"
void display_start(void)
{
if (!i2c_is_initialized())
{
i2c_main_init();
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
// Begin the I2C comm with SSD1306's address (SLA+Write)
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
// Tell the SSD1306 that a command stream is incoming
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
// Turn the Display OFF
i2c_master_write_byte(cmd, SSD1306_CMD_OFF, true);
// Set mux ration tp select max number of rows - 64
i2c_master_write_byte(cmd, SSD1306_CMD_MULTIPLEX_RATIO, true);
i2c_master_write_byte(cmd, 0x3F, true);
// Set the display offset to 0
i2c_master_write_byte(cmd, SSD1306_CMD_OFFSET, true);
i2c_master_write_byte(cmd, 0x00, true);
// Display start line to 0
i2c_master_write_byte(cmd, SSD1306_CMD_START_LINE, true);
// Mirror the x-axis. In case you set it up such that the pins are north.
i2c_master_write_byte(cmd, SSD1306_CMD_SEGMENT_HIGH, true);
// Mirror the y-axis. In case you set it up such that the pins are north.
i2c_master_write_byte(cmd, SSD1306_CMD_SCAN_DIRECTION_REMAPPED, true);
// Default - alternate COM pin map
i2c_master_write_byte(cmd, SSD1306_CMD_COM_PINS, true);
i2c_master_write_byte(cmd, 0x12, true);
// set contrast
i2c_master_write_byte(cmd, SSD1306_CMD_CONTRAST, true);
i2c_master_write_byte(cmd, 0xFF, true);
// Set display to enable rendering from GDDRAM (Graphic Display Data RAM)
i2c_master_write_byte(cmd, SSD1306_CMD_RAM, true);
// Normal mode!
i2c_master_write_byte(cmd, SSD1306_CMD_NORMAL, true);
// Default oscillator clock
i2c_master_write_byte(cmd, SSD1306_CMD_CLOCK, true);
i2c_master_write_byte(cmd, 0x80, true);
// Enable the charge pump
i2c_master_write_byte(cmd, SSD1306_CMD_CHARGE_PUMP, true);
i2c_master_write_byte(cmd, 0x14, true);
// Set precharge cycles to high cap type
i2c_master_write_byte(cmd, SSD1306_CMD_PRE_CHARGE_PERIOD, true);
i2c_master_write_byte(cmd, 0x22, true);
// Set the V_COMH deselect volatage to max
i2c_master_write_byte(cmd, SSD1306_CMD_VCOMH, true);
i2c_master_write_byte(cmd, 0x30, true);
// Horizonatal addressing mode to page addressing
i2c_master_write_byte(cmd, SSD1306_CMD_MEMORY_MODE, true);
i2c_master_write_byte(cmd, 0x02, true);
//i2c_master_write_byte(cmd, 0x00, true);
// i2c_master_write_byte(cmd, 0x10, true);
// i2c_master_write_byte(cmd, SSD1306_CMD_SCROLL_STOP, true);
// Turn the Display ON
i2c_master_write_byte(cmd, SSD1306_CMD_ON, 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 display_init_data(void)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
// Begin the I2C comm with SSD1306's address (SLA+Write)
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
// Tell the SSD1306 that a command stream is incoming
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
// set column start + end
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_LOW, true);
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_HIGH, true);
// set page
i2c_master_write_byte(cmd, SSD1306_CMD_PAGE, 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 display_clear_line(uint8_t line, bool invert)
{
i2c_cmd_handle_t cmd;
uint8_t *zeros = calloc(SSD1306_COLUMNS, sizeof(uint8_t));
// set line
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_LOW, true);
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_HIGH, true);
i2c_master_write_byte(cmd, SSD1306_CMD_PAGE | line, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
// fill line with zeros
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, SSD1306_CONTROL_DATA_STREAM, true);
i2c_master_write(cmd, zeros, SSD1306_COLUMNS, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
free(zeros);
}
void display_clear(void)
{
for (uint8_t i = 0; i < SSD1306_PAGES; i++)
{
display_clear_line(i, false);
}
}
void display_on(bool on)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
// Begin the I2C comm with SSD1306's address (SLA+Write)
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
// Tell the SSD1306 that a command stream is incoming
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
if (on)
{
// Turn the Display ON
i2c_master_write_byte(cmd, SSD1306_CMD_ON, true);
}
else
{
// Turn the Display OFF
i2c_master_write_byte(cmd, SSD1306_CMD_OFF, true);
}
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
{
uint8_t column = offset;
if (column > SSD1306_COLUMNS)
{
column = 0;
}
size_t columns = length;
if (columns > (SSD1306_COLUMNS - column))
{
columns = (SSD1306_COLUMNS - column);
}
display_init_data();
i2c_cmd_handle_t cmd;
// set line
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, SSD1306_CONTROL_CMD_STREAM, true);
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_LOW | (column & 0XF), true);
i2c_master_write_byte(cmd, SSD1306_CMD_COLUMN_HIGH | (column >> 4), true);
i2c_master_write_byte(cmd, SSD1306_CMD_PAGE | line, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
if (invert)
{
for (uint8_t i = 0; i < columns; i++)
{
data[i] = ~data[i];
}
}
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SSD1306_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, SSD1306_CONTROL_DATA_STREAM, true);
i2c_master_write(cmd, data, columns, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
void display_text_line_column(char *text, uint8_t line, uint8_t offset, bool invert)
{
display_chars(text, strlen(text), line, offset, invert);
}
void display_text_line(char *text, uint8_t line, bool invert)
{
display_text_line_column(text, line, 0, invert);
}
void display_text_input(char *text, uint8_t position)
{
size_t start = 0;
if (position > 13)
{
position = 13;
start = position - 13;
}
uint8_t cur_char = (uint8_t)text[start + position] - 32;
// arrow
display_data(display_gfx_arrow_left, 8, 2, 0, false);
// bounday
display_text_line_column("______________", 2, 1, false);
// arrow
display_data(display_gfx_arrow_right, 8, 2, 15 * 8, false);
// text
size_t text_length = strlen(text);
if (strlen(text) > 14)
{
text_length = 14;
}
size_t length = 0;
uint8_t *textdata = display_text_to_data(text, text_length, &length);
display_data(textdata, length, 2, 8, true);
free(textdata);
// arrow
display_data(display_gfx_arrow_up, 8, 0, (position + 1) * 8, false);
// upper char
display_data(display_gfx_font[cur_char - 1], 8, 1, (position + 1) * 8, false);
// sel char
display_data(display_gfx_font[cur_char], 8, 2, (position + 1) * 8, false);
// lower char
display_data(display_gfx_font[cur_char + 1], 8, 3, (position + 1) * 8, false);
// arrow
display_data(display_gfx_arrow_down, 8, 4, (position + 1) * 8, false);
}
void display_set_button(char *text, bool selected, bool primary)
{
uint8_t start = 0;
if (primary)
{
start = 64;
}
if (selected)
{
display_data(display_gfx_button_sel[0], 64, 5, start, false);
display_data(display_gfx_button_sel[1], 64, 6, start, false);
display_data(display_gfx_button_sel[2], 64, 7, start, false);
}
else
{
display_data(display_gfx_button[0], 64, 5, start, false);
display_data(display_gfx_button[1], 64, 6, start, false);
display_data(display_gfx_button[2], 64, 7, start, false);
}
// text
size_t text_length = strlen(text);
if (strlen(text) > 6)
{
text_length = 6;
}
size_t length = 0;
uint8_t *textdata = display_text_to_data(text, text_length, &length);
uint8_t offset = 0;
if (text_length < 6)
{
offset = (6 - text_length) / 2 * 8;
}
display_data(textdata, length, 6, start + 8 + offset, selected);
free(textdata);
}
void display_menu_headline(char *text, bool arrows, uint8_t line)
{
if (arrows)
{
display_data(display_gfx_arrow_left, 8, line, 0, false);
display_data(display_gfx_arrow_right, 8, line, 15 * 8, false);
}
// bounday
display_data(display_gfx_menu_head, 112, line, 8, false);
// text
size_t text_length = strlen(text);
if (strlen(text) > 10)
{
text_length = 10;
}
size_t length = 0;
uint8_t *textdata = display_text_to_data(text, text_length, &length);
uint8_t offset = 0;
if (text_length < 10)
{
offset = (10 - text_length) / 2 * 8;
}
display_data(textdata, length, line, 24 + offset, true);
free(textdata);
}

View File

@ -1,80 +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 I2C driver for SSD1306 display
*
*/
#ifndef _ssd1306_H_
#define _ssd1306_H_
#include "esp_system.h"
#define SSD1306_ADDRESS (0x3C)
#define SSD1306_COLUMNS (128)
#define SSD1306_PAGES (8)
// Write mode for I2C https://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html
#define SSD1306_CONTROL_CMD_BYTE (0x80)
#define SSD1306_CONTROL_CMD_STREAM (0x00)
#define SSD1306_CONTROL_DATA_BYTE (0xC0)
#define SSD1306_CONTROL_DATA_STREAM (0x40)
// 1. Fundamental Command Table
#define SSD1306_CMD_CONTRAST (0x81)
#define SSD1306_CMD_RAM (0xA4)
#define SSD1306_CMD_ALL_ON (0xA5)
#define SSD1306_CMD_NORMAL (0xA6)
#define SSD1306_CMD_INVERSE (0xA7)
#define SSD1306_CMD_OFF (0xAE)
#define SSD1306_CMD_ON (0xAF)
// 2. Scrolling Command Table
#define SSD1306_CMD_SCROLL_HORI_RIGHT (0x26)
#define SSD1306_CMD_SCROLL_HORI_LEFT (0x27)
#define SSD1306_CMD_SCROLL_VERT_RIGHT (0x29)
#define SSD1306_CMD_SCROLL_VERT_LEFT (0x2A)
#define SSD1306_CMD_SCROLL_STOP (0x2E)
#define SSD1306_CMD_SCROLL_START (0x2F)
#define SSD1306_CMD_SCROLL_VERT_AREA (0xA3)
// 3. Addressing Setting Command Table
#define SSD1306_CMD_COLUMN_LOW (0x00)
#define SSD1306_CMD_COLUMN_HIGH (0x10)
#define SSD1306_CMD_MEMORY_MODE (0x20)
#define SSD1306_CMD_COLUMN_ADDRESS (0x21)
#define SSD1306_CMD_PAGE_ADDRESS (0x22)
#define SSD1306_CMD_PAGE (0xB0)
// 4. Hardware Configuration (Panel resolution & layout related) Command Table
#define SSD1306_CMD_START_LINE (0x40)
#define SSD1306_CMD_SEGMENT_LOW (0xA0)
#define SSD1306_CMD_SEGMENT_HIGH (0xA1)
#define SSD1306_CMD_MULTIPLEX_RATIO (0xA8)
#define SSD1306_CMD_SCAN_DIRECTION_NORMAL (0xC0)
#define SSD1306_CMD_SCAN_DIRECTION_REMAPPED (0xC8)
#define SSD1306_CMD_OFFSET (0xD3)
#define SSD1306_CMD_COM_PINS (0xDA)
// 5. Timing & Driving Scheme Setting Command Table
#define SSD1306_CMD_CLOCK (0xD5)
#define SSD1306_CMD_PRE_CHARGE_PERIOD (0xD9)
#define SSD1306_CMD_VCOMH (0xDB)
#define SSD1306_CMD_NOP (0xE3)
// 1. Charge Pump Command Table
#define SSD1306_CMD_CHARGE_PUMP (0x8D)
#endif

View File

@ -1,6 +0,0 @@
idf_component_register(
SRCS
"display.c"
"display-gfx.c"
INCLUDE_DIRS "."
)

View File

@ -1,307 +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 "display-gfx.h"
uint8_t display_gfx_clear[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t display_gfx_font[224][8] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x5f, 0x5f, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x06, 0x08, 0x0e, 0x06, 0x00},
{0x00, 0x24, 0x7e, 0x7e, 0x24, 0x7e, 0x7e, 0x24},
{0x00, 0x4c, 0xde, 0x92, 0xfe, 0x92, 0xf6, 0x64},
{0x06, 0x8d, 0xe6, 0x78, 0x1e, 0x67, 0xd1, 0x60},
{0x00, 0x36, 0x7f, 0x49, 0x5f, 0x76, 0x70, 0x50},
{0x00, 0x00, 0x00, 0x08, 0x0e, 0x06, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x7f, 0x41, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x41, 0x7f, 0x3e, 0x00, 0x00},
{0x00, 0x14, 0x1c, 0x3e, 0x3e, 0x1c, 0x14, 0x00},
{0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xf0, 0x3c, 0x0f, 0x03, 0x00},
{0x00, 0x3e, 0x7f, 0x4d, 0x59, 0x7f, 0x3e, 0x00},
{0x00, 0x42, 0x42, 0x7f, 0x7f, 0x40, 0x40, 0x00},
{0x00, 0x42, 0x63, 0x71, 0x59, 0x4f, 0x46, 0x00},
{0x00, 0x41, 0x49, 0x49, 0x49, 0x7f, 0x36, 0x00},
{0x00, 0x18, 0x1c, 0x16, 0x7f, 0x7f, 0x10, 0x00},
{0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00},
{0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00},
{0x00, 0x03, 0x63, 0x71, 0x19, 0x0f, 0x07, 0x00},
{0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00},
{0x00, 0x06, 0x4f, 0x49, 0x69, 0x3f, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xe8, 0x68, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x1c, 0x36, 0x22, 0x00, 0x00},
{0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14},
{0x00, 0x00, 0x00, 0x22, 0x36, 0x1c, 0x08, 0x00},
{0x00, 0x02, 0x13, 0x59, 0x49, 0x0f, 0x06, 0x00},
{0x3e, 0x7f, 0x55, 0x5d, 0x5d, 0x5f, 0x6e, 0x20},
{0x00, 0x7e, 0x7f, 0x11, 0x11, 0x7f, 0x7e, 0x00},
{0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00},
{0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00},
{0x01, 0x7f, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00},
{0x00, 0x7f, 0x7f, 0x49, 0x49, 0x49, 0x41, 0x00},
{0x00, 0x7f, 0x7f, 0x09, 0x09, 0x09, 0x01, 0x00},
{0x00, 0x3e, 0x7f, 0x41, 0x49, 0x79, 0x79, 0x00},
{0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00},
{0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00},
{0x00, 0x41, 0x41, 0x7f, 0x3f, 0x01, 0x00, 0x00},
{0x00, 0x7f, 0x7f, 0x0c, 0x3e, 0x73, 0x41, 0x00},
{0x00, 0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x00},
{0x00, 0x7f, 0x7f, 0x0c, 0x08, 0x0c, 0x7f, 0x7f},
{0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x7f, 0x7f, 0x00},
{0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00},
{0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00},
{0x00, 0x3e, 0x7f, 0x51, 0x61, 0x7f, 0x5e, 0x00},
{0x00, 0x7f, 0x7f, 0x09, 0x19, 0x7f, 0x66, 0x00},
{0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00},
{0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00},
{0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00},
{0x00, 0x0f, 0x3f, 0x70, 0x70, 0x3f, 0x0f, 0x00},
{0x3f, 0x7f, 0x60, 0x3c, 0x3c, 0x60, 0x7f, 0x3f},
{0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00},
{0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00},
{0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00},
{0x00, 0x00, 0x00, 0x7f, 0x7f, 0x41, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x0f, 0x3c, 0xf0, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x06, 0x02, 0x06, 0x04, 0x00},
{0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
{0x00, 0x00, 0x00, 0x02, 0x0e, 0x0c, 0x00, 0x00},
{0x00, 0x30, 0x7a, 0x4a, 0x4a, 0x7e, 0x7c, 0x00},
{0x00, 0x7f, 0x7f, 0x44, 0x44, 0x7c, 0x38, 0x00},
{0x00, 0x3c, 0x7e, 0x42, 0x42, 0x46, 0x44, 0x00},
{0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x7f, 0x00},
{0x00, 0x3c, 0x7e, 0x4a, 0x4a, 0x4e, 0x4c, 0x00},
{0x00, 0x08, 0x7e, 0x7f, 0x09, 0x09, 0x01, 0x00},
{0x00, 0x1c, 0xbe, 0xa2, 0xa2, 0xfe, 0x7e, 0x00},
{0x00, 0x7f, 0x7f, 0x0c, 0x04, 0x7c, 0x78, 0x00},
{0x00, 0x00, 0x44, 0x7d, 0x7d, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xfe, 0x7e, 0x02, 0x00, 0x00},
{0x00, 0x7e, 0x7e, 0x18, 0x3c, 0x66, 0x42, 0x00},
{0x00, 0x00, 0x3e, 0x7e, 0x40, 0x40, 0x00, 0x00},
{0x7c, 0x7e, 0x02, 0x7e, 0x7e, 0x02, 0x7e, 0x7c},
{0x00, 0x7c, 0x7c, 0x06, 0x02, 0x7e, 0x7c, 0x00},
{0x00, 0x3c, 0x7e, 0x42, 0x42, 0x7e, 0x3c, 0x00},
{0x00, 0xfe, 0xfe, 0x22, 0x22, 0x3e, 0x1c, 0x00},
{0x00, 0x1c, 0x3e, 0x22, 0x22, 0xfe, 0xfe, 0x00},
{0x00, 0x00, 0x7c, 0x7e, 0x06, 0x02, 0x02, 0x00},
{0x00, 0x24, 0x6e, 0x4a, 0x4a, 0x7a, 0x30, 0x00},
{0x00, 0x00, 0x3f, 0x7f, 0x44, 0x44, 0x44, 0x00},
{0x00, 0x3e, 0x7e, 0x40, 0x60, 0x7e, 0x7e, 0x00},
{0x00, 0x0e, 0x3e, 0x70, 0x70, 0x3e, 0x0e, 0x00},
{0x3c, 0x7c, 0x40, 0x7c, 0x7c, 0x40, 0x7e, 0x3e},
{0x00, 0x42, 0x66, 0x3c, 0x3c, 0x66, 0x42, 0x00},
{0x00, 0x00, 0x4e, 0x5e, 0x70, 0x3e, 0x0e, 0x00},
{0x00, 0x00, 0x62, 0x72, 0x5a, 0x4e, 0x46, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0xc3, 0x81, 0x42, 0x00},
{0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0x81, 0xc3, 0x7e, 0x18, 0x00},
{0x00, 0x10, 0x18, 0x08, 0x18, 0x10, 0x18, 0x08},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0x28, 0x7c, 0xfe, 0xaa, 0xaa, 0x8a, 0xc6, 0x44},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0x00, 0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00},
{0x00, 0x00, 0x48, 0x7c, 0x3e, 0x0a, 0x00, 0x00},
{0x00, 0x80, 0xe0, 0x60, 0x80, 0xe0, 0x60, 0x00},
{0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40},
{0x00, 0x08, 0x04, 0x7e, 0x7e, 0x04, 0x08, 0x00},
{0x00, 0x24, 0x42, 0xff, 0xff, 0x42, 0x24, 0x00},
{0x00, 0x04, 0x06, 0x03, 0x03, 0x06, 0x04, 0x00},
{0xc0, 0x66, 0x1d, 0x66, 0xd8, 0x66, 0xd3, 0x60},
{0x00, 0x25, 0x6f, 0x4a, 0x4a, 0x7b, 0x31, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x24, 0x00, 0x00},
{0x3e, 0x7f, 0x41, 0x61, 0x7f, 0x7f, 0x49, 0x49},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0x00, 0x61, 0x73, 0x5a, 0x4e, 0x47, 0x43, 0x00},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0x00, 0x00, 0x00, 0x06, 0x0e, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x0e, 0x0c, 0x00, 0x00},
{0x00, 0x06, 0x0e, 0x08, 0x06, 0x0e, 0x08, 0x00},
{0x00, 0x02, 0x0e, 0x0c, 0x02, 0x0e, 0x0c, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00},
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00},
{0x00, 0x04, 0x06, 0x02, 0x04, 0x06, 0x02, 0x00},
{0x01, 0x0f, 0x0f, 0x01, 0x0e, 0x02, 0x0f, 0x0f},
{0x00, 0x25, 0x6f, 0x4a, 0x4a, 0x7b, 0x31, 0x00},
{0x00, 0x00, 0x00, 0x24, 0x3c, 0x18, 0x00, 0x00},
{0x3c, 0x7e, 0x42, 0x62, 0x7e, 0x7e, 0x52, 0x52},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0x00, 0x01, 0x63, 0x72, 0x5a, 0x4e, 0x47, 0x01},
{0x00, 0x05, 0x0d, 0x78, 0x78, 0x0d, 0x05, 0x00},
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
{0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x7c, 0x44, 0xfe, 0x44, 0x6c, 0x28},
{0x00, 0x90, 0xfc, 0xfe, 0x92, 0x92, 0xc6, 0x44},
{0x00, 0x42, 0x5a, 0x3c, 0x24, 0x3c, 0x5a, 0x42},
{0x00, 0x52, 0x56, 0xfc, 0xfc, 0x56, 0x52, 0x00},
{0x00, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1a, 0xbf, 0xa5, 0xfd, 0x58, 0x00},
{0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00},
{0x3c, 0x7e, 0xdb, 0xa5, 0xa5, 0xd3, 0x7e, 0x3c},
{0x00, 0x10, 0x16, 0x13, 0x13, 0x16, 0x10, 0x00},
{0x00, 0x18, 0x3c, 0x24, 0x18, 0x3c, 0x24, 0x00},
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x38},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00},
{0x7e, 0xff, 0x81, 0xbd, 0x95, 0xa9, 0xff, 0x7e},
{0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
{0x00, 0x00, 0x0c, 0x1a, 0x1a, 0x0c, 0x00, 0x00},
{0x00, 0x48, 0x48, 0x7e, 0x7e, 0x48, 0x48, 0x00},
{0x00, 0x00, 0x19, 0x1d, 0x17, 0x12, 0x00, 0x00},
{0x00, 0x00, 0x11, 0x15, 0x1f, 0x0a, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x00, 0x00},
{0x00, 0xfe, 0xfe, 0x20, 0x30, 0x3e, 0x7e, 0x40},
{0x00, 0x06, 0x0f, 0xff, 0xff, 0x01, 0xff, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x00, 0x00},
{0x00, 0x00, 0x12, 0x1f, 0x1f, 0x10, 0x00, 0x00},
{0x00, 0x10, 0x17, 0x17, 0x15, 0x17, 0x17, 0x10},
{0x00, 0x24, 0x3c, 0x18, 0x24, 0x3c, 0x18, 0x00},
{0x09, 0xcf, 0x7f, 0x3c, 0x6e, 0x53, 0xf8, 0xf8},
{0x89, 0xcf, 0x6f, 0x38, 0xdc, 0xee, 0xbb, 0x90},
{0x91, 0xd5, 0x7f, 0x3a, 0x6c, 0x56, 0xfb, 0xf8},
{0x00, 0x60, 0xf0, 0x92, 0x9a, 0xc8, 0x40, 0x00},
{0x00, 0x01, 0x7b, 0x7e, 0x24, 0x24, 0x7c, 0x78},
{0x00, 0x78, 0x7c, 0x24, 0x24, 0x7e, 0x7b, 0x01},
{0x02, 0x7b, 0x7d, 0x25, 0x25, 0x7d, 0x7b, 0x02},
{0x02, 0x7b, 0x7d, 0x25, 0x27, 0x7e, 0x7b, 0x01},
{0x00, 0x79, 0x7d, 0x24, 0x24, 0x7d, 0x79, 0x00},
{0x00, 0x78, 0x7e, 0x25, 0x25, 0x7e, 0x78, 0x00},
{0x70, 0x7c, 0x0e, 0x0b, 0x7f, 0x7f, 0x49, 0x49},
{0x00, 0x3e, 0x7f, 0x41, 0x41, 0xe3, 0xa2, 0x00},
{0x00, 0x01, 0x7f, 0x7e, 0x54, 0x54, 0x54, 0x44},
{0x7c, 0x7c, 0x54, 0x54, 0x54, 0x46, 0x03, 0x01},
{0x02, 0x03, 0x7d, 0x7d, 0x55, 0x55, 0x03, 0x02},
{0x00, 0x7d, 0x7d, 0x54, 0x54, 0x55, 0x45, 0x00},
{0x00, 0x00, 0x41, 0x7b, 0x7a, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x7a, 0x7b, 0x41, 0x00, 0x00},
{0x00, 0x02, 0x43, 0x7d, 0x7d, 0x43, 0x02, 0x00},
{0x00, 0x01, 0x41, 0x7c, 0x7c, 0x41, 0x01, 0x00},
{0x00, 0x11, 0x7f, 0x7f, 0x51, 0x41, 0x7f, 0x3e},
{0x02, 0x03, 0x7d, 0x7d, 0x1b, 0x72, 0x7b, 0x01},
{0x00, 0x01, 0x3b, 0x7e, 0x44, 0x44, 0x7c, 0x38},
{0x00, 0x38, 0x7c, 0x44, 0x44, 0x7e, 0x3b, 0x01},
{0x02, 0x3b, 0x7d, 0x45, 0x45, 0x7d, 0x3b, 0x02},
{0x02, 0x3b, 0x7d, 0x45, 0x47, 0x7e, 0x3b, 0x01},
{0x00, 0x39, 0x7d, 0x44, 0x44, 0x7d, 0x39, 0x00},
{0x00, 0x22, 0x36, 0x1c, 0x1c, 0x36, 0x22, 0x00},
{0x00, 0x5e, 0x7f, 0x39, 0x5d, 0x46, 0x7f, 0x3d},
{0x00, 0x01, 0x3f, 0x7e, 0x40, 0x40, 0x7c, 0x3c},
{0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7e, 0x3f, 0x01},
{0x02, 0x3b, 0x79, 0x41, 0x41, 0x79, 0x3b, 0x02},
{0x00, 0x3d, 0x7d, 0x40, 0x40, 0x7d, 0x3d, 0x00},
{0x00, 0x0e, 0x1e, 0x70, 0x72, 0x1b, 0x09, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x24, 0x3c, 0x18, 0x00},
{0x00, 0xfe, 0xff, 0x49, 0x4f, 0x7e, 0x38, 0x00},
{0x00, 0x01, 0x7b, 0x7e, 0x24, 0x24, 0x7c, 0x78},
{0x00, 0x78, 0x7c, 0x24, 0x24, 0x7e, 0x7b, 0x01},
{0x02, 0x7b, 0x7d, 0x25, 0x25, 0x7d, 0x7b, 0x02},
{0x02, 0x7b, 0x7d, 0x25, 0x27, 0x7e, 0x7b, 0x01},
{0x00, 0x79, 0x7d, 0x24, 0x24, 0x7d, 0x79, 0x00},
{0x00, 0x78, 0x7e, 0x25, 0x25, 0x7e, 0x78, 0x00},
{0x60, 0x78, 0x1c, 0x16, 0x7e, 0x7e, 0x52, 0x52},
{0x00, 0x3c, 0x7e, 0x42, 0x42, 0xe6, 0xa4, 0x00},
{0x00, 0x01, 0x7f, 0x7e, 0x54, 0x54, 0x54, 0x44},
{0x7c, 0x7c, 0x54, 0x54, 0x54, 0x46, 0x03, 0x01},
{0x02, 0x03, 0x7d, 0x7d, 0x55, 0x55, 0x03, 0x02},
{0x00, 0x7d, 0x7d, 0x54, 0x54, 0x55, 0x45, 0x00},
{0x00, 0x00, 0x41, 0x7b, 0x7a, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x7a, 0x7b, 0x41, 0x00, 0x00},
{0x00, 0x02, 0x43, 0x7d, 0x7d, 0x43, 0x02, 0x00},
{0x00, 0x00, 0x41, 0x79, 0x79, 0x41, 0x00, 0x00},
{0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x3f, 0x04},
{0x02, 0x03, 0x7d, 0x7d, 0x1b, 0x72, 0x7b, 0x01},
{0x00, 0x01, 0x3b, 0x7e, 0x44, 0x44, 0x7c, 0x38},
{0x00, 0x38, 0x7c, 0x44, 0x44, 0x7e, 0x3b, 0x01},
{0x02, 0x3b, 0x7d, 0x45, 0x45, 0x7d, 0x3b, 0x02},
{0x02, 0x3b, 0x7d, 0x45, 0x47, 0x7e, 0x3b, 0x01},
{0x00, 0x39, 0x7d, 0x44, 0x44, 0x7d, 0x39, 0x00},
{0x00, 0x08, 0x08, 0x2a, 0x2a, 0x08, 0x08, 0x00},
{0x00, 0x5c, 0x7e, 0x32, 0x5a, 0x4c, 0x7e, 0x3a},
{0x00, 0x01, 0x3f, 0x7e, 0x40, 0x40, 0x7c, 0x3c},
{0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7e, 0x3f, 0x01},
{0x02, 0x3b, 0x79, 0x41, 0x41, 0x79, 0x3b, 0x02},
{0x00, 0x3d, 0x7d, 0x40, 0x40, 0x7d, 0x3d, 0x00},
{0x00, 0x08, 0x18, 0x72, 0x73, 0x19, 0x08, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x24, 0x3c, 0x18, 0x00},
{0x00, 0x0d, 0x1d, 0x70, 0x70, 0x1d, 0x0d, 0x00},
};
uint8_t display_gfx_button[3][64] = {
{0x00, 0x00, 0x00, 0xe0, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0xe0, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x07, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x07, 0x00, 0x00, 0x00},
};
uint8_t display_gfx_button_sel[3][64] = {
{0x00, 0x00, 0x00, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x07, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x00, 0x00, 0x00},
};
uint8_t display_gfx_clock[8] = {0x3c, 0x42, 0x81, 0x9d, 0x91, 0x81, 0x42, 0x3c};
uint8_t display_gfx_menu_head[112] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t display_gfx_sad[4][24] = {
{0x00, 0x00, 0x00, 0x80, 0xe0, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0xe0, 0x80, 0x00, 0x00, 0x00},
{0xf8, 0xff, 0x0f, 0x01, 0x01, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x01, 0x01, 0x0f, 0xff, 0xf8},
{0x1f, 0xff, 0xf0, 0x80, 0x00, 0x40, 0x30, 0x38, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x38, 0x30, 0x40, 0x00, 0x80, 0xf0, 0xff, 0x1f},
{0x00, 0x00, 0x00, 0x01, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x06, 0x07, 0x01, 0x00, 0x00, 0x00},
};
uint8_t display_gfx_smile[4][24] = {
{0x00, 0x00, 0x00, 0x80, 0xe0, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0xe0, 0x80, 0x00, 0x00, 0x00},
{0xf8, 0xff, 0x0f, 0x01, 0x01, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x01, 0x01, 0x0f, 0xff, 0xf8},
{0x1f, 0xff, 0xf0, 0x80, 0x86, 0x06, 0x18, 0x38, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x38, 0x18, 0x06, 0x86, 0x80, 0xf0, 0xff, 0x1f},
{0x00, 0x00, 0x00, 0x01, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x06, 0x07, 0x01, 0x00, 0x00, 0x00},
};
uint8_t display_gfx_question[4][24] = {
{0x00, 0x00, 0x00, 0x80, 0xe0, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0xe0, 0x80, 0x00, 0x00, 0x00},
{0xf8, 0xff, 0x0f, 0x01, 0x01, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x01, 0x01, 0x0f, 0xff, 0xf8},
{0x1f, 0xff, 0xf0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x26, 0xb2, 0x92, 0x1e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xf0, 0xff, 0x1f},
{0x00, 0x00, 0x00, 0x01, 0x07, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x06, 0x07, 0x01, 0x00, 0x00, 0x00},
};
uint8_t display_gfx_wifi[8] = {0x00, 0x02, 0x0a, 0x2a, 0x2a, 0x0a, 0x02, 0x00};
uint8_t display_gfx_wifi_low[8] = {0x00, 0x00, 0x08, 0x28, 0x28, 0x08, 0x00, 0x00};
uint8_t display_gfx_wifi_lowest[8] = {0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00};
uint8_t display_gfx_arrow_down[8] = {0x08, 0x18, 0x38, 0x78, 0x78, 0x38, 0x18, 0x08};
uint8_t display_gfx_arrow_left[8] = {0x00, 0x18, 0x3c, 0x7e, 0xff, 0x00, 0x00, 0x00};
uint8_t display_gfx_arrow_right[8] = {0x00, 0x00, 0x00, 0xff, 0x7e, 0x3c, 0x18, 0x00};
uint8_t display_gfx_arrow_up[8] = {0x10, 0x18, 0x1c, 0x1e, 0x1e, 0x1c, 0x18, 0x10};
uint8_t display_gfx_cross[8] = {0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00};
uint8_t display_gfx_logo[8][64] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x86, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1e, 0x3e, 0x3c, 0x7c, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};

View File

@ -1,62 +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 gfx elements: font, icons, elements
*
*/
#ifndef _display_GFX_H_
#define _display_GFX_H_
#include <stdint.h>
uint8_t display_gfx_clear[8];
// Dogica Font https://www.dafont.com/de/dogica.font starting at space (32)
uint8_t display_gfx_font[224][8];
uint8_t display_gfx_button[3][64];
uint8_t display_gfx_button_sel[3][64];
uint8_t display_gfx_clock[8];
uint8_t display_gfx_menu_head[112];
uint8_t display_gfx_sad[4][24];
uint8_t display_gfx_smile[4][24];
uint8_t display_gfx_question[4][24];
uint8_t display_gfx_wifi[8];
uint8_t display_gfx_wifi_low[8];
uint8_t display_gfx_wifi_lowest[8];
uint8_t display_gfx_arrow_down[8];
uint8_t display_gfx_arrow_left[8];
uint8_t display_gfx_arrow_right[8];
uint8_t display_gfx_arrow_up[8];
uint8_t display_gfx_cross[8];
uint8_t display_gfx_logo[8][64];
#endif

View File

@ -1,90 +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 "display.h"
#include "display-gfx.h"
uint8_t display_utf8_to_ascii_char(uint8_t ascii)
{
static uint8_t c1;
if (ascii < 128) // Standard ASCII-set 0..0x7F handling
{
c1 = 0;
return (ascii);
}
// get previous input
uint8_t last = c1; // get last char
c1 = ascii; // remember actual character
switch (last) // conversion depending on first UTF8-character
{
case 0xC2:
return (ascii);
break;
case 0xC3:
return (ascii | 0xC0);
break;
case 0x82:
if (ascii == 0xAC)
return (0x80); // special case Euro-symbol
}
return (0); // otherwise: return zero, if character has to be ignored
}
void display_utf8_to_ascii(char *input, char *output)
{
strcpy(output, input);
int k = 0;
char c;
for (int i = 0; i < strlen(output); i++)
{
c = display_utf8_to_ascii_char(output[i]);
if (c != 0)
output[k++] = c;
}
output[k] = 0;
}
uint8_t *display_text_to_data(char *text, size_t text_length, size_t *length)
{
char target_text[strlen(text)];
display_utf8_to_ascii(text, target_text);
uint8_t font_width = sizeof(display_gfx_font[0]);
*length = text_length * font_width;
uint8_t *data = calloc(*length, sizeof(uint8_t));
for (uint8_t i = 0; i < text_length; i++)
{
memcpy(&data[i * font_width], display_gfx_font[(uint8_t)target_text[i] - 32], font_width);
}
return data;
}
void display_chars(char *text, size_t length, uint8_t line, uint8_t offset, bool invert)
{
if (length > 0)
{
uint8_t font_width = sizeof(display_gfx_font[0]);
size_t res_length = 0;
uint8_t *textdata = display_text_to_data(text, length, &res_length);
display_data(textdata, res_length, line, offset * font_width, invert);
free(textdata);
}
}

View File

@ -1,125 +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 display
*
*/
#ifndef _display_H_
#define _display_H_
#include "esp_system.h"
/**
*
*/
void display_utf8_to_ascii(char *input, char *output);
/**
*
*/
uint8_t *display_text_to_data(char *text, size_t text_length, size_t *length);
/**
* @brief initalize display
*/
void display_start(void);
/**
* @brief clear the display
*
* @param[in] line the line to clear
* @param[in] invert if true, image is inverted
*/
void display_clear_line( uint8_t line, bool invert);
/**
* @brief clear the display
*
*/
void display_clear(void);
/**
* @brief set display on or offf
*
* @param[in] on true if display on, false if display off
*/
void display_on(bool on);
/**
*
*/
uint8_t *display_text_to_data(char *text, size_t text_length, size_t *length);
/**
* @brief write raw bytes to display line at starting column
*
* @param[in] data bytes to display
* @param[in] length length of data
* @param[in] line the line to write to
* @param[in] offset number of offset chars to start
* @param[in] invert if true, image is inverted
*/
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert);
/**
* @brief write chars to display
*
* @param[in] text text to display
* @param[in] length length of text
* @param[in] line the line to write to
* @param[in] offset number of offset chars to start
* @param[in] invert if true, image is inverted
*/
void display_chars(char *text, size_t length, uint8_t line, uint8_t offset, bool invert);
/**
* @brief write text to display line at starting column
*
* @param[in] text text to display
* @param[in] line the line to write to
* @param[in] offset number of offset chars to start
* @param[in] invert if true, image is inverted
*/
void display_text_line_column(char *text, uint8_t line, uint8_t offset, bool invert);
/**
* @brief write text to display line
*
* @param[in] text text to display
* @param[in] line the line to write to
* @param[in] invert if true, image is inverted
*/
void display_text_line(char *text, uint8_t line, bool invert);
/**
* @brief display a button element
*
* @param[in] text button text
* @param[in] selected is button selected
* @param[in] primary is button primary
*/
void display_set_button(char *text, bool selected, bool primary);
/**
* @brief display a menu headline
*
* @param[in] text headline text
* @param[in] arrows if left right arrows should be displays
* @param[in] line line the line to write to
*/
void display_menu_headline(char *text, bool arrows, uint8_t line);
#endif

View File

@ -1,12 +0,0 @@
idf_component_register(
SRCS
"ena-cwa.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
esp_http_client
ena
ena-binary-export
wifi-controller
EMBED_FILES
"certs/telekom.pem"
)

View File

@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFwDCCBKigAwIBAgIIfjnHrR3Z8EMwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
BAYTAkRFMSswKQYDVQQKDCJULVN5c3RlbXMgRW50ZXJwcmlzZSBTZXJ2aWNlcyBH
bWJIMR8wHQYDVQQLDBZULVN5c3RlbXMgVHJ1c3QgQ2VudGVyMSUwIwYDVQQDDBxU
LVRlbGVTZWMgR2xvYmFsUm9vdCBDbGFzcyAyMB4XDTE0MDIxMTE0MzkxMFoXDTI0
MDIxMTIzNTk1OVowgd8xCzAJBgNVBAYTAkRFMSUwIwYDVQQKDBxULVN5c3RlbXMg
SW50ZXJuYXRpb25hbCBHbWJIMR8wHQYDVQQLDBZULVN5c3RlbXMgVHJ1c3QgQ2Vu
dGVyMRwwGgYDVQQIDBNOb3JkcmhlaW4gV2VzdGZhbGVuMQ4wDAYDVQQRDAU1NzI1
MDEQMA4GA1UEBwwHTmV0cGhlbjEgMB4GA1UECQwXVW50ZXJlIEluZHVzdHJpZXN0
ci4gMjAxJjAkBgNVBAMMHVRlbGVTZWMgU2VydmVyUGFzcyBDbGFzcyAyIENBMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3oxwJVY3bSb6ejJ42f9VEt1N
vW2swwllcs5ifPsHAulpSoFc2Y9gMOKQqkuyjN1foCegDDeEr6FBLD5YuROldcX8
2aDNBKDh9GpSJYZMLrYwlfR4EJUGwLidHDn93H95j1M67sNlCyCfcbso0zFBQzXK
KO06sbC1QH9M1Xdrltz8bQS+LbGRTM5JcPYhhxXcnsFstQVaGmfqFQitPXhT3g9+
8Fbob6taSylFVk1E89G2N0NrrtIVTnaD0PcWF8AdMyX34zIoQAXMezyGV2kqst/Q
Ghvzd09jjMT6f8Q8pAlyGFTGuxsEjeU/rrS/yKU8bFEEvuR5WT/I4Kme+8OlzQID
AQABo4IB2TCCAdUwEgYDVR0TAQH/BAgwBgEB/wIBADBDBgNVHSAEPDA6MDgGBFUd
IAAwMDAuBggrBgEFBQcCARYiaHR0cDovL3BraS50ZWxlc2VjLmRlL2Nwcy9jcHMu
aHRtbDAOBgNVHQ8BAf8EBAMCAQYwge8GA1UdHwSB5zCB5DA1oDOgMYYvaHR0cDov
L3BraS50ZWxlc2VjLmRlL3JsL0dsb2JhbFJvb3RfQ2xhc3NfMi5jcmwwgaqggaeg
gaSGgaFsZGFwOi8vcGtpLnRlbGVzZWMuZGUvQ049VC1UZWxlU2VjJTIwR2xvYmFs
Um9vdCUyMENsYXNzJTIwMixPVT1ULVN5c3RlbXMlMjBUcnVzdCUyMENlbnRlcixP
PVQtU3lzdGVtcyUyMEVudGVycHJpc2UlMjBTZXJ2aWNlcyUyMEdtYkgsQz1ERT9B
dXRob3JpdHlSZXZvY2F0aW9uTGlzdDA4BggrBgEFBQcBAQQsMCowKAYIKwYBBQUH
MAGGHGh0dHA6Ly9vY3NwLnRlbGVzZWMuZGUvb2NzcHIwHQYDVR0OBBYEFJTIdEb1
OrRGSCb4K8o0HlYmBBIAMB8GA1UdIwQYMBaAFL9ZIDYAeaCgImuM1fJh0rgsy4JK
MA0GCSqGSIb3DQEBCwUAA4IBAQB55S9CfCkclWVtUIxl2c4aM5wqlLZRZ7zVhynK
KOhWKyTw+D2BOjc+TXIPkgRMqF3Sn8ZD4UTOARboJxswYnLZDkvBuvTbYa+N52Jy
oBP2TXIpEWEyJl7Oq8NFbERwg4X6MabLgjGvJETicPpKGfAINKDwPScQCsWHiCaX
X50cZzmWw17S0rWECOvPEt/4tXJ4Me9aAxx6WRm708n/K8O4mB3AzvA/M7VUDaP9
8LtreoTnWInjyg/8+Ahtce3foMXiIP4+9IX7fbm6yqh4u33tqMESDcRP6eGdzq4D
qnHyIvj9XNpuGgMvDgq357kZQS9e5XVH5icSvW1kr2kX2t1f
-----END CERTIFICATE-----

View File

@ -1,128 +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 "esp_log.h"
#include "esp_event.h"
#include "esp_http_client.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ena-storage.h"
#include "ena-exposure.h"
#include "ena-binary-export.h"
#include "wifi-controller.h"
#include "ena-cwa.h"
extern uint8_t export_bin_start[] asm("_binary_export_bin_start"); // test data from Google or https://svc90.main.px.t-online.de/version/v1/diagnosis-keys/country/DE/date/2020-07-22
extern uint8_t export_bin_end[] asm("_binary_export_bin_end");
extern const uint8_t telekom_pem_start[] asm("_binary_telekom_pem_start");
extern const uint8_t telekom__pem_end[] asm("_binary_telekom_pem_end");
esp_err_t ena_cwa_http_event_handler(esp_http_client_event_t *evt)
{
static char *output_buffer;
static int output_len;
switch (evt->event_id)
{
case HTTP_EVENT_ON_DATA:
if (!esp_http_client_is_chunked_response(evt->client))
{
if (output_buffer == NULL)
{
output_buffer = (char *)malloc(esp_http_client_get_content_length(evt->client));
output_len = 0;
if (output_buffer == NULL)
{
ESP_LOGE(ENA_CWA_LOG, "Failed to allocate memory for output buffer, memory: %d kB", (xPortGetFreeHeapSize() / 1024));
return ESP_FAIL;
}
}
memcpy(output_buffer + output_len, evt->data, evt->data_len);
output_len += evt->data_len;
}
break;
case HTTP_EVENT_ON_FINISH:
if (output_buffer != NULL)
{
ESP_LOGD(ENA_CWA_LOG, "memory: %d kB", (xPortGetFreeHeapSize() / 1024));
free(output_buffer);
output_buffer = NULL;
output_len = 0;
ESP_ERROR_CHECK_WITHOUT_ABORT(ena_binary_export_check_export(export_bin_start, (export_bin_end - export_bin_start)));
}
else
{
return ESP_FAIL;
}
break;
default:
break;
}
return ESP_OK;
}
esp_err_t ena_cwa_receive_keys(char *date_string)
{
char *url = malloc(strlen(ENA_CWA_KEYFILES_URL) + strlen(date_string));
sprintf(url, ENA_CWA_KEYFILES_URL, date_string);
esp_http_client_config_t config = {
.url = url,
.cert_pem = (char *)telekom_pem_start,
.event_handler = ena_cwa_http_event_handler,
};
ESP_LOGD(ENA_CWA_LOG, "start memory: %d kB, %s", (xPortGetFreeHeapSize() / 1024), date_string);
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK)
{
int content_length = esp_http_client_get_content_length(client);
ESP_LOGD(ENA_CWA_LOG, "Url = %s, Status = %d, content_length = %d", url,
esp_http_client_get_status_code(client),
content_length);
}
free(url);
esp_http_client_close(client);
esp_http_client_cleanup(client);
return err;
}
void ena_cwa_run(void)
{
static time_t current_time = 0;
static uint32_t last_check = 0;
current_time = time(NULL);
last_check = ena_storage_read_last_exposure_date();
if ((((uint32_t)current_time) - last_check) / (60 * 60 * 24) > 0 && wifi_controller_connection() != NULL)
{
char date_string[11];
struct tm *time_info;
time_info = localtime(&current_time);
time_info->tm_mday--;
strftime(date_string, 11, "%Y-%m-%d", time_info);
esp_err_t err = ena_cwa_receive_keys(date_string);
if (err == ESP_OK)
{
ena_storage_write_last_exposure_date((uint32_t)current_time);
ena_exposure_summary(ena_exposure_default_config());
}
}
}

View File

@ -1,43 +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 connection to german Exposure Notification App (Corona Warn App)
*
* This is for receiving the Exposure Key export for germany and for report own infection inside germany.
*
*/
#ifndef _ena_CWA_H_
#define _ena_CWA_H_
#include "esp_err.h"
#define ENA_CWA_LOG "ESP-ENA-cwa" // TAG for Logging
#define ENA_CWA_KEYFILES_URL "https://svc90.main.px.t-online.de/version/v1/diagnosis-keys/country/DE/date/%s"
/**
* @brief fetch key export for given date
*
* @param[in] date_string the date to fetch the data for
*/
esp_err_t ena_cwa_receive_keys(char *date_string);
/**
* @brief start ena CWA
*/
void ena_cwa_run(void);
#endif

View File

@ -1,7 +0,0 @@
idf_component_register(
SRCS
"i2c-main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
driver
)

View File

@ -1,40 +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 "driver/i2c.h"
#include "i2c-main.h"
static bool i2c_initialized = false;
void i2c_main_init()
{
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_SDA_PIN,
.scl_io_num = I2C_SCL_PIN,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_CLK_SPEED};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &i2c_config));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0));
i2c_initialized = true;
}
bool i2c_is_initialized()
{
return i2c_initialized;
}

View File

@ -1,41 +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 start I2C driver for display and RTC.
*
*/
#ifndef _i2c_main_H_
#define _i2c_main_H_
#define I2C_SDA_PIN (23)
#define I2C_SCL_PIN (22)
#define I2C_CLK_SPEED (1000000)
/**
* @brief initialize main I2C interface
*/
void i2c_main_init();
/**
* @brief check if I2C interface already initialized
*
* @return
* - false I2C not initialized
* - true I2C initialized
*/
bool i2c_is_initialized();
#endif

View File

@ -1,7 +0,0 @@
idf_component_register(
SRCS
"button-input.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
interface
)

View File

@ -1,83 +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 "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "interface.h"
#include "button-input.h"
static int old_button_states[INTERFACE_COMMANDS_SIZE];
static int button_states[INTERFACE_COMMANDS_SIZE];
static int button_command_mapping[INTERFACE_COMMANDS_SIZE];
void button_input_check(interface_command_t command)
{
button_states[command] = gpio_get_level(button_command_mapping[command]);
if (old_button_states[command] != 0 && old_button_states[command] != 1)
{
old_button_states[command] = 1;
}
if (button_states[command] == 0 && button_states[command] != old_button_states[command])
{
interface_execute_command(command);
}
old_button_states[command] = button_states[command];
}
void button_input_task(void *pvParameter)
{
while (1)
{
button_input_check(INTERFACE_COMMAND_RST);
button_input_check(INTERFACE_COMMAND_SET);
button_input_check(INTERFACE_COMMAND_MID);
button_input_check(INTERFACE_COMMAND_RHT);
button_input_check(INTERFACE_COMMAND_LFT);
button_input_check(INTERFACE_COMMAND_DWN);
button_input_check(INTERFACE_COMMAND_UP);
vTaskDelay(20 / portTICK_PERIOD_MS);
}
}
void button_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);
button_command_mapping[INTERFACE_COMMAND_RST] = BUTTON_RST;
button_command_mapping[INTERFACE_COMMAND_SET] = BUTTON_SET;
button_command_mapping[INTERFACE_COMMAND_MID] = BUTTON_MID;
button_command_mapping[INTERFACE_COMMAND_RHT] = BUTTON_RHT;
button_command_mapping[INTERFACE_COMMAND_LFT] = BUTTON_LFT;
button_command_mapping[INTERFACE_COMMAND_DWN] = BUTTON_DWN;
button_command_mapping[INTERFACE_COMMAND_UP] = BUTTON_UP;
xTaskCreate(&button_input_task, "button_input_task", 4096, NULL, 5, NULL);
}

View File

@ -1,38 +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 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
/**
* @brief
*
*
*/
void button_input_start(void);
#endif

View File

@ -1,20 +0,0 @@
idf_component_register(
SRCS
"interface.c"
"interface-main.c"
"interface-data.c"
"interface-datetime.c"
"interface-input.c"
"interface-label.c"
"interface-report.c"
"interface-settings.c"
"interface-wifi.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
ena
display
display-ssd1306
rtc
rtc-ds3231
wifi-controller
)

View File

@ -1,195 +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"
#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;
display_clear_line( 2, false);
display_clear_line( 4, false);
display_clear_line( 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;
display_clear_line( 2, false);
display_clear_line( 4, false);
display_clear_line( 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)
{
display_clear_line( 2, false);
display_clear_line( 4, false);
display_clear_line( 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--;
}
display_clear_line( 2, false);
display_clear_line( 4, false);
display_clear_line( 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++;
}
display_clear_line( 2, false);
display_clear_line( 4, false);
display_clear_line( 6, false);
}
void interface_data_display(void)
{
display_menu_headline( interface_get_label_text(&interface_text_headline_data), true, 0);
if (confirm_current)
{
display_text_line_column( interface_get_label_text(&interface_text_data_del[current_interface_data_state]), 2, 2, false);
display_text_line_column( "?", 2, strlen(interface_get_label_text(&interface_text_data_del[current_interface_data_state])) + 2, false);
display_set_button( interface_get_label_text(&interface_text_button_cancel), true, false);
display_set_button( interface_get_label_text(&interface_text_button_ok), false, true);
}
else
{
display_clear_line( 5, false);
display_clear_line( 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)
{
display_data( display_gfx_arrow_right, 8, i * 2 + 2, 8, false);
}
display_text_line_column( 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_command_callback(INTERFACE_COMMAND_RST, &interface_data_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_data_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_data_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_data_rht);
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_data_mid);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_data_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_data_dwn);
interface_set_display_function(&interface_data_display);
ESP_LOGD(INTERFACE_LOG, "start delete data interface");
}

View File

@ -1,173 +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 "esp_log.h"
#include "driver/gpio.h"
#include "rtc.h"
#include "display.h"
#include "display-gfx.h"
#include "interface.h"
typedef enum
{
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_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_YEAR)
{
current_interface_datetime_state = INTERFACE_DATETIME_STATE_HOUR;
}
ESP_LOGD(INTERFACE_LOG, "datetime to %d", current_interface_datetime_state);
}
void interface_datetime_up(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);
rtc_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_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);
rtc_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];
display_menu_headline( 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;
display_clear_line( edit_line - 1, false);
display_clear_line( edit_line + 1, false);
time(&current_timstamp);
current_tm = localtime(&current_timstamp);
strftime(time_buffer, 16, INTERFACE_FORMAT_TIME, current_tm);
display_text_line_column( 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);
display_text_line_column( 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;
}
display_data( display_gfx_arrow_up, 8, edit_line - 1, edit_offset * 8 + 4, false);
display_chars( edit_char, edit_length, edit_line, edit_offset, true);
display_data( display_gfx_arrow_down, 8, edit_line + 1, edit_offset * 8 + 4, false);
}
void interface_datetime_start(void)
{
current_interface_datetime_state = INTERFACE_DATETIME_STATE_HOUR;
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_datetime_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_datetime_rht);
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_datetime_mid);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_datetime_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_datetime_dwn);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_datetime_set);
interface_register_command_callback(INTERFACE_COMMAND_RST, NULL);
interface_set_display_function(&interface_datetime_display);
ESP_LOGD(INTERFACE_LOG, "start datetime interface");
}

View File

@ -1,318 +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"
#include "interface.h"
static interface_text_callback current_input_callback_rst;
static interface_text_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
display_set_button( interface_get_label_text(&interface_text_button_cancel), true, false);
display_set_button( 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)
{
display_data( display_gfx_arrow_left, 8, 2, 0, false);
}
else
{
display_data( display_gfx_clear, 8, 2, 0, false);
}
// bounday
display_text_line_column( "______________", 2, 1, false);
// arrow
if (current_cursor < current_limit)
{
display_data( display_gfx_arrow_right, 8, 2, 15 * 8, false);
}
else
{
display_data( display_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], display_gfx_font[(uint8_t)current_text[i + start] - 32], 8);
}
display_data( textdata, length, 2, 8, true);
free(textdata);
// clear
display_clear_line( 0, false);
display_clear_line( 1, false);
display_clear_line( 3, false);
display_clear_line( 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
display_data( display_gfx_arrow_up, 8, 0, display_cursor * 8, false);
// upper char
display_data( display_gfx_font[prev_char], 8, 1, display_cursor * 8, false);
// sel char
display_data( display_gfx_font[current_char], 8, 2, display_cursor * 8, false);
// lower char
display_data( display_gfx_font[next_char], 8, 3, display_cursor * 8, false);
// arrow
display_data( display_gfx_arrow_down, 8, 4, display_cursor * 8, false);
}
void interface_input_set_text(char *text)
{
display_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_text_callback callback_rst, interface_text_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;
display_utf8_to_ascii("ABCDEFGHIJKLMNOPQRSTUVWXYZ", char_set_uppercase);
display_utf8_to_ascii("abcdefghijklmnopqrstuvwxyz", char_set_lowercase);
display_utf8_to_ascii(" !\"#$%&'()*+,-,&:;<=>@[\\]^_´`{}", char_set_special1);
display_utf8_to_ascii("0123456789", char_set_numeric);
display_utf8_to_ascii("ÄÖÜ", char_set_special_uppercasecase);
display_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_command_callback(INTERFACE_COMMAND_RST, &interface_input_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_input_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_input_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_input_rht);
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_input_mid);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_input_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_input_dwn);
interface_set_display_function(&interface_input_display);
ESP_LOGD(INTERFACE_LOG, "start input interface");
}

View File

@ -1,139 +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 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];
}

View File

@ -1,142 +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 "esp_log.h"
#include "driver/gpio.h"
#include "display.h"
#include "display-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)
{
display_data( display_gfx_wifi, 8, 0, 0, false);
}
else
{
display_data( display_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);
display_text_line_column( text_buffer, 0, 16 - strlen(text_buffer), false);
// current time
strftime(time_buffer, 16, INTERFACE_FORMAT_TIME, current_tm);
display_text_line_column( time_buffer, 1, 16 - strlen(time_buffer), false);
}
void interface_main_start(void)
{
interface_register_command_callback(INTERFACE_COMMAND_RST, &interface_main_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_main_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, NULL);
interface_register_command_callback(INTERFACE_COMMAND_RHT, NULL);
interface_register_command_callback(INTERFACE_COMMAND_MID, NULL);
interface_register_command_callback(INTERFACE_COMMAND_UP, NULL);
interface_register_command_callback(INTERFACE_COMMAND_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)
{
display_data( display_gfx_question[0], 24, 0, 12, false);
display_data( display_gfx_question[1], 24, 1, 12, false);
display_data( display_gfx_question[2], 24, 2, 12, false);
display_data( display_gfx_question[3], 24, 3, 12, false);
}
else if (current_exposure_summary->max_risk_score < 100)
{
display_data( display_gfx_smile[0], 24, 0, 12, false);
display_data( display_gfx_smile[1], 24, 1, 12, false);
display_data( display_gfx_smile[2], 24, 2, 12, false);
display_data( display_gfx_smile[3], 24, 3, 12, false);
}
else
{
display_data( display_gfx_sad[0], 24, 0, 12, false);
display_data( display_gfx_sad[1], 24, 1, 12, false);
display_data( display_gfx_sad[2], 24, 2, 12, false);
display_data( display_gfx_sad[3], 24, 3, 12, false);
}
// clock icon
display_data( display_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)
{
display_text_line_column( time_buffer, 4, 3, false);
}
// buttons
display_set_button( interface_get_label_text(&interface_text_button_menu), true, false);
display_set_button( interface_get_label_text(&interface_text_button_report), false, true);
ESP_LOGD(INTERFACE_LOG, "start main interface");
}

View File

@ -1,177 +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"
#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)
{
display_menu_headline( interface_get_label_text(&interface_text_headline_tan), false, 0);
// buttons
display_set_button( interface_get_label_text(&interface_text_button_cancel), true, false);
display_set_button( interface_get_label_text(&interface_text_button_ok), false, true);
static char tan_buffer[10] = {0};
if (interface_report_tan_index > 0)
{
display_data( display_gfx_arrow_left, 8, 3, 8, false);
}
else
{
display_data( display_gfx_clear, 8, 3, 8, false);
}
if (interface_report_tan_index < 9)
{
display_data( display_gfx_arrow_right, 8, 3, 112, false);
}
else
{
display_data( display_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]);
}
display_clear_line( 2, false);
display_clear_line( 4, false);
display_text_line_column( "-", 3, 5, false);
display_text_line_column( "-", 3, 9, false);
display_text_line_column( "___", 3, 2, false);
display_text_line_column( "___", 3, 6, false);
display_text_line_column( "____", 3, 10, false);
int offset = 2;
for (int i = 0; i < 3; i++)
{
if (i < interface_report_tan_index)
{
display_chars( &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)
{
display_chars( &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)
{
display_chars( &tan_buffer[i], 1, 3, i + offset, true);
}
}
}
display_data( display_gfx_arrow_up, 8, 2, interface_report_tan_index * 8 + offset * 8, false);
display_data( display_gfx_arrow_down, 8, 4, interface_report_tan_index * 8 + offset * 8, false);
display_chars( &tan_buffer[interface_report_tan_index], 1, 3, interface_report_tan_index + offset, false);
}
void interface_report_start(void)
{
interface_register_command_callback(INTERFACE_COMMAND_RST, &interface_report_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_report_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_report_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_report_rht);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_report_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_report_dwn);
interface_register_command_callback(INTERFACE_COMMAND_MID, NULL);
interface_set_display_function(&interface_report_display);
ESP_LOGD(INTERFACE_LOG, "start report interface");
}

View File

@ -1,147 +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"
#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;
}
display_clear_line( 2, false);
display_clear_line( 3, false);
display_clear_line( 4, false);
display_clear_line( 5, false);
display_clear_line( 6, false);
display_clear_line( 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)
{
display_menu_headline( interface_get_label_text(&interface_text_headline_settings), true, 0);
display_text_line_column( interface_get_label_text(&interface_text_settings_locale), 3, 1, false);
display_text_line_column( interface_get_label_text(&interface_text_settings_timezone), 6, 1, false);
if (current_interface_settings_state == INTERFACE_SETTINGS_LOCALE)
{
display_data( display_gfx_arrow_up, 8, 2, 12 * 8 + 4, false);
display_text_line_column(
interface_get_label_text(&interface_text_settings_locales[interface_get_locale()]), 3, 12, true);
display_data( display_gfx_arrow_down, 8, 4, 12 * 8 + 4, false);
}
else
{
display_text_line_column(
interface_get_label_text(&interface_text_settings_locales[interface_get_locale()]), 3, 12, true);
}
if (current_interface_settings_state == INTERFACE_SETTINGS_TIMEZONE)
{
display_data( display_gfx_arrow_up, 8, 5, 12 * 8 + 4, false);
display_data( display_gfx_arrow_down, 8, 7, 12 * 8 + 4, false);
}
}
void interface_settings_start(void)
{
current_interface_settings_state = INTERFACE_SETTINGS_LOCALE;
interface_register_command_callback(INTERFACE_COMMAND_RST, &interface_settings_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_settings_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_settings_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_settings_rht);
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_settings_mid);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_settings_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_settings_dwn);
interface_set_display_function(&interface_settings_display);
ESP_LOGD(INTERFACE_LOG, "start settings interface");
}

View File

@ -1,183 +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"
#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)
{
display_menu_headline( interface_get_label_text(&interface_text_headline_wifi), true, 0);
if (ap_count > 0)
{
display_clear_line( 2, false);
display_clear_line( 4, false);
display_clear_line( 6, false);
for (int i = 0; i < 3; i++)
{
int index = i + ap_index;
if (index < ap_count)
{
if (index == ap_selected)
{
display_data( display_gfx_arrow_right, 8, i * 2 + 2, 8, false);
}
if (sizeof(ap_info[i].ssid) > 0)
{
display_text_line_column( (char *)ap_info[index].ssid, i * 2 + 2, 2, false);
}
else
{
display_text_line_column( " / ", i * 2 + 2, 2, false);
}
if (ap_info[index].rssi >= -67)
{
display_data( display_gfx_wifi, 8, i * 2 + 2, 112, false);
}
else if (ap_info[index].rssi >= -80)
{
display_data( display_gfx_wifi_low, 8, i * 2 + 2, 112, false);
}
else if (ap_info[index].rssi >= -90)
{
display_data( display_gfx_wifi_lowest, 8, i * 2 + 2, 112, false);
}
}
}
}
else
{
display_text_line_column( interface_get_label_text(&interface_text_wifi_scanning), 4, 1, false);
}
}
void interface_wifi_start(void)
{
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_wifi_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_wifi_lft);
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_wifi_rht);
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_wifi_mid);
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_wifi_up);
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_wifi_dwn);
interface_register_command_callback(INTERFACE_COMMAND_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);
}

View File

@ -1,74 +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 "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "display.h"
#include "display-gfx.h"
#include "interface.h"
static interface_command_callback command_callbacks[INTERFACE_COMMANDS_SIZE];
static interface_display_function current_display_function;
void interface_register_command_callback(interface_command_t command, interface_command_callback callback)
{
command_callbacks[command] = callback;
}
void interface_set_display_function(interface_display_function display_function)
{
display_clear();
current_display_function = display_function;
}
void interface_execute_command(interface_command_t command)
{
if (command_callbacks[command] != NULL)
{
display_clear();
(*command_callbacks[command])();
}
}
void interface_display_task(void *pvParameter)
{
while (1)
{
if (current_display_function != NULL)
{
(*current_display_function)();
}
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void interface_start(void)
{
xTaskCreate(&interface_display_task, "interface_display_task", 4096, NULL, 5, NULL);
// init label
interface_init_label();
display_start();
display_clear();
for (int i = 0; i < 8; i++)
{
display_data(display_gfx_logo[i], 64, i, 32, false);
}
}

View File

@ -1,209 +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 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_FORMAT_TIME "%X"
#define INTERFACE_NUM_LOCALE 2
/**
* @brief available commands
*/
typedef enum
{
INTERFACE_COMMAND_RST = 0,
INTERFACE_COMMAND_SET,
INTERFACE_COMMAND_MID,
INTERFACE_COMMAND_RHT,
INTERFACE_COMMAND_LFT,
INTERFACE_COMMAND_DWN,
INTERFACE_COMMAND_UP,
INTERFACE_COMMANDS_SIZE,
} interface_command_t;
/**
* @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 command input (button press)
*/
typedef void (*interface_command_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_text_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 command event
*
* @param[in] command id of the command to listen to
* @param[in] callback callback function
*/
void interface_register_command_callback(interface_command_t command, interface_command_callback callback);
/**
* @brief execute a command
*
* @param[in] command id of the command to trigger
*/
void interface_execute_command(interface_command_t command);
/**
* @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_text_callback callback_rst, interface_text_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

View File

@ -1,8 +0,0 @@
idf_component_register(
SRCS
"ds3231.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
rtc
i2c-main
)

View File

@ -1,120 +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 <time.h>
#include "driver/i2c.h"
#include "esp_log.h"
#include "rtc.h"
#include "i2c-main.h"
#include "ds3231.h"
uint8_t ds3231_dec2bcd(uint8_t value)
{
return ((value / 10 * 16) + (value % 10));
}
uint8_t ds3231_bcd2dec(uint8_t value)
{
return ((value / 16 * 10) + (value % 16));
}
void rtc_get_time(struct tm *time)
{
if (!i2c_is_initialized())
{
i2c_main_init();
}
uint8_t data[7];
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (DS3231_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, DS3231_TIME, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (DS3231_ADDRESS << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd, data, 7, 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);
time->tm_sec = ds3231_bcd2dec(data[0]);
time->tm_min = ds3231_bcd2dec(data[1]);
if (data[2] & DS3231_12_HOUR_FLAG)
{
time->tm_hour = ds3231_bcd2dec(data[2] & DS3231_12_HOUR_MASK) - 1;
if (data[2] & DS3231_PM_HOUR_FLAG)
{
time->tm_hour += 12;
}
}
else
{
time->tm_hour = ds3231_bcd2dec(data[2]);
}
time->tm_wday = ds3231_bcd2dec(data[3]) - 1;
time->tm_mday = ds3231_bcd2dec(data[4]);
time->tm_mon = ds3231_bcd2dec(data[5] & DS3231_MONTH_MASK) - 1;
uint8_t century = (data[5] & DS3231_CENTURY_FLAG) >> 7;
if (century)
{
time->tm_year = ds3231_bcd2dec(data[6]) + 100;
}
else
{
time->tm_year = ds3231_bcd2dec(data[6]);
}
time->tm_isdst = 0;
}
void rtc_set_time(struct tm *time)
{
if (!i2c_is_initialized())
{
i2c_main_init();
}
uint8_t data[7] = {0};
data[0] = ds3231_dec2bcd(time->tm_sec);
data[1] = ds3231_dec2bcd(time->tm_min);
data[2] = ds3231_dec2bcd(time->tm_hour); // write 24h format
data[3] = ds3231_dec2bcd(time->tm_wday + 1);
data[4] = ds3231_dec2bcd(time->tm_mday);
uint8_t century = 0;
if (time->tm_year > 100)
{
century = DS3231_CENTURY_FLAG;
data[6] = ds3231_dec2bcd(time->tm_year - 100);
}
else
{
data[6] = ds3231_dec2bcd(time->tm_year);
}
data[5] = ds3231_dec2bcd(time->tm_mon + 1) + century;
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (DS3231_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, DS3231_TIME, true);
i2c_master_write(cmd, data, 7, 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);
}

View File

@ -1,74 +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 I2C driver for DS3231 Real Time Clock
*
*/
#ifndef _ds3231_H_
#define _ds3231_H_
#include <time.h>
// I2C address
#define DS3231_ADDRESS 0x68
// I2C registers
#define DS3231_TIME 0x00
#define DS3231_SECONDS 0x00
#define DS3231_MINUTES 0x01
#define DS3231_HOURS 0x02
#define DS3231_DAY 0x03
#define DS3231_DATE 0x04
#define DS3231_MONTH 0x05
#define DS3231_YEAR 0x06
#define DS3231_ALARM1_SECONDS 0x07
#define DS3231_ALARM1_MINUTES 0x08
#define DS3231_ALARM1_HOURS 0x09
#define DS3231_ALARM1_DATE 0x0A
#define DS3231_ALARM2_MINUTES 0x0B
#define DS3231_ALARM2_HOURS 0x0C
#define DS3231_ALARM2_DATE 0x0D
#define DS3231_CONTROL 0x0E
#define DS3231_STATUS 0x0F
#define DS3231_AGING_OFFSET 0x10
#define DS3231_MSB_TEMP 0x11
#define DS3231_LSB_TEMP 0x12
// control registers
#define DS3231_CONTROL_A1IE 0x01
#define DS3231_CONTROL_A2IE 0x02
#define DS3231_CONTROL_INTCN 0x04
#define DS3231_CONTROL_RS1 0x08
#define DS3231_CONTROL_RS2 0x10
#define DS3231_CONTROL_CONV 0x20
#define DS3231_CONTROL_BBSQW 0x40
#define DS3231_CONTROL_EOSC 0x80
// status registers
#define DS3231_STATUSL_A1F 0x01
#define DS3231_STATUSL_A2F 0x02
#define DS3231_STATUSL_BSY 0x04
#define DS3231_STATUSL_EN32KHZ 0x08
#define DS3231_STATUSL_OSF 0x80
// flags
#define DS3231_CENTURY_FLAG 0x80
#define DS3231_12_HOUR_FLAG 0x40
#define DS3231_PM_HOUR_FLAG 0x20
#define DS3231_12_HOUR_MASK 0x1F
#define DS3231_MONTH_MASK 0x1F
#endif

View File

@ -1,4 +0,0 @@
idf_component_register(
SRCS
INCLUDE_DIRS "."
)

View File

@ -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 for RTC
*
*/
#ifndef _rtc_H_
#define _rtc_H_
#include <time.h>
/**
* @brief Read time
*/
void rtc_get_time(struct tm *time);
/**
* @brief Write time
*/
void rtc_set_time(struct tm *time);
#endif

View File

@ -1,8 +0,0 @@
idf_component_register(
SRCS
"wifi-controller.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
esp_wifi
nvs_flash
)

View File

@ -1,185 +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 "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "wifi-controller.h"
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static EventGroupHandle_t s_wifi_event_group;
static bool initialized = false;
static wifi_ap_record_t current_wifi_ap;
void wifi_controller_init(void)
{
// init NVS for WIFI
esp_err_t ret;
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ESP_ERROR_CHECK(nvs_flash_init());
}
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
initialized = true;
}
void wifi_controller_scan(wifi_ap_record_t *ap_info, uint16_t *ap_count)
{
if (!initialized)
{
wifi_controller_init();
}
uint16_t number = 10;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, true));
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(ap_count));
ESP_ERROR_CHECK(esp_wifi_stop());
}
static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ESP_LOGD(WIFI_LOG, "got IP");
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
heap_caps_check_integrity_all(true);
}
}
esp_err_t wifi_controller_connect(wifi_config_t wifi_config)
{
if (!initialized)
{
wifi_controller_init();
}
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
s_wifi_event_group = xEventGroupCreate();
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGV(WIFI_LOG, "connected to ap SSID:%s", wifi_config.sta.ssid);
return ESP_OK;
}
else if (bits & WIFI_FAIL_BIT)
{
ESP_LOGI(WIFI_LOG, "Failed to connect to SSID:%s with PASSWORD:%s", wifi_config.sta.ssid, wifi_config.sta.password);
return ESP_ERR_INVALID_ARG;
}
else
{
ESP_LOGE(WIFI_LOG, "UNEXPECTED EVENT");
return ESP_FAIL;
}
}
esp_err_t wifi_controller_reconnect(void)
{
if (!initialized)
{
wifi_controller_init();
}
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
s_wifi_event_group = xEventGroupCreate();
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGV(WIFI_LOG, "reconnected to last ap");
return ESP_OK;
}
else if (bits & WIFI_FAIL_BIT)
{
ESP_LOGI(WIFI_LOG, "Failed to reconnect to last ap");
return ESP_ERR_INVALID_ARG;
}
else
{
ESP_LOGE(WIFI_LOG, "UNEXPECTED EVENT");
return ESP_FAIL;
}
}
wifi_ap_record_t *wifi_controller_connection(void)
{
if (esp_wifi_sta_get_ap_info(&current_wifi_ap) == ESP_OK)
{
ESP_LOGD(WIFI_LOG, "Current AP: %s", current_wifi_ap.ssid);
return &current_wifi_ap;
}
return NULL;
}

View File

@ -1,56 +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.
#ifndef _wifi_CONTROLLER_H_
#define _wifi_CONTROLLER_H_
#include "esp_err.h"
#include "esp_wifi_types.h"
#define WIFI_LOG "wifi-controller" // TAG for Logging
/**
* @brief scan for WiFis
*
* @param[out] ap_info scanned APs
* @param[out] ap_count number of scanned APs
*/
void wifi_controller_scan(wifi_ap_record_t ap_info[], uint16_t *ap_count);
/**
* @brief connect to wifi ap
*
* @param[in] wifi_config config of wifi to connect
*
* @return
* esp_err_t connection status
*/
esp_err_t wifi_controller_connect(wifi_config_t wifi_config);
/**
* @brief reconnect to previous wifi
*
* @return
* esp_err_t connection status
*/
esp_err_t wifi_controller_reconnect(void);
/**
* @brief reconnect to previous wifi
*
* @return
* wifi_ap_record_t pointer to current wifi connection, NULL if not connected
*/
wifi_ap_record_t *wifi_controller_connection(void);
#endif

View File

@ -1,5 +0,0 @@
idf_component_register(
SRCS
"main.c"
INCLUDE_DIRS ""
)

View File

@ -1,84 +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 "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <time.h>
#include <sys/time.h>
#include "esp_system.h"
#include "esp_log.h"
#include "ena.h"
#include "ena-storage.h"
#include "ena-beacons.h"
#include "ena-exposure.h"
#include "ena-bluetooth-advertise.h"
#include "ena-bluetooth-scan.h"
#include "ena-cwa.h"
#include "ds3231.h"
#include "ssd1306.h"
#include "interface.h"
#include "button-input.h"
#include "rtc.h"
#include "wifi-controller.h"
#include "sdkconfig.h"
void app_main(void)
{
// debug only own LOG TAGs
esp_log_level_set("*", ESP_LOG_WARN);
esp_log_level_set(ENA_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_BEACON_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_ADVERTISE_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_SCAN_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_EXPOSURE_LOG, ESP_LOG_DEBUG);
esp_log_level_set(ENA_STORAGE_LOG, ESP_LOG_INFO);
esp_log_level_set(ENA_CWA_LOG, ESP_LOG_DEBUG);
esp_log_level_set(INTERFACE_LOG, ESP_LOG_DEBUG);
esp_log_level_set(WIFI_LOG, ESP_LOG_DEBUG);
// start interface
interface_start();
// set system time from RTC
struct tm rtc_time;
rtc_get_time(&rtc_time);
time_t curtime = mktime(&rtc_time);
struct timeval tv = {0};
tv.tv_sec = curtime;
settimeofday(&tv, NULL);
// Hardcoded timezone of UTC+2 for now (consider POSIX notation!)
setenv("TZ", "UTC-2", 1);
tzset();
ena_start();
// start with main interface
interface_main_start();
// start button input
button_input_start();
while (1)
{
ena_run();
ena_cwa_run();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}