mirror of
https://github.com/Lurkars/esp-ena.git
synced 2024-11-22 10:06:11 +01:00
updated interface, added M5Stick (PLUS) support
This commit is contained in:
parent
559ed3762a
commit
0d3fd854f8
67
README.md
67
README.md
@ -23,6 +23,8 @@ The following acronyms will be used in code and comments:
|
||||
* Upload of own Exposure keys to proxy server
|
||||
|
||||
Additional features for full ENA device
|
||||
|
||||
#### Custom 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
|
||||
@ -34,6 +36,15 @@ Additional features for full ENA device
|
||||
* enter tan and uploading own exposure keys
|
||||
* battery support with ESP32 dev-boards with integrated LiPo support
|
||||
|
||||
#### M5StickC and M5StickC PLUS
|
||||
* RTC support
|
||||
* PMU support
|
||||
* display support
|
||||
* interface with 2 buttons and accelometer control
|
||||
* ok/cancel with button 1 and button 2 (depending on screen orientation)
|
||||
* up, down, left, right with tilting device
|
||||
* long press button 1 for changing character set on input
|
||||
|
||||
### Features in development
|
||||
* 3d print case
|
||||
|
||||
@ -78,30 +89,46 @@ For base functionality just an ESP32 is required. DS3231 RTC, SSD1306 Display an
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
required
|
||||
**required**
|
||||
* enable bluetooth (BLE)
|
||||
> Component config -> Bluetooth -> [*] Bluetooth
|
||||
* add partition-table for storage (currently hardcoded name "ena")
|
||||
> Partition Table -> Partition table -> (x) Custom partition table CSV
|
||||
* mbedTLS enable HKDF
|
||||
> Component config -> mbedTLS -> [*] HKDF algorithm (RFC 5869)
|
||||
* flash size > 3.9GB
|
||||
> Serial flasher config -> Flash size -> (x) 4MB
|
||||
* choose interface device (custom, M5StickC or M5StickC PLUS)
|
||||
> ENA Interface -> ENA Interface device
|
||||
|
||||
recommended
|
||||
**recommended**
|
||||
* BLE *Scan Duplicate* (By Device Address and Advertising Data)
|
||||
> Component config -> Bluetooth -> Bluetooth controller -> Scan Duplicate Type -> (X) Scan Duplicate By Device Address And Advertising Data
|
||||
|
||||
debug options
|
||||
**debug options**
|
||||
* Log output set to Debug
|
||||
> Component config -> Log output -> Default log verbosity -> (X) Debug
|
||||
* Exposure Notification API / Storage enable *Dump storage*
|
||||
> Exposure Notification API -> Storage -> [X] Dump storage
|
||||
|
||||
#### Configure device manually!
|
||||
|
||||
Select required device drivers manually, because config get not applied in interface's CmakeLists.txt (I don't know why!):
|
||||
> comment in/out line in *components/interface/CmakeLists.txt* with matching interface
|
||||
|
||||
|
||||
### Build and Flash
|
||||
|
||||
May flash partition table:
|
||||
|
||||
```
|
||||
idf.py partition_table-flash
|
||||
idf.py partition_table-flash -b 1500000
|
||||
```
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
idf.py -p PORT flash -b 1500000 monitor
|
||||
```
|
||||
|
||||
(Replace PORT with the name of the serial port to use.)
|
||||
@ -155,19 +182,43 @@ General module for set/get time from RTC.
|
||||
|
||||
### i2c-main
|
||||
|
||||
Just start I2C driver for display and RTC.
|
||||
Just start I²C driver for display and RTC.
|
||||
|
||||
### interface-input-buttons
|
||||
|
||||
Interface with 7 button input
|
||||
|
||||
### interface-input-m5
|
||||
|
||||
Interface with input for M5StickC (PLUS) with 2 button input and accelometer as axis input
|
||||
|
||||
### rtc-ds3231
|
||||
|
||||
I2C driver for a DS3231 RTC, implementation of [rtc](#-rtc) module
|
||||
I²C driver for a DS3231 RTC, implementation of [rtc](#-rtc) module
|
||||
|
||||
### rtc-bm8563
|
||||
|
||||
I²C driver for BM8563 of M5StickC (PLUS), implementation of [rtc](#-rtc) module
|
||||
|
||||
### display-ssd1306
|
||||
|
||||
I2C driver for a SSD1306 display, implementation of [display](#-display) module
|
||||
I²C driver for a SSD1306 display, implementation of [display](#-display) module
|
||||
|
||||
### display-st7735s
|
||||
|
||||
SPI driver for a ST7735s display of M5StickC, implementation of [display](#-display) module
|
||||
|
||||
### display-st7789
|
||||
|
||||
SPI driver for a ST7789 display of M5StickC PLUS, implementation of [display](#-display) module
|
||||
|
||||
### imu-mpu6886
|
||||
|
||||
I²C driver for MPU6886 6-Axis IMU of M5StickC (PLUS)
|
||||
|
||||
### pmu-axp192
|
||||
|
||||
I²C driver for AXP192 PMU of M5StickC (PLUS)
|
||||
|
||||
### ena-binary-export \[deprecared\]
|
||||
|
||||
|
@ -3,6 +3,6 @@ idf_component_register(
|
||||
"ssd1306.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
display
|
||||
i2c-main
|
||||
"display"
|
||||
"i2c-main"
|
||||
)
|
@ -221,117 +221,27 @@ void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bo
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void display_text_line_column(char *text, uint8_t line, uint8_t offset, bool invert)
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SEGMENT_HIGH, true);
|
||||
|
||||
void display_text_input(char *text, uint8_t position)
|
||||
if (flipped)
|
||||
{
|
||||
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);
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SCAN_DIRECTION_NORMAL, true);
|
||||
}
|
||||
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;
|
||||
i2c_master_write_byte(cmd, SSD1306_CMD_SCAN_DIRECTION_REMAPPED, true);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
9
components/display-st7735s/CMakeLists.txt
Normal file
9
components/display-st7735s/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"st7735s.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
"display"
|
||||
"spi_flash"
|
||||
"pmu-axp192"
|
||||
)
|
340
components/display-st7735s/st7735s.c
Normal file
340
components/display-st7735s/st7735s.c
Normal file
@ -0,0 +1,340 @@
|
||||
// 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 <math.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
#include "axp192.h"
|
||||
|
||||
#include "st7735s.h"
|
||||
|
||||
static spi_device_handle_t st7735s_handle;
|
||||
|
||||
bool spi_master_write(uint8_t *data, size_t len, uint8_t dc)
|
||||
{
|
||||
spi_transaction_t spi_trans;
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_set_level(M5_ST7735S_DC_GPIO, dc);
|
||||
|
||||
memset(&spi_trans, 0, sizeof(spi_transaction_t));
|
||||
spi_trans.length = len * 8;
|
||||
spi_trans.tx_buffer = data;
|
||||
ret = spi_device_transmit(st7735s_handle, &spi_trans);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_master_write_command(uint8_t cmd)
|
||||
{
|
||||
return spi_master_write(&cmd, 1, SPI_COMMAND_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data_byte(uint8_t data)
|
||||
{
|
||||
return spi_master_write(&data, 1, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data(uint8_t *data, size_t len)
|
||||
{
|
||||
return spi_master_write(data, len, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_addr(uint16_t addr1, uint16_t addr2)
|
||||
{
|
||||
uint8_t data[4];
|
||||
data[0] = (addr1 >> 8) & 0xFF;
|
||||
data[1] = addr1 & 0xFF;
|
||||
data[2] = (addr2 >> 8) & 0xFF;
|
||||
data[3] = addr2 & 0xFF;
|
||||
|
||||
return spi_master_write_data(data, 4);
|
||||
}
|
||||
|
||||
bool spi_master_write_color(uint16_t color, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
|
||||
uint8_t msbColor = (color >> 8) & 0xFF;
|
||||
uint8_t lsbColor = color & 0xFF;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = msbColor;
|
||||
data[index++] = lsbColor;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
bool spi_master_write_colors(uint16_t *colors, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = (colors[i] >> 8) & 0xFF;
|
||||
data[index++] = colors[i] & 0xFF;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
|
||||
axp192_start();
|
||||
axp192_screen_breath(0);
|
||||
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_set_direction(M5_ST7735S_CS_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7735S_CS_GPIO, 0);
|
||||
|
||||
gpio_set_direction(M5_ST7735S_DC_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7735S_DC_GPIO, 0);
|
||||
|
||||
gpio_set_direction(M5_ST7735S_RESET_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7735S_RESET_GPIO, 0);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(M5_ST7735S_RESET_GPIO, 1);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = M5_ST7735S_SCLK_GPIO,
|
||||
.mosi_io_num = M5_ST7735S_MOSI_GPIO,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1};
|
||||
|
||||
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = SPI_MASTER_FREQ_20M,
|
||||
.spics_io_num = M5_ST7735S_CS_GPIO,
|
||||
.queue_size = 7,
|
||||
.flags = SPI_DEVICE_NO_DUMMY,
|
||||
};
|
||||
|
||||
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &st7735s_handle);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_master_write_command(0x01); //Software Reset
|
||||
vTaskDelay(150 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x11); //Sleep Out
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0xB1); //Frame Rate Control (In normal mode/ Full colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB2); //Frame Rate Control (In Idle mode/ 8-colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB3); //Frame Rate Control (In Partial mode/ full colors)
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
|
||||
spi_master_write_command(0xB4); //Display Inversion Control
|
||||
spi_master_write_data_byte(0x07);
|
||||
|
||||
spi_master_write_command(0xC0); //Power Control 1
|
||||
spi_master_write_data_byte(0xA2);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x84);
|
||||
|
||||
spi_master_write_command(0xC1); //Power Control 2
|
||||
spi_master_write_data_byte(0xC5);
|
||||
|
||||
spi_master_write_command(0xC2); //Power Control 3 (in Normal mode/ Full colors)
|
||||
spi_master_write_data_byte(0x0A);
|
||||
spi_master_write_data_byte(0x00);
|
||||
|
||||
spi_master_write_command(0xC3); //Power Control 4 (in Idle mode/ 8-colors)
|
||||
spi_master_write_data_byte(0x8A);
|
||||
spi_master_write_data_byte(0x2A);
|
||||
|
||||
spi_master_write_command(0xC4); //Power Control 5 (in Partial mode/ full-colors)
|
||||
spi_master_write_data_byte(0x8A);
|
||||
spi_master_write_data_byte(0xEE);
|
||||
|
||||
spi_master_write_command(0xC5); //VCOM Control 1
|
||||
spi_master_write_data_byte(0x0E);
|
||||
|
||||
spi_master_write_command(0x20); //Display Inversion Off
|
||||
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
spi_master_write_data_byte(M5_ST7735S_LANDSCAPE); // landscape + RGB color
|
||||
|
||||
spi_master_write_command(0x3A); //Interface Pixel Format
|
||||
spi_master_write_data_byte(0x05); //16-bit/pixel 65K-Colors(RGB 5-6-5-bit Input)
|
||||
|
||||
spi_master_write_command(0x2A); //Column Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x81);
|
||||
|
||||
spi_master_write_command(0x2B); //Row Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xA0);
|
||||
|
||||
spi_master_write_command(0x21); //Display Inversion On
|
||||
|
||||
spi_master_write_command(0xE0); //Gamma (‘+’polarity) Correction Characteristics Setting
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x1C);
|
||||
spi_master_write_data_byte(0x07);
|
||||
spi_master_write_data_byte(0x12);
|
||||
spi_master_write_data_byte(0x37);
|
||||
spi_master_write_data_byte(0x32);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x25);
|
||||
spi_master_write_data_byte(0x2B);
|
||||
spi_master_write_data_byte(0x39);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x01);
|
||||
spi_master_write_data_byte(0x03);
|
||||
spi_master_write_data_byte(0x10);
|
||||
|
||||
spi_master_write_command(0xE1); //Gamma ‘-’polarity Correction Characteristics Setting
|
||||
spi_master_write_data_byte(0x03);
|
||||
spi_master_write_data_byte(0x1D);
|
||||
spi_master_write_data_byte(0x07);
|
||||
spi_master_write_data_byte(0x06);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x2C);
|
||||
spi_master_write_data_byte(0x29);
|
||||
spi_master_write_data_byte(0x2D);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x2E);
|
||||
spi_master_write_data_byte(0x37);
|
||||
spi_master_write_data_byte(0x3F);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x02);
|
||||
spi_master_write_data_byte(0x10);
|
||||
|
||||
spi_master_write_command(0x13); //Normal Display Mode On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x29); //Display On
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
|
||||
axp192_screen_breath(10);
|
||||
}
|
||||
|
||||
void display_rect(uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2, uint16_t color)
|
||||
{
|
||||
|
||||
uint16_t _x1 = x1 + M5_ST7735S_OFFSETX;
|
||||
uint16_t _x2 = x2 + M5_ST7735S_OFFSETX - 1;
|
||||
uint16_t _y1 = y1 + M5_ST7735S_OFFSETY;
|
||||
uint16_t _y2 = y2 + M5_ST7735S_OFFSETY - 1;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(color, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
display_rect(0, M5_ST7735S_WIDTH, line * 8, line * 8 + 8, invert ? display_get_color() : BLACK);
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
display_rect(0, M5_ST7735S_WIDTH, 0, M5_ST7735S_HEIGHT, BLACK);
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
axp192_screen_breath(on ? 10 : 0);
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
uint16_t _x1 = offset + M5_ST7735S_OFFSETX + M5_ST7735S_INTERFACE_OFFSETX;
|
||||
uint16_t _x2 = offset + length + M5_ST7735S_OFFSETX - 1 + M5_ST7735S_INTERFACE_OFFSETX;
|
||||
uint16_t _y1 = line * 8 + M5_ST7735S_OFFSETY + M5_ST7735S_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7735S_OFFSETY - 1 + M5_ST7735S_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); //Memory Write
|
||||
|
||||
uint8_t msbColor = (display_get_color() >> 8) & 0xFF;
|
||||
uint8_t lsbColor = display_get_color() & 0xFF;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t color[length * 2];
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
bool bit = (data[i] & (1 << j));
|
||||
if (invert)
|
||||
{
|
||||
bit = !bit;
|
||||
}
|
||||
color[index++] = bit ? msbColor : 0x00;
|
||||
color[index++] = bit ? lsbColor : 0x00;
|
||||
}
|
||||
spi_master_write_data(color, length * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
if (flipped)
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7735S_LANDSCAPE_FLIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7735S_LANDSCAPE);
|
||||
}
|
||||
}
|
27
components/display-st7735s/st7735s.h
Normal file
27
components/display-st7735s/st7735s.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef DISPLAY_ST7735S_H_
|
||||
#define DISPLAY_ST7735S_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
// M5stickC
|
||||
#define M5_ST7735S_WIDTH 160
|
||||
#define M5_ST7735S_HEIGHT 80
|
||||
#define M5_ST7735S_MOSI_GPIO 15
|
||||
#define M5_ST7735S_SCLK_GPIO 13
|
||||
#define M5_ST7735S_CS_GPIO 5
|
||||
#define M5_ST7735S_DC_GPIO 23
|
||||
#define M5_ST7735S_RESET_GPIO 18
|
||||
|
||||
#define M5_ST7735S_OFFSETX 1
|
||||
#define M5_ST7735S_OFFSETY 26
|
||||
|
||||
#define M5_ST7735S_INTERFACE_OFFSETX 16
|
||||
#define M5_ST7735S_INTERFACE_OFFSETY 8
|
||||
|
||||
#define M5_ST7735S_LANDSCAPE_FLIPPED 0x60
|
||||
#define M5_ST7735S_LANDSCAPE 0xA0
|
||||
|
||||
#define SPI_COMMAND_MODE 0
|
||||
#define SPI_DATA_MODE 1
|
||||
|
||||
#endif
|
9
components/display-st7789/CMakeLists.txt
Normal file
9
components/display-st7789/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"st7789.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
"display"
|
||||
"spi_flash"
|
||||
"pmu-axp192"
|
||||
)
|
281
components/display-st7789/st7789.c
Normal file
281
components/display-st7789/st7789.c
Normal file
@ -0,0 +1,281 @@
|
||||
// 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 <math.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <driver/spi_master.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
#include "axp192.h"
|
||||
|
||||
#include "st7789.h"
|
||||
|
||||
static spi_device_handle_t st7789_handle;
|
||||
|
||||
bool spi_master_write(uint8_t *data, size_t len, uint8_t dc)
|
||||
{
|
||||
spi_transaction_t spi_trans;
|
||||
|
||||
gpio_set_level(M5_ST7789_DC_GPIO, dc);
|
||||
|
||||
memset(&spi_trans, 0, sizeof(spi_transaction_t));
|
||||
spi_trans.length = len * 8;
|
||||
spi_trans.tx_buffer = data;
|
||||
spi_device_transmit(st7789_handle, &spi_trans);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_master_write_command(uint8_t cmd)
|
||||
{
|
||||
return spi_master_write(&cmd, 1, SPI_COMMAND_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data_byte(uint8_t data)
|
||||
{
|
||||
return spi_master_write(&data, 1, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_data(uint8_t *data, size_t len)
|
||||
{
|
||||
return spi_master_write(data, len, SPI_DATA_MODE);
|
||||
}
|
||||
|
||||
bool spi_master_write_addr(uint16_t addr1, uint16_t addr2)
|
||||
{
|
||||
uint8_t data[4];
|
||||
data[0] = (addr1 >> 8) & 0xFF;
|
||||
data[1] = addr1 & 0xFF;
|
||||
data[2] = (addr2 >> 8) & 0xFF;
|
||||
data[3] = addr2 & 0xFF;
|
||||
|
||||
return spi_master_write_data(data, 4);
|
||||
}
|
||||
|
||||
bool spi_master_write_color(uint16_t color, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
|
||||
uint8_t msbColor = (color >> 8) & 0xFF;
|
||||
uint8_t lsbColor = color & 0xFF;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = msbColor;
|
||||
data[index++] = lsbColor;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
bool spi_master_write_colors(uint16_t *colors, size_t size)
|
||||
{
|
||||
uint8_t data[size * 2];
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
data[index++] = (colors[i] >> 8) & 0xFF;
|
||||
data[index++] = colors[i] & 0xFF;
|
||||
}
|
||||
return spi_master_write_data(data, size * 2);
|
||||
}
|
||||
|
||||
void display_start(void)
|
||||
{
|
||||
|
||||
axp192_start();
|
||||
axp192_screen_breath(0);
|
||||
|
||||
esp_err_t ret;
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_CS_GPIO);
|
||||
gpio_set_direction(M5_ST7789_CS_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_CS_GPIO, 0);
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_DC_GPIO);
|
||||
gpio_set_direction(M5_ST7789_DC_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_DC_GPIO, 0);
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_RESET_GPIO);
|
||||
gpio_set_direction(M5_ST7789_RESET_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_RESET_GPIO, 1);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(M5_ST7789_RESET_GPIO, 0);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(M5_ST7789_RESET_GPIO, 1);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
|
||||
gpio_pad_select_gpio(M5_ST7789_BL_GPIO);
|
||||
gpio_set_direction(M5_ST7789_BL_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(M5_ST7789_BL_GPIO, 0);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = M5_ST7789_SCLK_GPIO,
|
||||
.mosi_io_num = M5_ST7789_MOSI_GPIO,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1};
|
||||
|
||||
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 1);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = SPI_MASTER_FREQ_20M,
|
||||
.queue_size = 7,
|
||||
.mode = 2,
|
||||
.flags = SPI_DEVICE_NO_DUMMY,
|
||||
};
|
||||
|
||||
devcfg.spics_io_num = M5_ST7789_CS_GPIO;
|
||||
|
||||
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &st7789_handle);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
spi_master_write_command(0x01); //Software Reset
|
||||
vTaskDelay(150 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x11); //Sleep Out
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x3A); //Interface Pixel Format
|
||||
spi_master_write_data_byte(0x55);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
// landscape RGB
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
spi_master_write_data_byte(M5_ST7789_LANDSCAPE);
|
||||
|
||||
spi_master_write_command(0x2A); //Column Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xF0);
|
||||
|
||||
spi_master_write_command(0x2B); //Row Address Set
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0x00);
|
||||
spi_master_write_data_byte(0xF0);
|
||||
|
||||
spi_master_write_command(0x21); //Display Inversion On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x13); //Normal Display Mode On
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
|
||||
spi_master_write_command(0x29); //Display ON
|
||||
vTaskDelay(255 / portTICK_PERIOD_MS);
|
||||
|
||||
gpio_set_level(M5_ST7789_BL_GPIO, 1);
|
||||
|
||||
axp192_screen_breath(10);
|
||||
}
|
||||
|
||||
void display_flipped(bool flipped)
|
||||
{
|
||||
spi_master_write_command(0x36); //Memory Data Access Control
|
||||
if (flipped)
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7789_LANDSCAPE_FLIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_master_write_data_byte(M5_ST7789_LANDSCAPE);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear_line(uint8_t line, bool invert)
|
||||
{
|
||||
uint16_t _x1 = 0 + M5_ST7789_OFFSETX;
|
||||
uint16_t _x2 = M5_ST7789_WIDTH + M5_ST7789_OFFSETX - 1;
|
||||
uint16_t _y1 = line * 8 + M5_ST7789_OFFSETY + M5_ST7789_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7789_OFFSETY - 1 + M5_ST7789_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(invert ? display_get_color() : BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_clear(void)
|
||||
{
|
||||
uint16_t _x1 = 0 + M5_ST7789_OFFSETX;
|
||||
uint16_t _x2 = M5_ST7789_WIDTH + M5_ST7789_OFFSETX - 1;
|
||||
uint16_t _y1 = 0 + M5_ST7789_OFFSETY;
|
||||
uint16_t _y2 = M5_ST7789_HEIGHT + M5_ST7789_OFFSETY - 1;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); // Memory Write
|
||||
for (int i = _x1; i <= _x2; i++)
|
||||
{
|
||||
uint16_t size = _y2 - _y1 + 1;
|
||||
spi_master_write_color(BLACK, size);
|
||||
}
|
||||
}
|
||||
|
||||
void display_on(bool on)
|
||||
{
|
||||
axp192_screen_breath(on ? 10 : 0);
|
||||
}
|
||||
|
||||
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
|
||||
{
|
||||
uint16_t _x1 = offset + M5_ST7789_OFFSETX + M5_ST7789_INTERFACE_OFFSETX;
|
||||
uint16_t _x2 = offset + length + M5_ST7789_OFFSETX - 1 + M5_ST7789_INTERFACE_OFFSETX;
|
||||
uint16_t _y1 = line * 8 + M5_ST7789_OFFSETY + M5_ST7789_INTERFACE_OFFSETY;
|
||||
uint16_t _y2 = line * 8 + 8 + M5_ST7789_OFFSETY - 1 + M5_ST7789_INTERFACE_OFFSETY;
|
||||
|
||||
spi_master_write_command(0x2A); // set column(x) address
|
||||
spi_master_write_addr(_x1, _x2);
|
||||
spi_master_write_command(0x2B); // set Page(y) address
|
||||
spi_master_write_addr(_y1, _y2);
|
||||
spi_master_write_command(0x2C); //Memory Write
|
||||
|
||||
uint8_t msbColor = (display_get_color() >> 8) & 0xFF;
|
||||
uint8_t lsbColor = display_get_color() & 0xFF;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t color[length * 2];
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
bool bit = (data[i] & (1 << j));
|
||||
if (invert)
|
||||
{
|
||||
bit = !bit;
|
||||
}
|
||||
color[index++] = bit ? msbColor : 0x00;
|
||||
color[index++] = bit ? lsbColor : 0x00;
|
||||
}
|
||||
spi_master_write_data(color, length * 2);
|
||||
}
|
||||
}
|
30
components/display-st7789/st7789.h
Normal file
30
components/display-st7789/st7789.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef DISPLAY_ST7789_H_
|
||||
#define DISPLAY_ST7789_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
// M5stickC PLUS
|
||||
#define M5_ST7789_WIDTH 240
|
||||
#define M5_ST7789_HEIGHT 135
|
||||
#define M5_ST7789_MOSI_GPIO 15
|
||||
#define M5_ST7789_SCLK_GPIO 13
|
||||
#define M5_ST7789_CS_GPIO 5
|
||||
#define M5_ST7789_DC_GPIO 23
|
||||
#define M5_ST7789_RESET_GPIO 18
|
||||
#define M5_ST7789_BL_GPIO 32
|
||||
#define M5_ST7789_OFFSETX 40
|
||||
#define M5_ST7789_OFFSETY 52
|
||||
|
||||
#define M5_ST7789_LANDSCAPE 0x60
|
||||
#define M5_ST7789_LANDSCAPE_FLIPPED 0xA0
|
||||
|
||||
#define M5_ST7789_INTERFACE_OFFSETX 56
|
||||
#define M5_ST7789_INTERFACE_OFFSETY 35
|
||||
|
||||
#define SPI_COMMAND_MODE 0
|
||||
#define SPI_DATA_MODE 1
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -16,6 +16,8 @@
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
static uint16_t current_color = WHITE;
|
||||
|
||||
uint8_t display_utf8_to_ascii_char(uint8_t ascii)
|
||||
{
|
||||
static uint8_t c1;
|
||||
@ -88,3 +90,128 @@ void display_chars(char *text, size_t length, uint8_t line, uint8_t offset, bool
|
||||
free(textdata);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void display_set_color(uint16_t color)
|
||||
{
|
||||
current_color = color;
|
||||
}
|
||||
|
||||
uint16_t display_get_color(void)
|
||||
{
|
||||
return current_color;
|
||||
}
|
@ -22,6 +22,18 @@
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
#define DISPLAY_COLUMNS 8
|
||||
|
||||
#define BLACK 0x0000
|
||||
#define WHITE 0xffff
|
||||
#define RED 0xf800
|
||||
#define GREEN 0x07e0
|
||||
#define BLUE 0x001f
|
||||
#define GRAY 0x8c51
|
||||
#define YELLOW 0xFFE0
|
||||
#define CYAN 0x07FF
|
||||
#define PURPLE 0xF81F
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -52,12 +64,19 @@ void display_clear_line( uint8_t line, bool invert);
|
||||
void display_clear(void);
|
||||
|
||||
/**
|
||||
* @brief set display on or offf
|
||||
* @brief set display on or off
|
||||
*
|
||||
* @param[in] on true if display on, false if display off
|
||||
*/
|
||||
void display_on(bool on);
|
||||
|
||||
/**
|
||||
* @brief set display flipped or not
|
||||
*
|
||||
* @param[in] on true display is flipped
|
||||
*/
|
||||
void display_flipped(bool flipped);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -122,4 +141,18 @@ void display_set_button(char *text, bool selected, bool primary);
|
||||
*/
|
||||
void display_menu_headline(char *text, bool arrows, uint8_t line);
|
||||
|
||||
/**
|
||||
* @brief set current color for colored displays
|
||||
*
|
||||
* @param[in] color the color to set
|
||||
*/
|
||||
void display_set_color(uint16_t color);
|
||||
|
||||
/**
|
||||
* @brief set current color for colored displays
|
||||
*
|
||||
* @return the current color
|
||||
*/
|
||||
uint16_t display_get_color(void);
|
||||
|
||||
#endif
|
@ -38,6 +38,23 @@ static time_t request_sleep = 0;
|
||||
static uint32_t request_sleep_waiting = 30;
|
||||
static time_t last_check = 0;
|
||||
static bool wait_for_request = false;
|
||||
static bool request_pause = false;
|
||||
|
||||
void ena_eke_proxy_pause(void)
|
||||
{
|
||||
while (wait_for_request || request_pause)
|
||||
{
|
||||
ESP_LOGD(ENA_EKE_PROXY_LOG, "waiting for other requests to finish...");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
request_pause = true;
|
||||
}
|
||||
|
||||
void ena_eke_proxy_resume(void)
|
||||
{
|
||||
request_pause = false;
|
||||
}
|
||||
|
||||
esp_err_t ena_eke_proxy_fetch_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
@ -256,7 +273,7 @@ void ena_eke_proxy_run(void)
|
||||
last_check = (time_t)ena_storage_read_last_exposure_date();
|
||||
check_diff = difftime(current_time, last_check);
|
||||
|
||||
if (check_diff > HOUR_IN_SECONDS && !wait_for_request && current_time > request_sleep)
|
||||
if (check_diff > HOUR_IN_SECONDS && !wait_for_request && !request_pause && current_time > request_sleep)
|
||||
{
|
||||
if (wifi_controller_connection() == NULL && current_time > wifi_reconnect && wifi_reconnect_waiting < 86400)
|
||||
{
|
||||
@ -323,6 +340,7 @@ esp_err_t ena_eke_proxy_fetch_upload_handler(esp_http_client_event_t *evt)
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
ena_eke_proxy_resume();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -333,6 +351,8 @@ esp_err_t ena_eke_proxy_fetch_upload_handler(esp_http_client_event_t *evt)
|
||||
esp_err_t ena_eke_proxy_upload(char *token, uint32_t days_since_onset_of_symptoms)
|
||||
{
|
||||
|
||||
ena_eke_proxy_pause();
|
||||
|
||||
ESP_LOGD(ENA_EKE_PROXY_LOG, "try to upload keys:");
|
||||
esp_http_client_config_t config = {
|
||||
.url = ENA_EKE_PROXY_KEYFILES_UPLOAD_URL,
|
||||
@ -391,6 +411,7 @@ esp_err_t ena_eke_proxy_upload(char *token, uint32_t days_since_onset_of_symptom
|
||||
else
|
||||
{
|
||||
ESP_LOGW(ENA_EKE_PROXY_LOG, "Keyupload failed!");
|
||||
ena_eke_proxy_resume();
|
||||
}
|
||||
|
||||
free(output_buffer);
|
||||
|
@ -85,4 +85,16 @@ void ena_eke_proxy_run(void);
|
||||
*/
|
||||
esp_err_t ena_eke_proxy_upload(char *token, uint32_t days_since_onset_of_symptoms);
|
||||
|
||||
/**
|
||||
* @brief pause requests
|
||||
*
|
||||
*/
|
||||
void ena_eke_proxy_pause(void);
|
||||
|
||||
/**
|
||||
* @brief resume requests
|
||||
*
|
||||
*/
|
||||
void ena_eke_proxy_resume(void);
|
||||
|
||||
#endif
|
@ -2,11 +2,11 @@ menu "I²C"
|
||||
|
||||
config I2C_SDA_PIN
|
||||
int "I²C sda pin"
|
||||
default 22
|
||||
default 21
|
||||
|
||||
config I2C_SCL_PIN
|
||||
int "I²C scl pin"
|
||||
default 23
|
||||
default 22
|
||||
|
||||
config I2C_CLOCKSPEED
|
||||
int "I²C clock speed"
|
||||
|
7
components/imu-mpu6886/CMakeLists.txt
Normal file
7
components/imu-mpu6886/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"mpu6886.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
i2c-main
|
||||
)
|
260
components/imu-mpu6886/mpu6886.c
Normal file
260
components/imu-mpu6886/mpu6886.c
Normal file
@ -0,0 +1,260 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "i2c-main.h"
|
||||
|
||||
#include "mpu6886.h"
|
||||
|
||||
int Gyscale = GFS_2000DPS;
|
||||
int Acscale = AFS_8G;
|
||||
float aRes, gRes;
|
||||
|
||||
void mpu6886_i2c_read_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *read_buffer)
|
||||
{
|
||||
i2c_cmd_handle_t cmd;
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, start_addr, true);
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_READ, true);
|
||||
i2c_master_read(cmd, read_buffer, number_Bytes, I2C_MASTER_LAST_NACK);
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void mpu6886_i2c_write_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *write_buffer)
|
||||
{
|
||||
i2c_cmd_handle_t cmd;
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, start_addr, true);
|
||||
i2c_master_write(cmd, write_buffer, number_Bytes, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mpu6886_getGres()
|
||||
{
|
||||
|
||||
switch (Gyscale)
|
||||
{
|
||||
// Possible gyro scales (and their register bit settings) are:
|
||||
case GFS_250DPS:
|
||||
gRes = 250.0 / 32768.0;
|
||||
break;
|
||||
case GFS_500DPS:
|
||||
gRes = 500.0 / 32768.0;
|
||||
break;
|
||||
case GFS_1000DPS:
|
||||
gRes = 1000.0 / 32768.0;
|
||||
break;
|
||||
case GFS_2000DPS:
|
||||
gRes = 2000.0 / 32768.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mpu6886_getAres()
|
||||
{
|
||||
switch (Acscale)
|
||||
{
|
||||
// Possible accelerometer scales (and their register bit settings) are:
|
||||
// 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11).
|
||||
// Here's a bit of an algorith to calculate DPS/(ADC tick) based on that 2-bit value:
|
||||
case AFS_2G:
|
||||
aRes = 2.0 / 32768.0;
|
||||
break;
|
||||
case AFS_4G:
|
||||
aRes = 4.0 / 32768.0;
|
||||
break;
|
||||
case AFS_8G:
|
||||
aRes = 8.0 / 32768.0;
|
||||
break;
|
||||
case AFS_16G:
|
||||
aRes = 16.0 / 32768.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int mpu6886_start(void)
|
||||
{
|
||||
unsigned char tempdata[1];
|
||||
unsigned char regdata;
|
||||
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
|
||||
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_WHOAMI, 1, tempdata);
|
||||
if (tempdata[0] != 0x19)
|
||||
return -1;
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x00;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, ®data);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = (0x01 << 7);
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, ®data);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = (0x01 << 0);
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_PWR_MGMT_1, 1, ®data);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x10;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x18;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_GYRO_CONFIG, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x01;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_CONFIG, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x05;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_SMPLRT_DIV, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x00;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_INT_ENABLE, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x00;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG2, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x00;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_USER_CTRL, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x00;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_FIFO_EN, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x22;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_INT_PIN_CFG, 1, ®data);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);;
|
||||
|
||||
regdata = 0x01;
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_INT_ENABLE, 1, ®data);
|
||||
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);;
|
||||
mpu6886_getGres();
|
||||
mpu6886_getAres();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mpu6886_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az)
|
||||
{
|
||||
|
||||
uint8_t buf[6];
|
||||
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_XOUT_H, 6, buf);
|
||||
|
||||
*ax = ((int16_t)buf[0] << 8) | buf[1];
|
||||
*ay = ((int16_t)buf[2] << 8) | buf[3];
|
||||
*az = ((int16_t)buf[4] << 8) | buf[5];
|
||||
}
|
||||
void mpu6886_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz)
|
||||
{
|
||||
|
||||
uint8_t buf[6];
|
||||
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_GYRO_XOUT_H, 6, buf);
|
||||
|
||||
*gx = ((uint16_t)buf[0] << 8) | buf[1];
|
||||
*gy = ((uint16_t)buf[2] << 8) | buf[3];
|
||||
*gz = ((uint16_t)buf[4] << 8) | buf[5];
|
||||
}
|
||||
|
||||
void mpu6886_get_temp_adc(int16_t *t)
|
||||
{
|
||||
|
||||
uint8_t buf[2];
|
||||
mpu6886_i2c_read_bytes(MPU6886_ADDRESS, MPU6886_TEMP_OUT_H, 2, buf);
|
||||
|
||||
*t = ((uint16_t)buf[0] << 8) | buf[1];
|
||||
}
|
||||
|
||||
void mpu6886_set_gyro_fsr(int scale)
|
||||
{
|
||||
//return IIC_Write_Byte(MPU_GYRO_CFG_REG,scale<<3);//设置陀螺仪满量程范围
|
||||
unsigned char regdata;
|
||||
regdata = (scale << 3);
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_GYRO_CONFIG, 1, ®data);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);;
|
||||
|
||||
Gyscale = scale;
|
||||
mpu6886_getGres();
|
||||
}
|
||||
|
||||
void mpu6886_set_accel_fsr(int scale)
|
||||
{
|
||||
unsigned char regdata;
|
||||
regdata = (scale << 3);
|
||||
mpu6886_i2c_write_bytes(MPU6886_ADDRESS, MPU6886_ACCEL_CONFIG, 1, ®data);
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);;
|
||||
|
||||
Acscale = scale;
|
||||
mpu6886_getAres();
|
||||
}
|
||||
|
||||
void mpu6886_get_accel_data(float *ax, float *ay, float *az)
|
||||
{
|
||||
|
||||
int16_t accX = 0;
|
||||
int16_t accY = 0;
|
||||
int16_t accZ = 0;
|
||||
mpu6886_get_accel_adc(&accX, &accY, &accZ);
|
||||
|
||||
*ax = (float)accX * aRes;
|
||||
*ay = (float)accY * aRes;
|
||||
*az = (float)accZ * aRes;
|
||||
}
|
||||
|
||||
void mpu6886_get_gyro_data(float *gx, float *gy, float *gz)
|
||||
{
|
||||
int16_t gyroX = 0;
|
||||
int16_t gyroY = 0;
|
||||
int16_t gyroZ = 0;
|
||||
mpu6886_get_gyro_adc(&gyroX, &gyroY, &gyroZ);
|
||||
|
||||
*gx = (float)gyroX * gRes;
|
||||
*gy = (float)gyroY * gRes;
|
||||
*gz = (float)gyroZ * gRes;
|
||||
}
|
||||
|
||||
void mpu6886_get_temp_data(float *t)
|
||||
{
|
||||
|
||||
int16_t temp = 0;
|
||||
mpu6886_get_temp_adc(&temp);
|
||||
|
||||
*t = (float)temp / 326.8 + 25.0;
|
||||
}
|
78
components/imu-mpu6886/mpu6886.h
Normal file
78
components/imu-mpu6886/mpu6886.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Note: The MPU6886 is an I2C sensor and uses the Arduino Wire library.
|
||||
Because the sensor is not 5V tolerant, we are using a 3.3 V 8 MHz Pro Mini or
|
||||
a 3.3 V Teensy 3.1. We have disabled the internal pull-ups used by the Wire
|
||||
library in the Wire.h/twi.c utility file. We are also using the 400 kHz fast
|
||||
I2C mode by setting the TWI_FREQ to 400000L /twi.h utility file.
|
||||
*/
|
||||
#ifndef _IMU_MPU6886_H_
|
||||
#define _IMU_MPU6886_H_
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#define MPU6886_ADDRESS 0x68
|
||||
#define MPU6886_WHOAMI 0x75
|
||||
#define MPU6886_ACCEL_INTEL_CTRL 0x69
|
||||
#define MPU6886_SMPLRT_DIV 0x19
|
||||
#define MPU6886_INT_PIN_CFG 0x37
|
||||
#define MPU6886_INT_ENABLE 0x38
|
||||
#define MPU6886_ACCEL_XOUT_H 0x3B
|
||||
#define MPU6886_ACCEL_XOUT_L 0x3C
|
||||
#define MPU6886_ACCEL_YOUT_H 0x3D
|
||||
#define MPU6886_ACCEL_YOUT_L 0x3E
|
||||
#define MPU6886_ACCEL_ZOUT_H 0x3F
|
||||
#define MPU6886_ACCEL_ZOUT_L 0x40
|
||||
|
||||
#define MPU6886_TEMP_OUT_H 0x41
|
||||
#define MPU6886_TEMP_OUT_L 0x42
|
||||
|
||||
#define MPU6886_GYRO_XOUT_H 0x43
|
||||
#define MPU6886_GYRO_XOUT_L 0x44
|
||||
#define MPU6886_GYRO_YOUT_H 0x45
|
||||
#define MPU6886_GYRO_YOUT_L 0x46
|
||||
#define MPU6886_GYRO_ZOUT_H 0x47
|
||||
#define MPU6886_GYRO_ZOUT_L 0x48
|
||||
|
||||
#define MPU6886_USER_CTRL 0x6A
|
||||
#define MPU6886_PWR_MGMT_1 0x6B
|
||||
#define MPU6886_PWR_MGMT_2 0x6C
|
||||
#define MPU6886_CONFIG 0x1A
|
||||
#define MPU6886_GYRO_CONFIG 0x1B
|
||||
#define MPU6886_ACCEL_CONFIG 0x1C
|
||||
#define MPU6886_ACCEL_CONFIG2 0x1D
|
||||
#define MPU6886_FIFO_EN 0x23
|
||||
|
||||
//#define G (9.8)
|
||||
#define RtA 57.324841
|
||||
#define AtR 0.0174533
|
||||
#define Gyro_Gr 0.0010653
|
||||
|
||||
enum Ascale
|
||||
{
|
||||
AFS_2G = 0,
|
||||
AFS_4G,
|
||||
AFS_8G,
|
||||
AFS_16G
|
||||
} ;
|
||||
|
||||
enum Gscale
|
||||
{
|
||||
GFS_250DPS = 0,
|
||||
GFS_500DPS,
|
||||
GFS_1000DPS,
|
||||
GFS_2000DPS
|
||||
};
|
||||
|
||||
int mpu6886_start(void);
|
||||
void mpu6886_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az);
|
||||
void mpu6886_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz);
|
||||
void mpu6886_get_temp_adc(int16_t *t);
|
||||
|
||||
void mpu6886_get_accel_data(float *ax, float *ay, float *az);
|
||||
void mpu6886_get_gyro_data(float *gx, float *gy, float *gz);
|
||||
void mpu6886_get_temp_data(float *t);
|
||||
|
||||
void mpu6886_set_gyro_fsr(int scale);
|
||||
void mpu6886_set_accel_fsr(int scale);
|
||||
|
||||
#endif
|
@ -21,39 +21,64 @@
|
||||
|
||||
#include "button-input.h"
|
||||
|
||||
static int old_button_states[INTERFACE_COMMANDS_SIZE];
|
||||
static int button_states[INTERFACE_COMMANDS_SIZE];
|
||||
static float 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]);
|
||||
int button_level = gpio_get_level(button_command_mapping[command]);
|
||||
|
||||
if (old_button_states[command] != 0 && old_button_states[command] != 1)
|
||||
if (button_level == 0)
|
||||
{
|
||||
old_button_states[command] = 1;
|
||||
}
|
||||
button_states[command] = button_states[command] + ((float)INTERFACE_INPUT_TICKS_MS / 1000);
|
||||
|
||||
if (button_states[command] == 0 && button_states[command] != old_button_states[command])
|
||||
if (command == INTERFACE_COMMAND_SET && button_states[command] > INTERFACE_LONG_STATE_SECONDS)
|
||||
{
|
||||
button_states[command] = 0;
|
||||
button_states[INTERFACE_COMMAND_SET_LONG] = button_states[INTERFACE_COMMAND_SET_LONG] + 1;
|
||||
interface_execute_command(INTERFACE_COMMAND_SET_LONG);
|
||||
}
|
||||
else if (command == INTERFACE_COMMAND_RST && button_states[command] > INTERFACE_LONG_STATE_SECONDS)
|
||||
{
|
||||
button_states[command] = 0;
|
||||
button_states[INTERFACE_COMMAND_RST_LONG] = button_states[INTERFACE_COMMAND_RST_LONG] + 1;
|
||||
interface_execute_command(INTERFACE_COMMAND_RST_LONG);
|
||||
}
|
||||
}
|
||||
else if (button_level == 1 && button_states[command] > 0)
|
||||
{
|
||||
button_states[command] = 0;
|
||||
|
||||
if (command == INTERFACE_COMMAND_SET && button_states[INTERFACE_COMMAND_SET_LONG] > 0)
|
||||
{
|
||||
button_states[INTERFACE_COMMAND_SET_LONG] = 0;
|
||||
}
|
||||
else if (command == INTERFACE_COMMAND_RST && button_states[INTERFACE_COMMAND_RST_LONG] > 0)
|
||||
{
|
||||
button_states[INTERFACE_COMMAND_RST_LONG] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
if (!interface_is_idle())
|
||||
{
|
||||
button_input_check(INTERFACE_COMMAND_RST);
|
||||
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);
|
||||
}
|
||||
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
8
components/interface-input-m5/CMakeLists.txt
Normal file
8
components/interface-input-m5/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"m5-input.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
interface
|
||||
imu-mpu6886
|
||||
)
|
205
components/interface-input-m5/m5-input.c
Normal file
205
components/interface-input-m5/m5-input.c
Normal file
@ -0,0 +1,205 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mpu6886.h"
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
#include "m5-input.h"
|
||||
|
||||
static float old_input_states[INTERFACE_COMMANDS_SIZE];
|
||||
static float input_states[INTERFACE_COMMANDS_SIZE];
|
||||
static int input_command_mapping[INTERFACE_COMMANDS_SIZE];
|
||||
static bool flipped = false;
|
||||
|
||||
void button_input_check(interface_command_t command)
|
||||
{
|
||||
int button_level = gpio_get_level(input_command_mapping[command]);
|
||||
|
||||
if (button_level == 0)
|
||||
{
|
||||
input_states[command] = input_states[command] + ((float)INTERFACE_INPUT_TICKS_MS / 1000);
|
||||
if (command == INTERFACE_COMMAND_SET && input_states[command] > INTERFACE_LONG_STATE_SECONDS)
|
||||
{
|
||||
input_states[command] = 0;
|
||||
input_states[INTERFACE_COMMAND_SET_LONG] = input_states[INTERFACE_COMMAND_SET_LONG] + 1;
|
||||
interface_execute_command(INTERFACE_COMMAND_SET_LONG);
|
||||
}
|
||||
else if (command == INTERFACE_COMMAND_RST && input_states[command] > INTERFACE_LONG_STATE_SECONDS)
|
||||
{
|
||||
input_states[command] = 0;
|
||||
input_states[INTERFACE_COMMAND_RST_LONG] = input_states[INTERFACE_COMMAND_RST_LONG] + 1;
|
||||
interface_execute_command(INTERFACE_COMMAND_RST_LONG);
|
||||
}
|
||||
}
|
||||
else if (button_level == 1 && input_states[command] > 0)
|
||||
{
|
||||
input_states[command] = 0;
|
||||
if (command == INTERFACE_COMMAND_SET && input_states[INTERFACE_COMMAND_SET_LONG] > 0)
|
||||
{
|
||||
input_states[INTERFACE_COMMAND_SET_LONG] = 0;
|
||||
}
|
||||
else if (command == INTERFACE_COMMAND_RST && input_states[INTERFACE_COMMAND_RST_LONG] > 0)
|
||||
{
|
||||
input_states[INTERFACE_COMMAND_RST_LONG] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!interface_is_idle() && flipped)
|
||||
{
|
||||
if (command == INTERFACE_COMMAND_SET)
|
||||
{
|
||||
command = INTERFACE_COMMAND_RST;
|
||||
}
|
||||
else if (command == INTERFACE_COMMAND_RST)
|
||||
{
|
||||
command = INTERFACE_COMMAND_SET;
|
||||
}
|
||||
}
|
||||
interface_execute_command(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void accel_input_up(float axis)
|
||||
{
|
||||
|
||||
input_states[INTERFACE_COMMAND_UP] = axis;
|
||||
if (axis < -0.3 && old_input_states[INTERFACE_COMMAND_UP] > -0.3 && old_input_states[INTERFACE_COMMAND_UP] + axis < -0.5)
|
||||
{
|
||||
interface_execute_command(INTERFACE_COMMAND_UP);
|
||||
old_input_states[INTERFACE_COMMAND_UP] = axis;
|
||||
}
|
||||
else if (axis > -0.3)
|
||||
{
|
||||
old_input_states[INTERFACE_COMMAND_UP] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void accel_input_left(float axis)
|
||||
{
|
||||
|
||||
input_states[INTERFACE_COMMAND_LFT] = axis;
|
||||
if (axis < -0.3 && old_input_states[INTERFACE_COMMAND_LFT] > -0.3 && old_input_states[INTERFACE_COMMAND_LFT] + axis < -0.5)
|
||||
{
|
||||
interface_execute_command(INTERFACE_COMMAND_LFT);
|
||||
old_input_states[INTERFACE_COMMAND_LFT] = axis;
|
||||
}
|
||||
else if (axis > -0.3)
|
||||
{
|
||||
old_input_states[INTERFACE_COMMAND_LFT] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void accel_input_right(float axis)
|
||||
{
|
||||
input_states[INTERFACE_COMMAND_RHT] = axis;
|
||||
if (axis > 0.3 && old_input_states[INTERFACE_COMMAND_RHT] < 0.3 && old_input_states[INTERFACE_COMMAND_RHT] + axis > 0.5)
|
||||
{
|
||||
interface_execute_command(INTERFACE_COMMAND_RHT);
|
||||
old_input_states[INTERFACE_COMMAND_RHT] = axis;
|
||||
}
|
||||
else if (axis < 0.3)
|
||||
{
|
||||
old_input_states[INTERFACE_COMMAND_RHT] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void accel_input_down(float axis)
|
||||
{
|
||||
input_states[INTERFACE_COMMAND_DWN] = axis;
|
||||
if (axis > 0.3 && old_input_states[INTERFACE_COMMAND_DWN] < 0.3 && old_input_states[INTERFACE_COMMAND_DWN] + axis > 0.5)
|
||||
{
|
||||
interface_execute_command(INTERFACE_COMMAND_DWN);
|
||||
old_input_states[INTERFACE_COMMAND_DWN] = axis;
|
||||
}
|
||||
else if (axis < 0.3)
|
||||
{
|
||||
old_input_states[INTERFACE_COMMAND_DWN] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gyro_input(float axis)
|
||||
{
|
||||
input_states[INTERFACE_COMMAND_MID] = axis;
|
||||
if (axis < -50 && old_input_states[INTERFACE_COMMAND_MID] > 50)
|
||||
{
|
||||
// interface_execute_command(INTERFACE_COMMAND_MID);
|
||||
old_input_states[INTERFACE_COMMAND_MID] = axis;
|
||||
ESP_LOGI(INTERFACE_LOG, "gyro: %f", axis);
|
||||
}
|
||||
else if (axis > 50)
|
||||
{
|
||||
old_input_states[INTERFACE_COMMAND_MID] = axis;
|
||||
}
|
||||
}
|
||||
|
||||
void m5_input_task(void *pvParameter)
|
||||
{
|
||||
float ax = 0;
|
||||
float ay = 0;
|
||||
float az = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
button_input_check(INTERFACE_COMMAND_SET);
|
||||
|
||||
if (!interface_is_idle())
|
||||
{
|
||||
button_input_check(INTERFACE_COMMAND_RST);
|
||||
mpu6886_get_accel_data(&ax, &ay, &az);
|
||||
accel_input_up(flipped ? -ax : ax);
|
||||
accel_input_left(flipped ? -ay : ay);
|
||||
accel_input_right(flipped ? -ay : ay);
|
||||
accel_input_down(flipped ? -ax : ax);
|
||||
|
||||
if (ax >= 1)
|
||||
{
|
||||
flipped = false;
|
||||
interface_flipped(flipped);
|
||||
}
|
||||
else if (ax <= -1)
|
||||
{
|
||||
flipped = true;
|
||||
interface_flipped(flipped);
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void m5_input_start(void)
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
|
||||
io_conf.pin_bit_mask = (1ULL << BUTTON_RST) | (1ULL << BUTTON_SET);
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
input_command_mapping[INTERFACE_COMMAND_RST] = BUTTON_RST;
|
||||
input_command_mapping[INTERFACE_COMMAND_SET] = BUTTON_SET;
|
||||
|
||||
mpu6886_start();
|
||||
|
||||
xTaskCreate(&m5_input_task, "m5_input_task", 4096, NULL, 5, NULL);
|
||||
}
|
33
components/interface-input-m5/m5-input.h
Normal file
33
components/interface-input-m5/m5-input.h
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief execute interface commands via simple push buttons
|
||||
*
|
||||
*/
|
||||
#ifndef _m5_input_H_
|
||||
#define _m5_input_H_
|
||||
|
||||
#define BUTTON_RST GPIO_NUM_37
|
||||
#define BUTTON_SET GPIO_NUM_39
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*
|
||||
*/
|
||||
void m5_input_start(void);
|
||||
|
||||
#endif
|
@ -1,9 +1,24 @@
|
||||
set(priv_requires "ena" "ena-eke-proxy" "display" "rtc" "wifi-controller" )
|
||||
|
||||
if(CONFIG_ENA_INTERFACE_CUSTOM)
|
||||
list(APPEND priv_requires "display-ssd1306" "rtc-ds3231")
|
||||
elseif(ENA_INTERFACE_M5STICKC)
|
||||
list(APPEND priv_requires "display-st7735s" "rtc-bm8563" "imu-mpu6886" "pmu-axp192")
|
||||
elseif(ENA_INTERFACE_M5STICKC_PLUS)
|
||||
list(APPEND priv_requires "display-st7789" "rtc-bm8563" "imu-mpu6886" "pmu-axp192")
|
||||
else()
|
||||
list(APPEND priv_requires "display-ssd1306" "rtc-ds3231") # uncomment for custom device with SSD1306 und DS3231
|
||||
# list(APPEND priv_requires "display-st7735s" "rtc-bm8563" "imu-mpu6886" "pmu-axp192") # uncomment for M5StickC
|
||||
# list(APPEND priv_requires "display-st7789" "rtc-bm8563" "imu-mpu6886" "pmu-axp192") # uncomment for M5StickC PLUS
|
||||
endif()
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"interface.c"
|
||||
"interface-main.c"
|
||||
"interface-data.c"
|
||||
"interface-datetime.c"
|
||||
"interface-debug.c"
|
||||
"interface-info.c"
|
||||
"interface-input.c"
|
||||
"interface-label.c"
|
||||
@ -11,12 +26,5 @@ idf_component_register(
|
||||
"interface-settings.c"
|
||||
"interface-wifi.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
ena
|
||||
ena-eke-proxy
|
||||
display
|
||||
display-ssd1306
|
||||
rtc
|
||||
rtc-ds3231
|
||||
wifi-controller
|
||||
PRIV_REQUIRES ${priv_requires}
|
||||
)
|
26
components/interface/Kconfig.projbuild
Normal file
26
components/interface/Kconfig.projbuild
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
menu "ENA Interface"
|
||||
|
||||
config ENA_INTERFACE_IDLE_TIME
|
||||
int "Seconds after display turns off on inactivity"
|
||||
default 15
|
||||
|
||||
config ENA_INTERFACE_DEBUG
|
||||
bool "Adds a debug interface for additional information for device"
|
||||
default false
|
||||
|
||||
choice ENA_INTERFACE_DEVICE
|
||||
prompt "Choose device"
|
||||
default ENA_INTERFACE_CUSTOM
|
||||
|
||||
config ENA_INTERFACE_CUSTOM
|
||||
bool "Custom"
|
||||
|
||||
config ENA_INTERFACE_M5STICKC
|
||||
bool "M5StickC"
|
||||
|
||||
config ENA_INTERFACE_M5STICKC_PLUS
|
||||
bool "M5StickC PLUS"
|
||||
endchoice
|
||||
|
||||
endmenu
|
@ -50,8 +50,11 @@ void interface_data_set(void)
|
||||
{
|
||||
confirm_current = false;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,9 +86,19 @@ void interface_data_rst(void)
|
||||
}
|
||||
|
||||
confirm_current = false;
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_clear_line(2, false);
|
||||
display_clear_line(4, false);
|
||||
display_clear_line(6, false);
|
||||
confirm_current = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +109,11 @@ void interface_data_lft(void)
|
||||
|
||||
void interface_data_rht(void)
|
||||
{
|
||||
#if defined(CONFIG_ENA_INTERFACE_DEBUG)
|
||||
interface_debug_start();
|
||||
#else
|
||||
interface_info_start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void interface_data_mid(void)
|
||||
@ -150,6 +167,7 @@ void interface_data_dwn(void)
|
||||
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);
|
||||
@ -160,8 +178,9 @@ void interface_data_display(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
display_clear_line( 5, false);
|
||||
display_clear_line( 7, false);
|
||||
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 + current_data_index;
|
||||
@ -171,6 +190,10 @@ void interface_data_display(void)
|
||||
{
|
||||
display_data(display_gfx_arrow_right, 8, i * 2 + 2, 8, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, i * 2 + 2, 8, false);
|
||||
}
|
||||
|
||||
display_text_line_column(interface_get_label_text(&interface_text_data_del[index]), i * 2 + 2, 2, false);
|
||||
}
|
||||
@ -189,8 +212,6 @@ void interface_data_start(void)
|
||||
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);
|
||||
interface_set_display_refresh_function(NULL);
|
||||
|
||||
ESP_LOGD(INTERFACE_LOG, "start delete data interface");
|
||||
interface_set_display_function(&interface_data_display);
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ void interface_datetime_mid(void)
|
||||
{
|
||||
current_interface_datetime_state = INTERFACE_DATETIME_STATE_HOUR;
|
||||
}
|
||||
ESP_LOGD(INTERFACE_LOG, "datetime to %d", current_interface_datetime_state);
|
||||
}
|
||||
|
||||
void interface_datetime_up(void)
|
||||
@ -75,7 +74,6 @@ void interface_datetime_up(void)
|
||||
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)
|
||||
@ -86,17 +84,20 @@ void interface_datetime_dwn(void)
|
||||
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)
|
||||
{
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_time), true, 0);
|
||||
}
|
||||
|
||||
void interface_datetime_display_refresh(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;
|
||||
@ -157,6 +158,8 @@ void interface_datetime_display(void)
|
||||
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);
|
||||
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_time), true, 0);
|
||||
}
|
||||
|
||||
void interface_datetime_start(void)
|
||||
@ -164,12 +167,12 @@ 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_RST, &interface_datetime_mid);
|
||||
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(NULL);
|
||||
interface_set_display_refresh_function(&interface_datetime_display);
|
||||
ESP_LOGD(INTERFACE_LOG, "start datetime interface");
|
||||
|
||||
interface_set_display_function(&interface_datetime_display);
|
||||
interface_set_display_refresh_function(&interface_datetime_display_refresh);
|
||||
}
|
148
components/interface/interface-debug.c
Normal file
148
components/interface/interface-debug.c
Normal file
@ -0,0 +1,148 @@
|
||||
// Copyright 2020 Lukas Haubaum
|
||||
//
|
||||
// Licensed under the GNU Affero General Public License, Version 3;
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// https://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
|
||||
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
|
||||
#include "mpu6886.h"
|
||||
#include "axp192.h"
|
||||
#endif
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
static bool runTask = true;
|
||||
static TaskHandle_t debugTaskHandle = NULL;
|
||||
|
||||
void interface_debug_set(void)
|
||||
{
|
||||
runTask = false;
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
vTaskSuspend(debugTaskHandle);
|
||||
interface_main_start();
|
||||
}
|
||||
|
||||
void interface_debug_rst(void)
|
||||
{
|
||||
}
|
||||
|
||||
void interface_debug_lft(void)
|
||||
{
|
||||
runTask = false;
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
vTaskSuspend(debugTaskHandle);
|
||||
interface_data_start();
|
||||
}
|
||||
|
||||
void interface_debug_rht(void)
|
||||
{
|
||||
runTask = false;
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
vTaskSuspend(debugTaskHandle);
|
||||
interface_info_start();
|
||||
}
|
||||
|
||||
void interface_debug_mid(void)
|
||||
{
|
||||
}
|
||||
|
||||
void interface_debug_up(void)
|
||||
{
|
||||
}
|
||||
|
||||
void interface_debug_dwn(void)
|
||||
{
|
||||
}
|
||||
|
||||
void interface_debug_task(void *pvParameter)
|
||||
{
|
||||
|
||||
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
|
||||
float ax = 0;
|
||||
float ay = 0;
|
||||
float az = 0;
|
||||
|
||||
float gx = 0;
|
||||
float gy = 0;
|
||||
float gz = 0;
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
if (!interface_is_idle() && runTask)
|
||||
{
|
||||
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
|
||||
mpu6886_get_accel_data(&ax, &ay, &az);
|
||||
mpu6886_get_gyro_data(&gx, &gy, &gz);
|
||||
|
||||
char data_chars[32];
|
||||
sprintf(data_chars, "acc x:%3.2f", ax);
|
||||
display_text_line(data_chars, 2, false);
|
||||
sprintf(data_chars, "acc y:%3.2f", ay);
|
||||
display_text_line(data_chars, 3, false);
|
||||
sprintf(data_chars, "acc z:%3.2f", az);
|
||||
display_text_line(data_chars, 4, false);
|
||||
sprintf(data_chars, "gyr x:%3.2f", gx);
|
||||
display_text_line(data_chars, 5, false);
|
||||
sprintf(data_chars, "gyr y:%3.2f", gy);
|
||||
display_text_line(data_chars, 6, false);
|
||||
sprintf(data_chars, "gyr z:%3.2f", gz);
|
||||
display_text_line(data_chars, 7, false);
|
||||
|
||||
float bat_v = axp192_get_bat_voltage();
|
||||
|
||||
sprintf(data_chars, "Battery: %.2f V", bat_v);
|
||||
display_text_line(data_chars, 7, false);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void interface_debug_start(void)
|
||||
{
|
||||
|
||||
interface_register_command_callback(INTERFACE_COMMAND_RST, &interface_debug_rst);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_debug_set);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_debug_lft);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_RHT, &interface_debug_rht);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_debug_mid);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_debug_up);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_debug_dwn);
|
||||
|
||||
interface_set_display_function(NULL);
|
||||
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_debug), true, 0);
|
||||
|
||||
if (debugTaskHandle == NULL)
|
||||
{
|
||||
xTaskCreate(&interface_debug_task, "interface_debug_task", 4096 * 2, NULL, 5, &debugTaskHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
vTaskResume(debugTaskHandle);
|
||||
}
|
||||
|
||||
runTask = true;
|
||||
}
|
@ -38,7 +38,11 @@ void interface_info_rst(void)
|
||||
|
||||
void interface_info_lft(void)
|
||||
{
|
||||
#if defined(CONFIG_ENA_INTERFACE_DEBUG)
|
||||
interface_debug_start();
|
||||
#else
|
||||
interface_data_start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void interface_info_rht(void)
|
||||
@ -58,40 +62,69 @@ void interface_info_dwn(void)
|
||||
{
|
||||
}
|
||||
|
||||
int interface_info_num_offset(int num)
|
||||
{
|
||||
if (num < 10)
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
else if (num < 100)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
}
|
||||
|
||||
void interface_info_display(void)
|
||||
{
|
||||
char data_chars[10];
|
||||
ena_exposure_summary_t *current_exposure_summary = ena_exposure_current_summary();
|
||||
|
||||
char data_chars[16];
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_info), true, 0);
|
||||
|
||||
display_text_line_column(interface_get_label_text(&interface_text_info_num_keys), 2, 1, false);
|
||||
|
||||
sprintf(data_chars, "%u", ena_storage_beacons_count());
|
||||
display_text_line_column(data_chars, 2, 9, false);
|
||||
int num = ena_storage_beacons_count();
|
||||
sprintf(data_chars, "%u", num);
|
||||
display_text_line_column(data_chars, 2, interface_info_num_offset(num), false);
|
||||
|
||||
ena_exposure_summary_t *current_exposure_summary = ena_exposure_current_summary();
|
||||
display_text_line_column(interface_get_label_text(&interface_text_info_last_keys), 3, 1, false);
|
||||
|
||||
time_t current_timstamp;
|
||||
time(¤t_timstamp);
|
||||
|
||||
int max = ena_expore_check_find_min((uint32_t)current_timstamp);
|
||||
int min = ena_expore_check_find_min((uint32_t)current_timstamp - 60 * 30);
|
||||
int last30 = max - min;
|
||||
|
||||
if (last30 > 0)
|
||||
{
|
||||
sprintf(data_chars, "%d", last30);
|
||||
display_text_line_column(data_chars, 3, interface_info_num_offset(last30), false);
|
||||
}
|
||||
|
||||
display_text_line_column(interface_get_label_text(&interface_text_info_exp_days), 4, 1, false);
|
||||
sprintf(data_chars, "%d", current_exposure_summary->days_since_last_exposure);
|
||||
if (current_exposure_summary->days_since_last_exposure < 0)
|
||||
int last = current_exposure_summary->days_since_last_exposure;
|
||||
if (last >= 0)
|
||||
{
|
||||
display_text_line_column("/", 4, 12, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_text_line_column(data_chars, 4, 12, false);
|
||||
sprintf(data_chars, "%d", last);
|
||||
display_text_line_column(data_chars, 4, interface_info_num_offset(last), false);
|
||||
}
|
||||
|
||||
display_text_line_column(interface_get_label_text(&interface_text_info_exp_num), 5, 1, false);
|
||||
sprintf(data_chars, "%d", current_exposure_summary->num_exposures);
|
||||
display_text_line_column(data_chars, 5, 12, false);
|
||||
display_text_line_column(data_chars, 5, interface_info_num_offset(current_exposure_summary->num_exposures), false);
|
||||
|
||||
display_text_line_column(interface_get_label_text(&interface_text_info_exp_max), 6, 1, false);
|
||||
sprintf(data_chars, "%d", current_exposure_summary->max_risk_score);
|
||||
display_text_line_column(data_chars, 6, 12, false);
|
||||
display_text_line_column(data_chars, 6, interface_info_num_offset(current_exposure_summary->max_risk_score), false);
|
||||
|
||||
display_text_line_column(interface_get_label_text(&interface_text_info_exp_sum), 7, 1, false);
|
||||
sprintf(data_chars, "%d", current_exposure_summary->risk_score_sum);
|
||||
display_text_line_column(data_chars, 7, 12, false);
|
||||
display_text_line_column(data_chars, 7, interface_info_num_offset(current_exposure_summary->risk_score_sum), false);
|
||||
}
|
||||
|
||||
void interface_info_start(void)
|
||||
@ -104,8 +137,6 @@ void interface_info_start(void)
|
||||
interface_register_command_callback(INTERFACE_COMMAND_MID, &interface_info_mid);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_UP, &interface_info_up);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_DWN, &interface_info_dwn);
|
||||
interface_set_display_function(&interface_info_display);
|
||||
interface_set_display_refresh_function(NULL);
|
||||
|
||||
ESP_LOGD(INTERFACE_LOG, "start info interface");
|
||||
interface_set_display_function(&interface_info_display);
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ void interface_input_set_char_set(void)
|
||||
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)
|
||||
@ -152,7 +151,6 @@ void interface_input_mid(void)
|
||||
}
|
||||
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)
|
||||
@ -198,26 +196,9 @@ void interface_input_display(void)
|
||||
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)
|
||||
@ -264,6 +245,23 @@ void interface_input_display(void)
|
||||
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);
|
||||
|
||||
if (current_cursor > 0)
|
||||
{
|
||||
display_data(display_gfx_arrow_left, 8, 2, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, 2, 0, false);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void interface_input_set_text(char *text)
|
||||
@ -313,8 +311,7 @@ void interface_input(interface_text_callback callback_rst, interface_text_callba
|
||||
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_register_command_callback(INTERFACE_COMMAND_RST_LONG, &interface_input_mid);
|
||||
|
||||
interface_set_display_function(&interface_input_display);
|
||||
interface_set_display_refresh_function(NULL);
|
||||
ESP_LOGD(INTERFACE_LOG, "start input interface");
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ void interface_init_label(void)
|
||||
interface_text_settings_timezone.text[EN] = "UTC:";
|
||||
|
||||
interface_text_info_num_keys.text[EN] = "Seen:";
|
||||
interface_text_info_last_keys.text[EN] = "<=30m:";
|
||||
interface_text_info_exp_days.text[EN] = "Last Exp:";
|
||||
interface_text_info_exp_num.text[EN] = "Num Exp:";
|
||||
interface_text_info_exp_max.text[EN] = "Score:";
|
||||
@ -111,6 +112,7 @@ void interface_init_label(void)
|
||||
interface_text_settings_timezone.text[DE] = "GMT:";
|
||||
|
||||
interface_text_info_num_keys.text[DE] = "Gesehen:";
|
||||
interface_text_info_last_keys.text[DE] = "<=30m:";
|
||||
interface_text_info_exp_days.text[DE] = "letz. Exp:";
|
||||
interface_text_info_exp_num.text[DE] = "Anz. Exp:";
|
||||
interface_text_info_exp_max.text[DE] = "Score:";
|
||||
|
@ -51,6 +51,7 @@ void interface_main_display(void)
|
||||
// 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_set_color(YELLOW);
|
||||
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);
|
||||
@ -58,18 +59,23 @@ void interface_main_display(void)
|
||||
}
|
||||
else if (current_exposure_summary->max_risk_score < 100)
|
||||
{
|
||||
display_set_color(GREEN);
|
||||
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);
|
||||
display_set_color(WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_set_color(RED);
|
||||
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);
|
||||
display_set_color(WHITE);
|
||||
}
|
||||
|
||||
// clock icon
|
||||
display_data(display_gfx_clock, 8, 4, 8, false);
|
||||
|
||||
@ -78,9 +84,9 @@ void interface_main_display(void)
|
||||
|
||||
last_update_tm->tm_hour = last_update_tm->tm_hour + (interface_get_timezone_offset()) % 24;
|
||||
|
||||
sprintf(time_buffer, "%02d %s %02d:%02d",
|
||||
last_update_tm->tm_mday,
|
||||
sprintf(time_buffer, "%s %02d %02d:%02d",
|
||||
interface_get_label_text(&interface_texts_month[last_update_tm->tm_mon]),
|
||||
last_update_tm->tm_mday,
|
||||
last_update_tm->tm_hour,
|
||||
last_update_tm->tm_min);
|
||||
|
||||
@ -89,6 +95,8 @@ void interface_main_display(void)
|
||||
display_text_line_column(time_buffer, 4, 3, false);
|
||||
}
|
||||
|
||||
display_set_color(WHITE);
|
||||
|
||||
// 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);
|
||||
@ -124,7 +132,6 @@ void interface_main_display_refresh(void)
|
||||
|
||||
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);
|
||||
@ -135,7 +142,4 @@ void interface_main_start(void)
|
||||
|
||||
interface_set_display_function(&interface_main_display);
|
||||
interface_set_display_refresh_function(&interface_main_display_refresh);
|
||||
|
||||
interface_main_display();
|
||||
ESP_LOGD(INTERFACE_LOG, "start main interface");
|
||||
}
|
||||
|
@ -48,10 +48,10 @@ static int current_report_status = INTERFACE_REPORT_STATUS_NONE;
|
||||
|
||||
void interface_report_display(void)
|
||||
{
|
||||
display_clear();
|
||||
if (current_report_status == INTERFACE_REPORT_STATUS_NONE)
|
||||
{
|
||||
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);
|
||||
if (current_cursor == 9)
|
||||
@ -59,24 +59,6 @@ void interface_report_display(void)
|
||||
display_set_button(interface_get_label_text(&interface_text_button_ok), false, true);
|
||||
}
|
||||
|
||||
if (current_cursor > 0)
|
||||
{
|
||||
display_data(display_gfx_arrow_left, 8, 3, 8, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, 3, 8, false);
|
||||
}
|
||||
|
||||
if (current_cursor < 9)
|
||||
{
|
||||
display_data(display_gfx_arrow_right, 8, 3, 112, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, 3, 112, false);
|
||||
}
|
||||
|
||||
display_clear_line(2, false);
|
||||
display_clear_line(4, false);
|
||||
|
||||
@ -123,25 +105,45 @@ void interface_report_display(void)
|
||||
display_data(display_gfx_arrow_down, 8, 4, current_cursor * 8 + offset * 8, false);
|
||||
|
||||
display_chars(¤t_tan[current_cursor], 1, 3, current_cursor + offset, false);
|
||||
|
||||
if (current_cursor > 0)
|
||||
{
|
||||
display_data(display_gfx_arrow_left, 8, 3, 8, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, 3, 8, false);
|
||||
}
|
||||
|
||||
if (current_cursor < 9)
|
||||
{
|
||||
display_data(display_gfx_arrow_right, 8, 3, 112, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, 3, 112, false);
|
||||
}
|
||||
}
|
||||
else if (current_report_status == INTERFACE_REPORT_STATUS_PENDING)
|
||||
{
|
||||
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_report), false, 0);
|
||||
display_clear();
|
||||
display_text_line_column(interface_get_label_text(&interface_text_report_pending), 4, 1, false);
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_report), false, 0);
|
||||
}
|
||||
else if (current_report_status == INTERFACE_REPORT_STATUS_SUCCESS)
|
||||
{
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_report), false, 0);
|
||||
display_clear();
|
||||
display_text_line_column(interface_get_label_text(&interface_text_report_success), 3, 1, false);
|
||||
display_set_button(interface_get_label_text(&interface_text_button_ok), false, true);
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_report), false, 0);
|
||||
}
|
||||
else if (current_report_status == INTERFACE_REPORT_STATUS_FAIL)
|
||||
{
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_report), false, 0);
|
||||
display_clear();
|
||||
display_text_line_column(interface_get_label_text(&interface_text_report_fail), 3, 1, false);
|
||||
display_set_button(interface_get_label_text(&interface_text_button_back), true, false);
|
||||
display_set_button(interface_get_label_text(&interface_text_button_ok), false, true);
|
||||
display_menu_headline(interface_get_label_text(&interface_text_headline_report), false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,8 +308,7 @@ void interface_report_start(void)
|
||||
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_set_display_function(&interface_report_display);
|
||||
interface_set_display_refresh_function(NULL);
|
||||
interface_register_command_callback(INTERFACE_COMMAND_RST_LONG, &interface_report_mid);
|
||||
|
||||
ESP_LOGD(INTERFACE_LOG, "start report interface");
|
||||
interface_set_display_function(&interface_report_display);
|
||||
}
|
||||
|
@ -50,10 +50,6 @@ void interface_settings_set(void)
|
||||
interface_main_start();
|
||||
}
|
||||
|
||||
void interface_settings_rst(void)
|
||||
{
|
||||
}
|
||||
|
||||
void interface_settings_lft(void)
|
||||
{
|
||||
interface_info_start();
|
||||
@ -191,15 +187,13 @@ 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_RST, &interface_settings_mid);
|
||||
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);
|
||||
interface_set_display_refresh_function(NULL);
|
||||
|
||||
ESP_LOGD(INTERFACE_LOG, "start settings interface");
|
||||
interface_set_display_function(&interface_settings_display);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "display.h"
|
||||
#include "display-gfx.h"
|
||||
#include "wifi-controller.h"
|
||||
#include "ena-eke-proxy.h"
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
@ -70,12 +71,14 @@ void interface_wifi_rht(void)
|
||||
{
|
||||
interface_datetime_start();
|
||||
}
|
||||
|
||||
void interface_wifi_mid(void)
|
||||
{
|
||||
memset(¤t_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--;
|
||||
@ -120,6 +123,7 @@ void interface_wifi_display_refresh(void)
|
||||
{
|
||||
if (ap_count > 0)
|
||||
{
|
||||
ena_eke_proxy_resume();
|
||||
display_clear_line(2, false);
|
||||
display_clear_line(4, false);
|
||||
display_clear_line(6, false);
|
||||
@ -132,6 +136,10 @@ void interface_wifi_display_refresh(void)
|
||||
{
|
||||
display_data(display_gfx_arrow_right, 8, i * 2 + 2, 8, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_data(display_gfx_clear, 8, i * 2 + 2, 8, false);
|
||||
}
|
||||
|
||||
if (sizeof(ap_info[i].ssid) > 0)
|
||||
{
|
||||
@ -171,18 +179,17 @@ void interface_wifi_start(void)
|
||||
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_register_command_callback(INTERFACE_COMMAND_RST, &interface_wifi_mid);
|
||||
|
||||
interface_set_display_function(&interface_wifi_display);
|
||||
interface_set_display_refresh_function(&interface_wifi_display_refresh);
|
||||
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;
|
||||
|
||||
ena_eke_proxy_pause();
|
||||
|
||||
wifi_controller_scan(ap_info, &ap_count);
|
||||
}
|
||||
|
@ -29,6 +29,12 @@ static interface_display_function current_display_refresh_function;
|
||||
|
||||
static TimerHandle_t interface_idle_timer;
|
||||
static bool interface_idle = false;
|
||||
static bool busy = false;
|
||||
|
||||
bool interface_is_idle(void)
|
||||
{
|
||||
return interface_idle;
|
||||
}
|
||||
|
||||
void interface_register_command_callback(interface_command_t command, interface_command_callback callback)
|
||||
{
|
||||
@ -37,14 +43,26 @@ void interface_register_command_callback(interface_command_t command, interface_
|
||||
|
||||
void interface_set_display_function(interface_display_function display_function)
|
||||
{
|
||||
busy = true;
|
||||
display_clear();
|
||||
current_display_refresh_function = NULL;
|
||||
current_display_function = display_function;
|
||||
if (current_display_function != NULL)
|
||||
{
|
||||
(*current_display_function)();
|
||||
}
|
||||
busy = false;
|
||||
}
|
||||
|
||||
void interface_set_display_refresh_function(interface_display_function display_function)
|
||||
{
|
||||
display_clear();
|
||||
busy = true;
|
||||
current_display_refresh_function = display_function;
|
||||
if (current_display_function != NULL)
|
||||
{
|
||||
(*current_display_function)();
|
||||
}
|
||||
busy = false;
|
||||
}
|
||||
|
||||
void interface_execute_command(interface_command_t command)
|
||||
@ -53,19 +71,14 @@ void interface_execute_command(interface_command_t command)
|
||||
{
|
||||
xTimerReset(interface_idle_timer, 0);
|
||||
(*command_callbacks[command])();
|
||||
if (current_display_function != NULL || current_display_refresh_function != NULL)
|
||||
if (!busy)
|
||||
{
|
||||
display_clear();
|
||||
if (current_display_refresh_function != NULL)
|
||||
{
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
(*current_display_refresh_function)();
|
||||
}
|
||||
busy = true;
|
||||
if (current_display_function != NULL)
|
||||
{
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
(*current_display_function)();
|
||||
}
|
||||
busy = false;
|
||||
}
|
||||
}
|
||||
else if (interface_idle && command == INTERFACE_COMMAND_SET)
|
||||
@ -82,12 +95,16 @@ void interface_display_task(void *pvParameter)
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (current_display_refresh_function != NULL)
|
||||
if (!interface_idle && !busy && current_display_refresh_function != NULL)
|
||||
{
|
||||
(*current_display_refresh_function)();
|
||||
}
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
}
|
||||
else
|
||||
{
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void interface_idle_callback(TimerHandle_t timer)
|
||||
@ -101,7 +118,7 @@ void interface_start(void)
|
||||
|
||||
interface_idle_timer = xTimerCreate(
|
||||
"interface_idle",
|
||||
(15 * 1000) / portTICK_PERIOD_MS,
|
||||
(INTERFACE_IDLE_SECONDS * 1000) / portTICK_PERIOD_MS,
|
||||
false,
|
||||
NULL,
|
||||
interface_idle_callback);
|
||||
@ -112,10 +129,18 @@ void interface_start(void)
|
||||
display_start();
|
||||
display_clear();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
display_data(display_gfx_logo[i], 64, i, 32, false);
|
||||
}
|
||||
|
||||
xTaskCreate(&interface_display_task, "interface_display_task", 4096, NULL, 5, NULL);
|
||||
}
|
||||
|
||||
void interface_flipped(bool flipped)
|
||||
{
|
||||
busy = true;
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
display_clear();
|
||||
display_flipped(flipped);
|
||||
if (current_display_function != NULL)
|
||||
{
|
||||
(*current_display_function)();
|
||||
}
|
||||
busy = false;
|
||||
}
|
@ -28,6 +28,11 @@
|
||||
|
||||
#define INTERFACE_NUM_LOCALE 2
|
||||
|
||||
#define INTERFACE_IDLE_SECONDS CONFIG_ENA_INTERFACE_IDLE_TIME
|
||||
|
||||
#define INTERFACE_INPUT_TICKS_MS 20
|
||||
#define INTERFACE_LONG_STATE_SECONDS 1.0
|
||||
|
||||
/**
|
||||
* @brief available commands
|
||||
*/
|
||||
@ -40,6 +45,8 @@ typedef enum
|
||||
INTERFACE_COMMAND_LFT,
|
||||
INTERFACE_COMMAND_DWN,
|
||||
INTERFACE_COMMAND_UP,
|
||||
INTERFACE_COMMAND_RST_LONG,
|
||||
INTERFACE_COMMAND_SET_LONG,
|
||||
INTERFACE_COMMANDS_SIZE,
|
||||
} interface_command_t;
|
||||
|
||||
@ -80,6 +87,7 @@ interface_label_t interface_text_settings_locales[INTERFACE_NUM_LOCALE];
|
||||
interface_label_t interface_text_settings_timezone;
|
||||
|
||||
interface_label_t interface_text_info_num_keys;
|
||||
interface_label_t interface_text_info_last_keys;
|
||||
interface_label_t interface_text_info_exp_update;
|
||||
interface_label_t interface_text_info_exp_days;
|
||||
interface_label_t interface_text_info_exp_num;
|
||||
@ -116,6 +124,13 @@ typedef void (*interface_display_function)(void);
|
||||
*/
|
||||
typedef void (*interface_text_callback)(char *text, uint8_t cursor);
|
||||
|
||||
/**
|
||||
* @brief is interface in idle mode
|
||||
*
|
||||
* @return if interface is idle
|
||||
*/
|
||||
bool interface_is_idle(void);
|
||||
|
||||
/**
|
||||
* @brief init label
|
||||
*/
|
||||
@ -194,6 +209,13 @@ void interface_set_display_refresh_function(interface_display_function display_f
|
||||
*/
|
||||
void interface_start(void);
|
||||
|
||||
/**
|
||||
* @brief set interface flipped or not
|
||||
*
|
||||
* @param[in] on true interface is flipped
|
||||
*/
|
||||
void interface_flipped(bool flipped);
|
||||
|
||||
/**
|
||||
* @brief start delete data interface
|
||||
*/
|
||||
@ -229,6 +251,11 @@ void interface_settings_start(void);
|
||||
*/
|
||||
void interface_info_start(void);
|
||||
|
||||
/**
|
||||
* @brief start debug interface
|
||||
*/
|
||||
void interface_debug_start(void);
|
||||
|
||||
/**
|
||||
* @brief start interface for input
|
||||
*
|
||||
|
7
components/pmu-axp192/CMakeLists.txt
Normal file
7
components/pmu-axp192/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"axp192.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
i2c-main
|
||||
)
|
483
components/pmu-axp192/axp192.c
Normal file
483
components/pmu-axp192/axp192.c
Normal file
@ -0,0 +1,483 @@
|
||||
// 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_sleep.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "i2c-main.h"
|
||||
|
||||
#include "axp192.h"
|
||||
|
||||
void axp192_write_byte(uint8_t addr, uint8_t data)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(cmd);
|
||||
// Begin the I2C comm with AXP192_ADDRESS's address (SLA+Write)
|
||||
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
i2c_master_write_byte(cmd, data, 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 axp192_read_buff(uint8_t addr, uint8_t size, uint8_t *buff)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
// Send register address
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
|
||||
// Receive data
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_READ, true);
|
||||
i2c_master_read(cmd, buff, size, 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);
|
||||
}
|
||||
|
||||
uint8_t axp192_read_8bit(uint8_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
axp192_read_buff(addr, 1, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t axp192_read_12bit(uint8_t addr)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(addr, 2, buf);
|
||||
data = ((buf[0] << 4) + buf[1]); //
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t axp192_read_13bit(uint8_t addr)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(addr, 2, buf);
|
||||
data = ((buf[0] << 5) + buf[1]); //
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t axp192_read_16bit(uint8_t addr)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(addr, 2, buf);
|
||||
data = ((buf[0] << 8) + buf[1]);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t axp192_read_24bit(uint8_t addr)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint8_t buf[3];
|
||||
axp192_read_buff(addr, 3, buf);
|
||||
data = ((buf[0] << 16) + (buf[1] << 8) + buf[2]);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t axp192_read_32bit(uint8_t addr)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint8_t buf[4];
|
||||
axp192_read_buff(addr, 4, buf);
|
||||
data = ((buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]);
|
||||
return data;
|
||||
}
|
||||
|
||||
void axp192_screen_breath(uint8_t brightness)
|
||||
{
|
||||
if (brightness > 12)
|
||||
{
|
||||
brightness = 12;
|
||||
}
|
||||
uint8_t buf = axp192_read_8bit(0x28);
|
||||
axp192_write_byte(0x28, ((buf & 0x0f) | (brightness << 4)));
|
||||
}
|
||||
|
||||
void axp192_start(void)
|
||||
{
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
|
||||
// Set LDO2 & LDO3(ST7789_LED & TFT) 3.0V
|
||||
axp192_write_byte(0x28, 0xcc);
|
||||
|
||||
// Set ADC sample rate to 200hz
|
||||
axp192_write_byte(0x84, 0xF2);
|
||||
|
||||
// Set ADC to All Enable
|
||||
axp192_write_byte(0x82, 0xff);
|
||||
|
||||
// Bat charge voltage to 4.2, Current 100MA
|
||||
axp192_write_byte(0x33, 0xc0);
|
||||
|
||||
// Enable Bat,ACIN,VBUS,APS adc
|
||||
axp192_write_byte(0x82, 0xff);
|
||||
|
||||
// Enable Ext, LDO2, LDO3, DCDC1
|
||||
axp192_write_byte(0x12, axp192_read_8bit(0x12) | 0x4D);
|
||||
|
||||
// 128ms power on, 4s power off
|
||||
axp192_write_byte(0x36, 0x0C);
|
||||
|
||||
// Set RTC voltage to 3.3V
|
||||
axp192_write_byte(0x91, 0xF0);
|
||||
|
||||
// Set GPIO0 to LDO
|
||||
axp192_write_byte(0x90, 0x02);
|
||||
|
||||
// Disable vbus hold limit
|
||||
axp192_write_byte(0x30, 0x80);
|
||||
|
||||
// Set temperature protection
|
||||
axp192_write_byte(0x39, 0xfc);
|
||||
|
||||
// Enable RTC BAT charge
|
||||
axp192_write_byte(0x35, 0xa2);
|
||||
|
||||
// Enable bat detection
|
||||
axp192_write_byte(0x32, 0x46);
|
||||
}
|
||||
|
||||
bool axp192_get_bat_state()
|
||||
{
|
||||
if (axp192_read_8bit(0x01) | 0x20)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
//---------coulombcounter_from_here---------
|
||||
//enable: void EnableCoulombcounter(void);
|
||||
//disable: void DisableCOulombcounter(void);
|
||||
//stop: void StopCoulombcounter(void);
|
||||
//clear: void ClearCoulombcounter(void);
|
||||
//get charge data: uint32_t GetCoulombchargedata(void);
|
||||
//get discharge data: uint32_t GetCoulombdischargedata(void);
|
||||
//get coulomb val affter calculation: float GetCoulombdata(void);
|
||||
//------------------------------------------
|
||||
void axp192_enable_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0x80);
|
||||
}
|
||||
|
||||
void axp192_disable_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0x00);
|
||||
}
|
||||
|
||||
void axp192_stop_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0xC0);
|
||||
}
|
||||
|
||||
void axp192_clear_coulombcounter(void)
|
||||
{
|
||||
axp192_write_byte(0xB8, 0xA0);
|
||||
}
|
||||
|
||||
uint32_t axp192_get_coulombcharge_data(void)
|
||||
{
|
||||
return axp192_read_32bit(0xB0);
|
||||
}
|
||||
|
||||
uint32_t axp192_get_coulombdischarge_data(void)
|
||||
{
|
||||
return axp192_read_32bit(0xB4);
|
||||
}
|
||||
|
||||
float axp192_get_coulomb_data(void)
|
||||
{
|
||||
|
||||
uint32_t coin = 0;
|
||||
uint32_t coout = 0;
|
||||
|
||||
coin = axp192_get_coulombcharge_data();
|
||||
coout = axp192_get_coulombdischarge_data();
|
||||
|
||||
//c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate
|
||||
//Adc rate can be read from 84H ,change this variable if you change the ADC reate
|
||||
float ccc = 65536 * 0.5 * (coin - coout) / 3600.0 / 25.0;
|
||||
return ccc;
|
||||
}
|
||||
//----------coulomb_end_at_here----------
|
||||
|
||||
uint16_t axp192_get_Vbatdata(void)
|
||||
{
|
||||
|
||||
uint16_t vbat = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x78, 2, buf);
|
||||
vbat = ((buf[0] << 4) + buf[1]); // V
|
||||
return vbat;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Vindata(void)
|
||||
{
|
||||
uint16_t vin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x56, 2, buf);
|
||||
vin = ((buf[0] << 4) + buf[1]); // V
|
||||
return vin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Iindata(void)
|
||||
{
|
||||
uint16_t iin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x58, 2, buf);
|
||||
iin = ((buf[0] << 4) + buf[1]);
|
||||
return iin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Vusbindata(void)
|
||||
{
|
||||
uint16_t vin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x5a, 2, buf);
|
||||
vin = ((buf[0] << 4) + buf[1]); // V
|
||||
return vin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Iusbindata(void)
|
||||
{
|
||||
uint16_t iin = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x5C, 2, buf);
|
||||
iin = ((buf[0] << 4) + buf[1]);
|
||||
return iin;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Ichargedata(void)
|
||||
{
|
||||
|
||||
uint16_t icharge = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x7A, 2, buf);
|
||||
icharge = (buf[0] << 5) + buf[1];
|
||||
return icharge;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Idischargedata(void)
|
||||
{
|
||||
uint16_t idischarge = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x7C, 2, buf);
|
||||
idischarge = (buf[0] << 5) + buf[1];
|
||||
return idischarge;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Tempdata(void)
|
||||
{
|
||||
uint16_t temp = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x5e, 2, buf);
|
||||
temp = ((buf[0] << 4) + buf[1]);
|
||||
return temp;
|
||||
}
|
||||
|
||||
uint32_t axp192_get_Powerbatdata(void)
|
||||
{
|
||||
uint32_t power = 0;
|
||||
uint8_t buf[3];
|
||||
axp192_read_buff(0x70, 2, buf);
|
||||
power = (buf[0] << 16) + (buf[1] << 8) + buf[2];
|
||||
return power;
|
||||
}
|
||||
|
||||
uint16_t axp192_get_Vapsdata(void)
|
||||
{
|
||||
uint16_t vaps = 0;
|
||||
uint8_t buf[2];
|
||||
axp192_read_buff(0x7e, 2, buf);
|
||||
vaps = ((buf[0] << 4) + buf[1]);
|
||||
return vaps;
|
||||
}
|
||||
|
||||
void axp192_set_sleep(void)
|
||||
{
|
||||
uint8_t buf = axp192_read_8bit(0x31);
|
||||
buf = (1 << 3) | buf;
|
||||
axp192_write_byte(0x31, buf);
|
||||
axp192_write_byte(0x90, 0x00);
|
||||
axp192_write_byte(0x12, 0x09);
|
||||
axp192_write_byte(0x12, 0x00);
|
||||
}
|
||||
|
||||
uint8_t axp192_get_warning_leve(void)
|
||||
{
|
||||
uint8_t buf = axp192_read_8bit(0x47);
|
||||
return (buf & 0x01);
|
||||
}
|
||||
|
||||
// -- sleep
|
||||
void axp192_deep_sleep(uint64_t time_in_us)
|
||||
{
|
||||
axp192_set_sleep();
|
||||
|
||||
if (time_in_us > 0)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(time_in_us);
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||||
}
|
||||
(time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us);
|
||||
}
|
||||
|
||||
void axp192_light_sleep(uint64_t time_in_us)
|
||||
{
|
||||
axp192_set_sleep();
|
||||
|
||||
if (time_in_us > 0)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(time_in_us);
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||||
}
|
||||
esp_light_sleep_start();
|
||||
}
|
||||
|
||||
// 0 not press, 0x01 long press, 0x02 press
|
||||
uint8_t axp192_get_btn_press()
|
||||
{
|
||||
uint8_t state = axp192_read_8bit(0x46);
|
||||
if (state)
|
||||
{
|
||||
axp192_write_byte(0x46, 0x03);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
uint8_t axp192_get_warning_level(void)
|
||||
{
|
||||
return axp192_read_8bit(0x47) & 0x01;
|
||||
}
|
||||
|
||||
float axp192_get_bat_voltage()
|
||||
{
|
||||
float ADCLSB = 1.1 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x78);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_bat_current()
|
||||
{
|
||||
float ADCLSB = 0.5;
|
||||
uint16_t CurrentIn = axp192_read_13bit(0x7A);
|
||||
uint16_t CurrentOut = axp192_read_13bit(0x7C);
|
||||
return (CurrentIn - CurrentOut) * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vin_voltage()
|
||||
{
|
||||
float ADCLSB = 1.7 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x56);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vin_current()
|
||||
{
|
||||
float ADCLSB = 0.625;
|
||||
uint16_t Redata = axp192_read_12bit(0x58);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vbus_voltage()
|
||||
{
|
||||
float ADCLSB = 1.7 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x5A);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_vbus_current()
|
||||
{
|
||||
float ADCLSB = 0.375;
|
||||
uint16_t Redata = axp192_read_12bit(0x5C);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_temp()
|
||||
{
|
||||
float ADCLSB = 0.1;
|
||||
const float OFFSET_DEG_C = -144.7;
|
||||
uint16_t Redata = axp192_read_12bit(0x5E);
|
||||
return OFFSET_DEG_C + Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_bat_power()
|
||||
{
|
||||
float VoltageLSB = 1.1;
|
||||
float CurrentLCS = 0.5;
|
||||
uint32_t Redata = axp192_read_24bit(0x70);
|
||||
return VoltageLSB * CurrentLCS * Redata / 1000.0;
|
||||
}
|
||||
|
||||
float axp192_get_bat_charge_current()
|
||||
{
|
||||
float ADCLSB = 0.5;
|
||||
uint16_t Redata = axp192_read_12bit(0x7A);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
float axp192_get_aps_voltage()
|
||||
{
|
||||
float ADCLSB = 1.4 / 1000.0;
|
||||
uint16_t Redata = axp192_read_12bit(0x7E);
|
||||
return Redata * ADCLSB;
|
||||
}
|
||||
|
||||
float axp192_get_bat_coulomb_input()
|
||||
{
|
||||
uint32_t Redata = axp192_read_32bit(0xB0);
|
||||
return Redata * 65536 * 0.5 / 3600 / 25.0;
|
||||
}
|
||||
|
||||
float axp192_get_bat_coulomb_out()
|
||||
{
|
||||
uint32_t Redata = axp192_read_32bit(0xB4);
|
||||
return Redata * 65536 * 0.5 / 3600 / 25.0;
|
||||
}
|
||||
|
||||
void axp192_set_coulomb_clear()
|
||||
{
|
||||
axp192_write_byte(0xB8, 0x20);
|
||||
}
|
||||
|
||||
void axp192_set_ldo2(bool state)
|
||||
{
|
||||
uint8_t buf = axp192_read_8bit(0x12);
|
||||
if (state == true)
|
||||
buf = (1 << 2) | buf;
|
||||
else
|
||||
buf = ~(1 << 2) & buf;
|
||||
axp192_write_byte(0x12, buf);
|
||||
}
|
66
components/pmu-axp192/axp192.h
Normal file
66
components/pmu-axp192/axp192.h
Normal file
@ -0,0 +1,66 @@
|
||||
// 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 _PMW_AXP192_H_
|
||||
#define _PWM_AXP192_H_
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#define AXP192_ADDRESS 0x34
|
||||
|
||||
void axp192_start(void);
|
||||
void axp192_screen_breath(uint8_t brightness);
|
||||
bool axp192_get_bat_state();
|
||||
|
||||
void axp192_enable_coulombcounter(void);
|
||||
void axp192_disable_coulombcounter(void);
|
||||
void axp192_stop_coulombcounter(void);
|
||||
void axp192_clear_coulombcounter(void);
|
||||
uint32_t axp192_get_coulombcharge_data(void);
|
||||
uint32_t axp192_get_coulombdischarge_data(void);
|
||||
float axp192_get_coulomb_data(void);
|
||||
|
||||
uint8_t axp192_get_btn_press(void);
|
||||
|
||||
// -- sleep
|
||||
void axp192_set_sleep(void);
|
||||
void axp192_deep_sleep(uint64_t time_in_us);
|
||||
void axp192_light_sleep(uint64_t time_in_us);
|
||||
uint8_t axp192_get_warning_leve(void);
|
||||
|
||||
float axp192_get_bat_voltage();
|
||||
float axp192_get_bat_current();
|
||||
float axp192_get_vin_voltage();
|
||||
float axp192_get_vin_current();
|
||||
float axp192_get_vbus_voltage();
|
||||
float axp192_get_vbus_current();
|
||||
float axp192_get_temp();
|
||||
float axp192_get_bat_power();
|
||||
float axp192_get_bat_charge_current();
|
||||
float axp192_get_aps_voltage();
|
||||
float axp192_get_bat_coulomb_input();
|
||||
float axp192_get_bat_coulomb_out();
|
||||
uint8_t axp192_get_warning_level(void);
|
||||
void axp192_set_coulomb_clear();
|
||||
void axp192_set_ldo2(bool state);
|
||||
|
||||
void axp192_write_byte(uint8_t addr, uint8_t data);
|
||||
uint8_t axp192_read_8bit(uint8_t addr);
|
||||
uint16_t axp192_read_12bit(uint8_t addr);
|
||||
uint16_t axp192_read_13bit(uint8_t addr);
|
||||
uint16_t axp192_read_16bit(uint8_t addr);
|
||||
uint32_t axp192_read_24bit(uint8_t addr);
|
||||
uint32_t axp192_read_32bit(uint8_t addr);
|
||||
void axp192_read_buff(uint8_t addr, uint8_t size, uint8_t *buff);
|
||||
|
||||
#endif
|
8
components/rtc-bm8563/CMakeLists.txt
Normal file
8
components/rtc-bm8563/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"bm8563.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES
|
||||
rtc
|
||||
i2c-main
|
||||
)
|
112
components/rtc-bm8563/bm8563.c
Normal file
112
components/rtc-bm8563/bm8563.c
Normal file
@ -0,0 +1,112 @@
|
||||
// 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 "bm8563.h"
|
||||
|
||||
uint8_t bm8563_dec2bcd(uint8_t value)
|
||||
{
|
||||
return (((value / 10) << 4) | (value % 10));
|
||||
}
|
||||
|
||||
uint8_t bm8563_bcd2dec(uint8_t value)
|
||||
{
|
||||
return (((value >> 4) * 10) + (value & 0x0f));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read time
|
||||
*/
|
||||
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, (BM8563_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, BM8563_SECONDS, true);
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (BM8563_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 = bm8563_bcd2dec(data[0] & 0b01111111);
|
||||
time->tm_min = bm8563_bcd2dec(data[1] & 0b01111111);
|
||||
time->tm_hour = bm8563_bcd2dec(data[2] & 0b00111111);
|
||||
time->tm_mday = bm8563_bcd2dec(data[3] & 0b00111111);
|
||||
time->tm_wday = bm8563_bcd2dec(data[4] & 0b00000111);
|
||||
time->tm_mon = bm8563_bcd2dec(data[5] & 0b00011111) - 1;
|
||||
if (data[5] & BM8563_CENTURY_BIT)
|
||||
{
|
||||
time->tm_year = bm8563_bcd2dec(data[6] & 0b11111111) + 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
time->tm_year = bm8563_bcd2dec(data[6] & 0b01111111);
|
||||
}
|
||||
time->tm_isdst = 0;
|
||||
|
||||
mktime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write time
|
||||
*/
|
||||
void rtc_set_time(struct tm *time)
|
||||
{
|
||||
if (!i2c_is_initialized())
|
||||
{
|
||||
i2c_main_init();
|
||||
}
|
||||
|
||||
uint8_t data[7] = {0};
|
||||
data[0] = bm8563_dec2bcd(time->tm_sec) & 0b01111111;
|
||||
data[1] = bm8563_dec2bcd(time->tm_min) & 0b01111111;
|
||||
data[2] = bm8563_dec2bcd(time->tm_hour) & 0b00111111;
|
||||
data[3] = bm8563_dec2bcd(time->tm_mday) & 0b00111111;
|
||||
data[4] = bm8563_dec2bcd(time->tm_wday) & 0b00000111;
|
||||
data[5] = bm8563_dec2bcd(time->tm_mon + 1) & 0b00011111;
|
||||
if (time->tm_year > 100)
|
||||
{
|
||||
data[5] |= BM8563_CENTURY_BIT;
|
||||
}
|
||||
|
||||
data[6] = bm8563_dec2bcd(time->tm_year % 100) & 0b11111111;
|
||||
|
||||
i2c_cmd_handle_t cmd;
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (BM8563_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, BM8563_SECONDS, 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);
|
||||
}
|
80
components/rtc-bm8563/bm8563.h
Normal file
80
components/rtc-bm8563/bm8563.h
Normal file
@ -0,0 +1,80 @@
|
||||
// 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 BM8563 RTC
|
||||
*
|
||||
*/
|
||||
#ifndef _RTC_BM8562_H_
|
||||
#define _RTC_BM8562_H_
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#define BM8563_ADDRESS 0x51
|
||||
#define BM8563_CONTROL_STATUS1 0x00
|
||||
#define BM8563_TESTC 0b00001000
|
||||
#define BM8563_STOP 0b00100000
|
||||
#define BM8563_TEST1 0b10000000
|
||||
#define BM8563_CONTROL_STATUS2 0x01
|
||||
#define BM8563_TIE 0b00000001
|
||||
#define BM8563_AIE 0b00000010
|
||||
#define BM8563_TF 0b00000100
|
||||
#define BM8563_AF 0b00001000
|
||||
#define BM8563_TI_TP 0b00010000
|
||||
#define BM8563_SECONDS 0x02
|
||||
#define BM8563_MINUTES 0x03
|
||||
#define BM8563_HOURS 0x04
|
||||
#define BM8563_DAY 0x05
|
||||
#define BM8563_WEEKDAY 0x06
|
||||
#define BM8563_MONTH 0x07
|
||||
#define BM8563_YEAR 0x08
|
||||
#define BM8563_TIME_SIZE 0x07
|
||||
#define BM8563_CENTURY_BIT 0b10000000
|
||||
|
||||
#define BM8563_MINUTE_ALARM 0x09
|
||||
#define BM8563_HOUR_ALARM 0x0a
|
||||
#define BM8563_DAY_ALARM 0x0b
|
||||
#define BM8563_WEEKDAY_ALARM 0x0c
|
||||
#define BM8563_ALARM_DISABLE 0b10000000
|
||||
#define BM8563_ALARM_NONE 0xff
|
||||
#define BM8563_ALARM_SIZE 0x04
|
||||
|
||||
#define BM8563_TIMER_CONTROL 0x0e
|
||||
#define BM8563_TIMER_ENABLE 0b10000000
|
||||
#define BM8563_TIMER_4_096KHZ 0b00000000
|
||||
#define BM8563_TIMER_64HZ 0b00000001
|
||||
#define BM8563_TIMER_1HZ 0b00000010
|
||||
#define BM8563_TIMER_1_60HZ 0b00000011
|
||||
#define BM8563_TIMER 0x0f
|
||||
|
||||
#define BM8563_ALARM_SET 0x0900
|
||||
#define BM8563_ALARM_READ 0x0901
|
||||
#define BM8563_CONTROL_STATUS1_READ 0x0000
|
||||
#define BM8563_CONTROL_STATUS1_WRITE 0x0001
|
||||
#define BM8563_CONTROL_STATUS2_READ 0x0100
|
||||
#define BM8563_CONTROL_STATUS2_WRITE 0x0101
|
||||
#define BM8563_TIMER_CONTROL_READ 0x0e00
|
||||
#define BM8563_TIMER_CONTROL_WRITE 0x0e01
|
||||
#define BM8563_TIMER_READ 0x0f00
|
||||
#define BM8563_TIMER_WRITE 0x0f01
|
||||
|
||||
/* Status codes. */
|
||||
#define BM8563_ERROR_NOTTY (-1)
|
||||
#define BM8563_OK (0x00)
|
||||
#define BM8563_ERR_LOW_VOLTAGE (0x80)
|
||||
|
||||
#endif
|
@ -1,9 +0,0 @@
|
||||
menu "WiFi STA"
|
||||
|
||||
config WIFI_STA_SSID
|
||||
string "Wifi SSID"
|
||||
|
||||
config WIFI_STA_PASSWORD
|
||||
string "Wifi Password"
|
||||
|
||||
endmenu
|
18
main/main.c
18
main/main.c
@ -27,15 +27,20 @@
|
||||
#include "ena-bluetooth-advertise.h"
|
||||
#include "ena-bluetooth-scan.h"
|
||||
#include "ena-eke-proxy.h"
|
||||
#include "ds3231.h"
|
||||
#include "ssd1306.h"
|
||||
#include "interface.h"
|
||||
#include "button-input.h"
|
||||
#include "rtc.h"
|
||||
#include "wifi-controller.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_ENA_INTERFACE_CUSTOM
|
||||
#include "button-input.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
|
||||
#include "m5-input.h"
|
||||
#endif
|
||||
|
||||
void time_sync_notification_cb(struct timeval *tv)
|
||||
{
|
||||
time_t time = (time_t)tv->tv_sec;
|
||||
@ -49,6 +54,7 @@ void app_main(void)
|
||||
{
|
||||
// debug only own LOG TAGs
|
||||
esp_log_level_set("*", ESP_LOG_WARN);
|
||||
esp_log_level_set("wifi", ESP_LOG_ERROR);
|
||||
esp_log_level_set(ENA_LOG, ESP_LOG_DEBUG);
|
||||
esp_log_level_set(ENA_BEACON_LOG, ESP_LOG_INFO);
|
||||
esp_log_level_set(ENA_ADVERTISE_LOG, ESP_LOG_INFO);
|
||||
@ -83,7 +89,13 @@ void app_main(void)
|
||||
interface_main_start();
|
||||
|
||||
// start button input
|
||||
#if defined(CONFIG_ENA_INTERFACE_CUSTOM)
|
||||
button_input_start();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
|
||||
m5_input_start();
|
||||
#endif
|
||||
|
||||
wifi_controller_reconnect(NULL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user