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)).
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.
@ -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!)
* 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
* WiFi or other external connection needed for infections status (auto-connect to open WiFis?)
* obtaining accessibility
@ -72,51 +55,9 @@ So on average it is possible to meet 38 (24 on a lower boundary) different devic
### 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
```
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
```
### Include into project
## 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.
### 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](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);
}
}