small interface improvements, renaming of device specific modules, starting with TTGO T-Wristband support

This commit is contained in:
Lurkars 2020-12-15 13:12:35 +01:00
parent 48528e027e
commit 17ebf801f1
45 changed files with 850 additions and 54 deletions

View File

@ -180,39 +180,51 @@ General module for set/get time from RTC.
Just start I²C driver.
### interface-input-buttons
### interface-custom-input
Interface with 7 button input.
### interface-input-m5
### interface-m5-input
Interface with input for M5StickC (PLUS) with 2 button input and accelerometer as axis input.
### rtc-ds3231
### interface-ttgo-input
Interface with input for TTGO T-Wristband with 1 button input and accelerometer as axis input.
### rtc-custom-ds3231
I²C driver for a DS3231 RTC, implementation of [rtc](#-rtc) module.
### rtc-bm8563
### rtc-m5-bm8563
I²C driver for BM8563 of M5StickC (PLUS), implementation of [rtc](#-rtc) module.
### display-ssd1306
### display-custom-ssd1306
I²C driver for a SSD1306 display, implementation of [display](#-display) module.
### display-st7735s
### display-m5-st7735s
SPI driver for a ST7735s display of M5StickC, implementation of [display](#-display) module.
### display-st7789
### display-m5-st7789
SPI driver for a ST7789 display of M5StickC PLUS, implementation of [display](#-display) module
### imu-mpu6886
### display-ttgo-st7735
SPI driver for a ST7735 display of TTGO T-Wristband, implementation of [display](#-display) module.
### imu-m5-mpu6886
I²C driver for MPU6886 6-Axis IMU of M5StickC (PLUS).
### pmu-axp192
### imu-ttgo-lsm9ds1 \[in development\]
I²C driver for LSM9DS1 6-Axis IMU of TTGO T-Wristband.
### pmu-m5-axp192
I²C driver for AXP192 PMU of M5StickC (PLUS).

View File

@ -5,5 +5,5 @@ idf_component_register(
PRIV_REQUIRES
"display"
"spi_flash"
"pmu-axp192"
"pmu-m5-axp192"
)

View File

@ -5,5 +5,5 @@ idf_component_register(
PRIV_REQUIRES
"display"
"spi_flash"
"pmu-axp192"
"pmu-m5-axp192"
)

View File

@ -0,0 +1,8 @@
idf_component_register(
SRCS
"st7735.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
"display"
"spi_flash"
)

View File

@ -0,0 +1,346 @@
// 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 "st7735.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(TTGO_T_WRISTBAND_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)
{
esp_err_t ret;
gpio_set_direction(TTGO_T_WRISTBAND_CS_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(TTGO_T_WRISTBAND_CS_GPIO, 0);
gpio_set_direction(TTGO_T_WRISTBAND_DC_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(TTGO_T_WRISTBAND_DC_GPIO, 0);
gpio_set_direction(TTGO_T_WRISTBAND_RESET_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(TTGO_T_WRISTBAND_RESET_GPIO, 0);
vTaskDelay(100 / portTICK_PERIOD_MS);
gpio_set_level(TTGO_T_WRISTBAND_RESET_GPIO, 1);
spi_bus_config_t buscfg = {
.sclk_io_num = TTGO_T_WRISTBAND_SCLK_GPIO,
.mosi_io_num = TTGO_T_WRISTBAND_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 = TTGO_T_WRISTBAND_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(TTGO_T_WRISTBAND_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);
vTaskDelay(50 / portTICK_PERIOD_MS);
gpio_pad_select_gpio(TTGO_T_WRISTBAND__BL_GPIO);
gpio_set_direction(TTGO_T_WRISTBAND__BL_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(TTGO_T_WRISTBAND__BL_GPIO, 1);
}
void display_clear_line(uint8_t line, bool invert)
{
uint16_t _x1 = 0 + TTGO_T_WRISTBAND_OFFSETX;
uint16_t _x2 = TTGO_T_WRISTBAND_WIDTH + TTGO_T_WRISTBAND_OFFSETX - 1;
uint16_t _y1 = line * 8 + TTGO_T_WRISTBAND_OFFSETY + TTGO_T_WRISTBAND_INTERFACE_OFFSETY;
uint16_t _y2 = line * 8 + 8 + TTGO_T_WRISTBAND_OFFSETY - 1 + TTGO_T_WRISTBAND_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 + TTGO_T_WRISTBAND_OFFSETX;
uint16_t _x2 = TTGO_T_WRISTBAND_WIDTH + TTGO_T_WRISTBAND_OFFSETX - 1;
uint16_t _y1 = 0 + TTGO_T_WRISTBAND_OFFSETY;
uint16_t _y2 = TTGO_T_WRISTBAND_HEIGHT + TTGO_T_WRISTBAND_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)
{
// TODO
}
void display_data(uint8_t *data, size_t length, uint8_t line, uint8_t offset, bool invert)
{
uint16_t _x1 = offset + TTGO_T_WRISTBAND_OFFSETX + TTGO_T_WRISTBAND_INTERFACE_OFFSETX;
uint16_t _x2 = offset + length + TTGO_T_WRISTBAND_OFFSETX - 1 + TTGO_T_WRISTBAND_INTERFACE_OFFSETX;
uint16_t _y1 = line * 8 + TTGO_T_WRISTBAND_OFFSETY + TTGO_T_WRISTBAND_INTERFACE_OFFSETY;
uint16_t _y2 = line * 8 + 8 + TTGO_T_WRISTBAND_OFFSETY - 1 + TTGO_T_WRISTBAND_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(TTGO_T_WRISTBAND_LANDSCAPE_FLIPPED);
}
else
{
spi_master_write_data_byte(TTGO_T_WRISTBAND_LANDSCAPE);
}
}

View File

@ -0,0 +1,28 @@
#ifndef DISPLAY_ST7735_H_
#define DISPLAY_ST7735_H_
#include "driver/spi_master.h"
// M5stickC
#define TTGO_T_WRISTBAND_WIDTH 160
#define TTGO_T_WRISTBAND_HEIGHT 80
#define TTGO_T_WRISTBAND_MOSI_GPIO 19
#define TTGO_T_WRISTBAND_SCLK_GPIO 18
#define TTGO_T_WRISTBAND_CS_GPIO 5
#define TTGO_T_WRISTBAND_DC_GPIO 23
#define TTGO_T_WRISTBAND_RESET_GPIO 26
#define TTGO_T_WRISTBAND__BL_GPIO 27
#define TTGO_T_WRISTBAND_OFFSETX 1
#define TTGO_T_WRISTBAND_OFFSETY 26
#define TTGO_T_WRISTBAND_INTERFACE_OFFSETX 16
#define TTGO_T_WRISTBAND_INTERFACE_OFFSETY 8
#define TTGO_T_WRISTBAND_LANDSCAPE_FLIPPED 0x60
#define TTGO_T_WRISTBAND_LANDSCAPE 0xA0
#define SPI_COMMAND_MODE 0
#define SPI_DATA_MODE 1
#endif

View File

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

View File

@ -0,0 +1,127 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <time.h>
#include "driver/i2c.h"
#include "esp_log.h"
#include "i2c-main.h"
#include "lsm9ds1.h"
float aRes, gRes;
void lsm9ds1_i2c_read_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *read_buffer)
{
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, start_addr, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd, read_buffer, number_Bytes, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
}
void lsm9ds1_i2c_write_bytes(uint8_t driver_addr, uint8_t start_addr, uint8_t number_Bytes, uint8_t *write_buffer)
{
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (driver_addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, start_addr, true);
i2c_master_write(cmd, write_buffer, number_Bytes, true);
i2c_master_stop(cmd);
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
}
int lsm9ds1_start(void)
{
unsigned char regdata;
// init ACC
regdata = 0x38;
lsm9ds1_i2c_write_bytes(ACC_ADDR, CTRL_REG5_A, 1, &regdata);
regdata = 0xC0;
lsm9ds1_i2c_write_bytes(ACC_ADDR, CTRL_REG6_A, 1, &regdata);
lsm9ds1_i2c_read_bytes(ACC_ADDR, CTRL_REG6_A, 1, &regdata);
regdata &= ~(0b00011000);
regdata |= ACCELRANGE_16G;
lsm9ds1_i2c_write_bytes(ACC_ADDR, CTRL_REG6_A, 1, &regdata);
// init gyr
regdata = 0xC0;
lsm9ds1_i2c_write_bytes(GYR_ADDR, CTRL_REG1_G, 1, &regdata);
lsm9ds1_i2c_read_bytes(GYR_ADDR, CTRL_REG1_G, 1, &regdata);
regdata &= ~(0b00011000);
regdata |= GYROSCALE_500DPS;
lsm9ds1_i2c_write_bytes(GYR_ADDR, CTRL_REG1_G, 1, &regdata);
aRes = 16.0 / 32768.0;
gRes = 500.0 / 32768.0;
return 0;
}
void lsm9ds1_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az)
{
uint8_t buf[6];
lsm9ds1_i2c_read_bytes(ACC_ADDR, OUT_X_L_A, 6, buf);
*ax = ((int16_t)buf[0] << 8) | buf[1];
*ay = ((int16_t)buf[2] << 8) | buf[3];
*az = ((int16_t)buf[4] << 8) | buf[5];
}
void lsm9ds1_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz)
{
uint8_t buf[6];
lsm9ds1_i2c_read_bytes(GYR_ADDR, OUT_X_L_G, 6, buf);
*gx = ((uint16_t)buf[0] << 8) | buf[1];
*gy = ((uint16_t)buf[2] << 8) | buf[3];
*gz = ((uint16_t)buf[4] << 8) | buf[5];
}
void lsm9ds1_get_accel_data(float *ax, float *ay, float *az)
{
int16_t accX = 0;
int16_t accY = 0;
int16_t accZ = 0;
lsm9ds1_get_accel_adc(&accX, &accY, &accZ);
*ax = (float)accX * aRes;
*ay = (float)accY * aRes;
*az = (float)accZ * aRes;
}
void lsm9ds1_get_gyro_data(float *gx, float *gy, float *gz)
{
int16_t gyroX = 0;
int16_t gyroY = 0;
int16_t gyroZ = 0;
lsm9ds1_get_gyro_adc(&gyroX, &gyroY, &gyroZ);
*gx = (float)gyroX * gRes;
*gy = (float)gyroY * gRes;
*gz = (float)gyroZ * gRes;
}

View File

@ -0,0 +1,138 @@
/*
Note: The MPU6886 is an I2C sensor and uses the Arduino Wire library.
Because the sensor is not 5V tolerant, we are using a 3.3 V 8 MHz Pro Mini or
a 3.3 V Teensy 3.1. We have disabled the internal pull-ups used by the Wire
library in the Wire.h/twi.c utility file. We are also using the 400 kHz fast
I2C mode by setting the TWI_FREQ to 400000L /twi.h utility file.
*/
#ifndef _IMU_LSM9DS1_H_
#define _IMU_LSM9DS1_H_
#include "stdio.h"
#define ID_AG 0x6F
#define ID_A 0x6F
#define ID_G 0x6F
#define ID_M 0x3D
#define FILENAME "/dev/i2c-1"
#define MAG_ADDR 0x1E
#define ACC_ADDR 0x6B
#define GYR_ADDR 0x6B
// Shared Accelerometer/Gyroscope Addresses
#define WHO_AM_I_AG 0x0F
#define CTRL_REG1_AG 0x10
#define CTRL_REG2_AG 0x11
#define CTRL_REG3_AG 0x12
#define OUT_TEMP_L_AG 0x15
#define OUT_TEMP_H_AG 0x16
#define REG_STATUS_REG_AG 0x17
#define CTRL_REG4_AG 0x1E
#define CTRL_REG5_AG 0x1F
#define CTRL_REG6_AG 0x20
#define CTRL_REG7_AG 0x21
#define CTRL_REG8_AG 0x22
#define CTRL_REG9_AG 0x23
#define CTRL_REG10_AG 0x24
// Gyroscope addresses
#define WHO_AM_I_G 0x0F
#define CTRL_REG1_G 0x10
#define CTRL_REG2_G 0x11
#define CTRL_REG3_G 0x12
#define OUT_X_L_G 0x18
#define OUT_X_H_G 0x19
#define OUT_Y_L_G 0x1A
#define OUT_Y_H_G 0x1B
#define OUT_Z_L_G 0x1C
#define OUT_Z_H_G 0x1D
// Accelerometer addresses
#define WHO_AM_I_A 0x0F
#define CTRL_REG5_A 0x1F
#define CTRL_REG6_A 0x20
#define CTRL_REG7_A 0x21
#define OUT_X_L_A 0x28
#define OUT_X_H_A 0x29
#define OUT_Y_L_A 0x2A
#define OUT_Y_H_A 0x2B
#define OUT_Z_L_A 0x2C
#define OUT_Z_H_A 0x2D
// Magnetometer addresses
#define WHO_AM_I_M 0x0F
#define CTRL_REG1_M 0x20
#define CTRL_REG2_M 0x21
#define CTRL_REG3_M 0x22
#define CTRL_REG4_M 0x23
#define CTRL_REG5_M 0x24
#define REG_STATUS_REG_M 0x27
#define OUT_X_L_M 0x28
#define OUT_X_H_M 0x29
#define OUT_Y_L_M 0x2A
#define OUT_Y_H_M 0x2B
#define OUT_Z_L_M 0x2C
#define OUT_Z_H_M 0x2D
#define REG_CFG_M 0x30
#define INT_SRC_M 0x31
// Settings
#define ACCELRANGE_2G 0x0 << 3
#define ACCELRANGE_16G 0x1 << 3
#define ACCELRANGE_4G 0x2 << 3
#define ACCELRANGE_8G 0x3 << 3
#define ACCELDATARATE_POWERDOWN 0x0 << 4
#define ACCELDATARATE_3_125HZ 0x1 << 4
#define ACCELDATARATE_6_25HZ 0x2 << 4
#define ACCELDATARATE_12_5HZ 0x3 << 4
#define ACCELDATARATE_25HZ 0x4 << 4
#define ACCELDATARATE_50HZ 0x5 << 4
#define ACCELDATARATE_100HZ 0x6 << 4
#define ACCELDATARATE_200HZ 0x7 << 4
#define ACCELDATARATE_400HZ 0x8 << 4
#define ACCELDATARATE_800HZ 0x9 << 4
#define ACCELDATARATE_1600HZ 0xa << 4
#define MAGGAIN_4GAUSS 0x0 << 5
#define MAGGAIN_8GAUSS 0x1 << 5
#define MAGGAIN_12GAUSS 0x2 << 5
#define MAGGAIN_16GAUSS 0x3 << 5
#define MAGDATARATE_3_125HZ 0x0 << 2
#define MAGDATARATE_6_25HZ 0x1 << 2
#define MAGDATARATE_12_5HZ 0x2 << 2
#define MAGDATARATE_25HZ 0x3 << 2
#define MAGDATARATE_50HZ 0x4 << 2
#define MAGDATARATE_100HZ 0x5 << 2
#define GYROSCALE_245DPS 0x0 << 4
#define GYROSCALE_500DPS 0x1 << 4
#define GYROSCALE_2000DPS 0x2 << 4
/* Conversions */
#define GRAVITY (9.80665F)
#define ACCEL_MG_LSB_2G (0.061F)
#define ACCEL_MG_LSB_4G (0.122F)
#define ACCEL_MG_LSB_8G (0.244F)
#define ACCEL_MG_LSB_16G (0.732F) // Is this right? Was expecting 0.488F
#define MAG_MGAUSS_4GAUSS (0.16F)
#define MAG_MGAUSS_8GAUSS (0.32F)
#define MAG_MGAUSS_12GAUSS (0.48F)
#define MAG_MGAUSS_16GAUSS (0.58F)
#define GYRO_DPS_DIGIT_245DPS (0.00875F)
#define GYRO_DPS_DIGIT_500DPS (0.01750F)
#define GYRO_DPS_DIGIT_2000DPS (0.07000F)
int lsm9ds1_start(void);
void lsm9ds1_get_accel_adc(int16_t *ax, int16_t *ay, int16_t *az);
void lsm9ds1_get_gyro_adc(int16_t *gx, int16_t *gy, int16_t *gz);
void lsm9ds1_get_accel_data(float *ax, float *ay, float *az);
void lsm9ds1_get_gyro_data(float *gx, float *gy, float *gz);
#endif

View File

@ -1,6 +1,6 @@
idf_component_register(
SRCS
"button-input.c"
"custom-input.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
interface

View File

@ -19,13 +19,13 @@
#include "interface.h"
#include "button-input.h"
#include "custom-input.h"
static float input_states[INTERFACE_COMMANDS_SIZE];
static float input_trigger_state[INTERFACE_COMMANDS_SIZE];
static int input_command_mapping[INTERFACE_COMMANDS_SIZE];
void button_input_check(interface_command_t command)
void custom_input_check(interface_command_t command)
{
int button_level = gpio_get_level(input_command_mapping[command]);
@ -79,25 +79,25 @@ void button_input_check(interface_command_t command)
}
}
void button_input_task(void *pvParameter)
void custom_input_task(void *pvParameter)
{
while (1)
{
button_input_check(INTERFACE_COMMAND_SET);
custom_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);
custom_input_check(INTERFACE_COMMAND_RST);
custom_input_check(INTERFACE_COMMAND_MID);
custom_input_check(INTERFACE_COMMAND_RHT);
custom_input_check(INTERFACE_COMMAND_LFT);
custom_input_check(INTERFACE_COMMAND_DWN);
custom_input_check(INTERFACE_COMMAND_UP);
}
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
}
}
void button_input_start(void)
void custom_input_start(void)
{
gpio_config_t io_conf;
@ -124,5 +124,5 @@ void button_input_start(void)
input_trigger_state[i] = INTERFACE_LONG_STATE_SECONDS;
}
xTaskCreate(&button_input_task, "button_input_task", 4096, NULL, 5, NULL);
xTaskCreate(&custom_input_task, "custom_input_task", 4096, NULL, 5, NULL);
}

View File

@ -33,6 +33,6 @@
*
*
*/
void button_input_start(void);
void custom_input_start(void);
#endif

View File

@ -4,5 +4,5 @@ idf_component_register(
INCLUDE_DIRS "."
PRIV_REQUIRES
interface
imu-mpu6886
imu-m5-mpu6886
)

View File

@ -0,0 +1,8 @@
idf_component_register(
SRCS
"ttgo-input.c"
INCLUDE_DIRS "."
PRIV_REQUIRES
interface
imu-ttgo-lsm9ds1
)

View File

@ -0,0 +1,44 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "lsm9ds1.h"
#include "interface.h"
#include "ttgo-input.h"
void ttgo_input_task(void *pvParameter)
{
float ax = 0;
float ay = 0;
float az = 0;
while (1)
{
lsm9ds1_get_accel_data(&ax, &ay, &az);
// ESP_LOGI(INTERFACE_LOG, "ax: %f ay:%f az:%f", ax, ay, az);
vTaskDelay(INTERFACE_INPUT_TICKS_MS / portTICK_PERIOD_MS);
}
}
void ttgo_input_start(void)
{
lsm9ds1_start();
xTaskCreate(&ttgo_input_task, "ttgo_input_task", 4096, NULL, 5, NULL);
}

View File

@ -0,0 +1,30 @@
// Copyright 2020 Lukas Haubaum
//
// Licensed under the GNU Affero General Public License, Version 3;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.gnu.org/licenses/agpl-3.0.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @file
*
* @brief execute interface commands via simple push buttons
*
*/
#ifndef _ttgo_input_H_
#define _ttgo_input_H_
/**
* @brief
*
*
*/
void ttgo_input_start(void);
#endif

View File

@ -1,15 +1,18 @@
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")
list(APPEND priv_requires "display-custom-ssd1306" "rtc-custom-ds3231")
elseif(CONFIG_ENA_INTERFACE_M5STICKC)
list(CONFIG_APPEND priv_requires "display-m5-st7735s" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192")
elseif(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
list(APPEND priv_requires "display-m5-st7789" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192")
elseif(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
list(APPEND priv_requires "display-ttgo-st7735" "imu-ttgo-lsm9ds1")
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
list(APPEND priv_requires "display-custom-ssd1306" "rtc-custom-ds3231") # uncomment for custom device with SSD1306 und DS3231
# list(APPEND priv_requires "display-m5-st7735s" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192") # uncomment for M5StickC
# list(APPEND priv_requires "display-m5-st7789" "rtc-m5-bm8563" "imu-m5-mpu6886" "pmu-m5-axp192") # uncomment for M5StickC PLUS
# list(APPEND priv_requires "display-ttgo-st7735" "imu-ttgo-lsm9ds1") # uncomment for TTGO T-Wristband
endif()
idf_component_register(

View File

@ -21,6 +21,9 @@ menu "ENA Interface"
config ENA_INTERFACE_M5STICKC_PLUS
bool "M5StickC PLUS"
config ENA_INTERFACE_TTGO_T_WRISTBAND
bool "TTGO T-Wristband"
endchoice
endmenu

View File

@ -27,6 +27,10 @@
#include "axp192.h"
#endif
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
#include "lsm9ds1.h"
#endif
#include "interface.h"
static bool runTask = true;
@ -75,7 +79,7 @@ void interface_debug_dwn(void)
void interface_debug_task(void *pvParameter)
{
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS) || defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
float ax = 0;
float ay = 0;
float az = 0;
@ -94,6 +98,14 @@ void interface_debug_task(void *pvParameter)
mpu6886_get_accel_data(&ax, &ay, &az);
mpu6886_get_gyro_data(&gx, &gy, &gz);
#endif
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
lsm9ds1_get_accel_data(&ax, &ay, &az);
lsm9ds1_get_gyro_data(&gx, &gy, &gz);
#endif
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS) || defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
char data_chars[32];
sprintf(data_chars, "acc x:%3.2f", ax);
display_text_line(data_chars, 2, false);
@ -108,8 +120,10 @@ void interface_debug_task(void *pvParameter)
sprintf(data_chars, "gyr z:%3.2f", gz);
display_text_line(data_chars, 7, false);
float bat_v = axp192_get_bat_voltage();
#endif
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
float bat_v = axp192_get_bat_voltage();
sprintf(data_chars, "Battery: %.2f V", bat_v);
display_text_line(data_chars, 7, false);
@ -123,6 +137,10 @@ void interface_debug_task(void *pvParameter)
void interface_debug_start(void)
{
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
lsm9ds1_start();
#endif
interface_register_command_callback(INTERFACE_COMMAND_RST, &interface_debug_rst);
interface_register_command_callback(INTERFACE_COMMAND_SET, &interface_debug_set);
interface_register_command_callback(INTERFACE_COMMAND_LFT, &interface_debug_lft);

View File

@ -111,15 +111,10 @@ void interface_input_rht(void)
if (current_cursor > current_max_index)
{
current_max_index = current_cursor;
strcpy(current_char_set, char_set_uppercase);
current_text[current_cursor] = current_text[current_cursor - 1];
}
current_char_index = 0;
current_text[current_cursor] = current_char_set[current_char_index];
}
else
{
interface_input_set_char_set();
}
interface_input_set_char_set();
}
}
@ -149,7 +144,12 @@ void interface_input_mid(void)
{
strcpy(current_char_set, char_set_uppercase);
}
current_char_index = 0;
if (current_char_index >= strlen(current_char_set))
{
current_char_index = 0;
}
current_text[current_cursor] = current_char_set[current_char_index];
}

View File

@ -40,7 +40,9 @@ void interface_init_label(void)
interface_text_headline_info.text[EN] = "INFO";
interface_text_headline_debug.text[EN] = "DEBUG";
interface_text_wifi_waiting.text[EN] = "Waiting...";
interface_text_wifi_scanning.text[EN] = "Scanning...";
interface_text_wifi_connecting.text[EN] = "Connecting...";
interface_text_wifi_nothing.text[EN] = "None...";
interface_text_settings_locale.text[EN] = "Language:";
@ -104,7 +106,9 @@ void interface_init_label(void)
interface_text_headline_info.text[DE] = "INFOS";
interface_text_headline_debug.text[DE] = "DEBUG";
interface_text_wifi_waiting.text[DE] = "Warten...";
interface_text_wifi_scanning.text[DE] = "Scannen...";
interface_text_wifi_connecting.text[DE] = "Verbinden...";
interface_text_wifi_nothing.text[DE] = "Keine...";
interface_text_settings_locale.text[DE] = "Sprache:";

View File

@ -43,6 +43,12 @@ void interface_wifi_input_rst(char *text, uint8_t cursor)
void interface_wifi_input_set(char *text, uint8_t cursor)
{
display_clear();
display_menu_headline(interface_get_label_text(&interface_text_headline_wifi), true, 0);
display_text_line_column(interface_get_label_text(&interface_text_wifi_connecting), 4, 1, false);
memcpy(current_wifi_config.sta.password, text, cursor + 1);
ESP_LOGD(INTERFACE_LOG, "ssid: '%s' password '%s'", current_wifi_config.sta.ssid, current_wifi_config.sta.password);
@ -173,15 +179,16 @@ void interface_wifi_scan(void)
if (!interface_wifi_working)
{
interface_wifi_working = true;
display_clear();
display_menu_headline(interface_get_label_text(&interface_text_headline_wifi), true, 0);
display_text_line_column(interface_get_label_text(&interface_text_wifi_waiting), 4, 1, false);
ena_eke_proxy_pause();
memset(ap_info, 0, sizeof(ap_info));
ap_count = 0;
ap_index = 0;
ap_selected = 0;
ena_eke_proxy_pause();
display_clear();
display_menu_headline(interface_get_label_text(&interface_text_headline_wifi), true, 0);
display_text_line_column(interface_get_label_text(&interface_text_wifi_scanning), 4, 1, false);
wifi_controller_scan(ap_info, &ap_count, interface_wifi_display);
@ -194,8 +201,11 @@ void interface_wifi_reconnect(void)
{
if (!interface_wifi_working)
{
display_clear();
display_menu_headline(interface_get_label_text(&interface_text_headline_wifi), true, 0);
display_text_line_column(interface_get_label_text(&interface_text_wifi_connecting), 4, 1, false);
interface_wifi_working = true;
wifi_controller_reconnect(NULL);
wifi_controller_reconnect(&interface_wifi_set);
interface_wifi_working = false;
}
}

View File

@ -98,7 +98,9 @@ interface_label_t interface_text_report_pending;
interface_label_t interface_text_report_success;
interface_label_t interface_text_report_fail;
interface_label_t interface_text_wifi_waiting;
interface_label_t interface_text_wifi_scanning;
interface_label_t interface_text_wifi_connecting;
interface_label_t interface_text_wifi_nothing;
interface_label_t interface_text_data_del[6];

View File

@ -34,13 +34,17 @@
#include "sdkconfig.h"
#ifdef CONFIG_ENA_INTERFACE_CUSTOM
#include "button-input.h"
#include "custom-input.h"
#endif
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
#include "m5-input.h"
#endif
#ifdef CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND
#include "ttgo-input.h"
#endif
void time_sync_notification_cb(struct timeval *tv)
{
time_t time = (time_t)tv->tv_sec;
@ -88,15 +92,19 @@ void app_main(void)
// start with main interface
interface_main_start();
// start button input
// start input
#if defined(CONFIG_ENA_INTERFACE_CUSTOM)
button_input_start();
custom_input_start();
#endif
#if defined(CONFIG_ENA_INTERFACE_M5STICKC) || defined(CONFIG_ENA_INTERFACE_M5STICKC_PLUS)
m5_input_start();
#endif
#if defined(CONFIG_ENA_INTERFACE_TTGO_T_WRISTBAND)
ttgo_input_start();
#endif
wifi_controller_reconnect(NULL);
while (1)