put pin mode config into hardwarerevX class along with some other hardware things. Still lots of work to pull everything into the HAL.

Change-Id: If3cacc43d43670b0ff2233140b1cff66a4aeb48d
This commit is contained in:
Matthew Colvin 2023-07-28 16:32:07 -05:00
parent 8af4b276cf
commit dab062008f
7 changed files with 259 additions and 212 deletions

View file

@ -17,9 +17,8 @@ public:
virtual void MQTTPublish(const char *topic, const char *payload) = 0; virtual void MQTTPublish(const char *topic, const char *payload) = 0;
virtual void initLVGL(display_flush_cb aDisplayFlushCb, virtual void init() = 0;
touch_pad_read aTouchPadReadCb) = 0;
virtual lv_coord_t getScreenWidth() = 0; protected:
virtual lv_coord_t getScreenHeight() = 0; virtual void initLVGL() = 0;
}; };

View file

@ -8,10 +8,6 @@
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#define screenWidth 240
#define screenHeight 320
/// @brief Singleton to allow UI code to live separately from the Initialization /// @brief Singleton to allow UI code to live separately from the Initialization
/// of resources. /// of resources.
class OmoteUI { class OmoteUI {

View file

@ -2,7 +2,17 @@
#define IS_SIMULATOR false #define IS_SIMULATOR false
#define ENABLE_WIFI // Comment out to disable connected features // Comment out to disable connected features
#define ENABLE_WIFI
// time until device enters sleep mode in milliseconds
#define SLEEP_TIMEOUT 20000
// motion above threshold keeps device awake
#define MOTION_THRESHOLD 50
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 360
// Pin assignment // Pin assignment
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------

View file

@ -0,0 +1,158 @@
#include "HardwareRevX.hpp"
std::shared_ptr<HardwareRevX> HardwareRevX::mInstance = nullptr;
void HardwareRevX::initIO() {
// Button Pin Definition
pinMode(SW_1, OUTPUT);
pinMode(SW_2, OUTPUT);
pinMode(SW_3, OUTPUT);
pinMode(SW_4, OUTPUT);
pinMode(SW_5, OUTPUT);
pinMode(SW_A, INPUT);
pinMode(SW_B, INPUT);
pinMode(SW_C, INPUT);
pinMode(SW_D, INPUT);
pinMode(SW_E, INPUT);
// Power Pin Definition
pinMode(CRG_STAT, INPUT_PULLUP);
pinMode(ADC_BAT, INPUT);
// IR Pin Definition
pinMode(IR_RX, INPUT);
pinMode(IR_LED, OUTPUT);
pinMode(IR_VCC, OUTPUT);
digitalWrite(IR_LED, HIGH); // HIGH off - LOW on
digitalWrite(IR_VCC, LOW); // HIGH on - LOW off
// LCD Pin Definition
pinMode(LCD_EN, OUTPUT);
digitalWrite(LCD_EN, HIGH);
pinMode(LCD_BL, OUTPUT);
digitalWrite(LCD_BL, HIGH);
// Other Pin Definition
pinMode(ACC_INT, INPUT);
pinMode(USER_LED, OUTPUT);
digitalWrite(USER_LED, LOW);
// Release GPIO hold in case we are coming out of standby
gpio_hold_dis((gpio_num_t)SW_1);
gpio_hold_dis((gpio_num_t)SW_2);
gpio_hold_dis((gpio_num_t)SW_3);
gpio_hold_dis((gpio_num_t)SW_4);
gpio_hold_dis((gpio_num_t)SW_5);
gpio_hold_dis((gpio_num_t)LCD_EN);
gpio_hold_dis((gpio_num_t)LCD_BL);
gpio_deep_sleep_hold_dis();
}
void HardwareRevX::init() {
// Make sure ESP32 is running at full speed
setCpuFrequencyMhz(240);
initIO();
// Setup TFT
tft.init();
tft.initDMA();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setSwapBytes(true);
initLVGL();
}
void HardwareRevX::initLVGL() {
{
lv_init();
lv_disp_draw_buf_init(&mdraw_buf, mbufA, mbufB,
SCREEN_WIDTH * SCREEN_HEIGHT / 10);
// Initialize the display driver
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = SCREEN_WIDTH;
disp_drv.ver_res = SCREEN_HEIGHT;
disp_drv.flush_cb = &HardwareRevX::displayFlushImpl;
disp_drv.draw_buf = &mdraw_buf;
lv_disp_drv_register(&disp_drv);
// Initialize the touchscreen driver
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = &HardwareRevX::touchPadReadImpl;
lv_indev_drv_register(&indev_drv);
}
}
void HardwareRevX::displayFlush(lv_disp_drv_t *disp, const lv_area_t *area,
lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushPixelsDMA((uint16_t *)&color_p->full, w * h);
tft.endWrite();
lv_disp_flush_ready(disp);
}
void HardwareRevX::touchPadRead(lv_indev_drv_t *indev_driver,
lv_indev_data_t *data) {
// int16_t touchX, touchY;
touchPoint = touch.getPoint();
int16_t touchX = touchPoint.x;
int16_t touchY = touchPoint.y;
bool touched = false;
if ((touchX > 0) || (touchY > 0)) {
touched = true;
standbyTimer = SLEEP_TIMEOUT;
}
if (!touched) {
data->state = LV_INDEV_STATE_REL;
} else {
data->state = LV_INDEV_STATE_PR;
// Set the coordinates
data->point.x = SCREEN_WIDTH - touchX;
data->point.y = SCREEN_HEIGHT - touchY;
// Serial.print( "touchpoint: x" );
// Serial.print( touchX );
// Serial.print( " y" );
// Serial.println( touchY );
// tft.drawFastHLine(0, screenHeight - touchY, screenWidth, TFT_RED);
// tft.drawFastVLine(screenWidth - touchX, 0, screenHeight, TFT_RED);
}
}
void HardwareRevX::activityDetection() {
static int accXold;
static int accYold;
static int accZold;
int accX = IMU.readFloatAccelX() * 1000;
int accY = IMU.readFloatAccelY() * 1000;
int accZ = IMU.readFloatAccelZ() * 1000;
// determine motion value as da/dt
motion = (abs(accXold - accX) + abs(accYold - accY) + abs(accZold - accZ));
// Calculate time to standby
standbyTimer -= 100;
if (standbyTimer < 0)
standbyTimer = 0;
// If the motion exceeds the threshold, the standbyTimer is reset
if (motion > MOTION_THRESHOLD)
standbyTimer = SLEEP_TIMEOUT;
// Store the current acceleration and time
accXold = accX;
accYold = accY;
accZold = accZ;
}

View file

@ -1,14 +1,24 @@
#pragma once #pragma once
#include "SparkFunLIS3DH.h"
#include "HardwareAbstractionInterface.h" #include "HardwareAbstractionInterface.h"
#include "lvgl.h" #include "lvgl.h"
#include <Adafruit_FT6206.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <functional> #include <functional>
#include <memory>
#define screenWidth 240 #include "omoteconfig.h"
#define screenHeight 320
class HardwareRevX : public HardwareAbstractionInterface { class HardwareRevX : public HardwareAbstractionInterface {
public: public:
static std::shared_ptr<HardwareRevX> getInstance() {
if (!mInstance) {
mInstance = std::make_shared<HardwareRevX>();
}
return mInstance;
}
HardwareRevX() : HardwareAbstractionInterface(){}; HardwareRevX() : HardwareAbstractionInterface(){};
virtual void debugPrint(std::string aDebugMessage) override {} virtual void debugPrint(std::string aDebugMessage) override {}
@ -17,34 +27,48 @@ public:
virtual void MQTTPublish(const char *topic, const char *payload) override {} virtual void MQTTPublish(const char *topic, const char *payload) override {}
virtual void initLVGL(display_flush_cb aDisplayFlushCb, virtual void init();
touch_pad_read aTouchPadReadCb) {
lv_init();
lv_disp_draw_buf_init(&mdraw_buf, mbufA, mbufB, void handleLoop();
screenWidth * screenHeight / 10);
// Initialize the display driver public:
static lv_disp_drv_t disp_drv; virtual void initLVGL();
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = aDisplayFlushCb;
disp_drv.draw_buf = &mdraw_buf;
lv_disp_drv_register(&disp_drv);
// Initialize the touchscreen driver void displayFlush(lv_disp_drv_t *disp, const lv_area_t *area,
static lv_indev_drv_t indev_drv; lv_color_t *color_p);
lv_indev_drv_init(&indev_drv); void touchPadRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = aTouchPadReadCb; void activityDetection();
lv_indev_drv_register(&indev_drv);
void initIO();
public:
static void displayFlushImpl(lv_disp_drv_t *disp, const lv_area_t *area,
lv_color_t *color_p) {
mInstance->displayFlush(disp, area, color_p);
}
static void touchPadReadImpl(lv_indev_drv_t *indev_driver,
lv_indev_data_t *data) {
mInstance->touchPadRead(indev_driver, data);
} }
virtual lv_coord_t getScreenWidth() { return screenWidth; } int standbyTimer = SLEEP_TIMEOUT;
virtual lv_coord_t getScreenHeight() { return screenHeight; }
Adafruit_FT6206 touch = Adafruit_FT6206();
TS_Point touchPoint;
TS_Point oldPoint;
TFT_eSPI tft = TFT_eSPI();
// IMU Motion Detection
LIS3DH IMU = LIS3DH(I2C_MODE, 0x19); // Default constructor is I2C, addr 0x19.
bool wakeupByIMUEnabled = true;
int motion = 0;
// LVGL Screen Buffers
lv_disp_draw_buf_t mdraw_buf; lv_disp_draw_buf_t mdraw_buf;
lv_color_t mbufA[screenWidth * screenHeight / 10]; lv_color_t mbufA[SCREEN_WIDTH * SCREEN_HEIGHT / 10];
lv_color_t mbufB[screenWidth * screenHeight / 10]; lv_color_t mbufB[SCREEN_WIDTH * SCREEN_HEIGHT / 10];
static std::shared_ptr<HardwareRevX> mInstance;
}; };

View file

@ -95,7 +95,7 @@ void OmoteUI::layout_UI() {
lv_tabview_create(lv_scr_act(), LV_DIR_TOP, lv_tabview_create(lv_scr_act(), LV_DIR_TOP,
0); // Hide tab labels by setting their height to 0 0); // Hide tab labels by setting their height to 0
lv_obj_set_style_bg_color(tabview, lv_color_black(), LV_PART_MAIN); lv_obj_set_style_bg_color(tabview, lv_color_black(), LV_PART_MAIN);
lv_obj_set_size(tabview, mHardware->getScreenWidth(), lv_obj_set_size(tabview, SCREEN_WIDTH,
270); // 270 = screenHeight(320) - panel(30) - statusbar(20) 270); // 270 = screenHeight(320) - panel(30) - statusbar(20)
lv_obj_align(tabview, LV_ALIGN_TOP_MID, 0, 20); lv_obj_align(tabview, LV_ALIGN_TOP_MID, 0, 20);
@ -465,7 +465,7 @@ void OmoteUI::layout_UI() {
panel = lv_obj_create(lv_scr_act()); panel = lv_obj_create(lv_scr_act());
lv_obj_clear_flag( lv_obj_clear_flag(
panel, LV_OBJ_FLAG_CLICKABLE); // this indicator will not be clickable panel, LV_OBJ_FLAG_CLICKABLE); // this indicator will not be clickable
lv_obj_set_size(panel, mHardware->getScreenWidth(), 30); lv_obj_set_size(panel, SCREEN_WIDTH, 30);
lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW); lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW);
lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0); lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0);
lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF);

View file

@ -1,11 +1,9 @@
// OMOTE firmware for ESP32 // OMOTE firmware for ESP32
// 2023 Maximilian Kern // 2023 Maximilian Kern
#include "SparkFunLIS3DH.h"
#include "WiFi.h" #include "WiFi.h"
#include "Wire.h" #include "Wire.h"
#include "driver/ledc.h" #include "driver/ledc.h"
#include <Adafruit_FT6206.h>
#include <IRrecv.h> #include <IRrecv.h>
#include <IRremoteESP8266.h> #include <IRremoteESP8266.h>
#include <IRsend.h> #include <IRsend.h>
@ -13,37 +11,20 @@
#include <Keypad.h> // modified for inverted logic #include <Keypad.h> // modified for inverted logic
#include <Preferences.h> #include <Preferences.h>
#include <PubSubClient.h> #include <PubSubClient.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <lvgl.h> #include <lvgl.h>
#include "HardwareRevX.hpp" #include "HardwareRevX.hpp"
#include "OmoteUI/OmoteUI.hpp" #include "OmoteUI/OmoteUI.hpp"
#include "omoteconfig.h" #include "omoteconfig.h"
// Variables and Object declarations std::shared_ptr<HardwareRevX> hal = nullptr;
// ------------------------------------------------------------------------------------------------------
// Battery declares
int battery_voltage = 0; int battery_voltage = 0;
int battery_percentage = 100; int battery_percentage = 100;
bool battery_ischarging = false; bool battery_ischarging = false;
// IMU declarations
int motion = 0;
#define SLEEP_TIMEOUT \
20000 // time until device enters sleep mode in milliseconds
#define MOTION_THRESHOLD 50 // motion above threshold keeps device awake
int standbyTimer = SLEEP_TIMEOUT;
bool wakeupByIMUEnabled = true;
LIS3DH IMU(I2C_MODE, 0x19); // Default constructor is I2C, addr 0x19.
// LCD declarations // LCD declarations
TFT_eSPI tft = TFT_eSPI();
#define screenWidth 240
#define screenHeight 320
Adafruit_FT6206 touch = Adafruit_FT6206();
TS_Point touchPoint;
TS_Point oldPoint;
int backlight_brightness = 255; int backlight_brightness = 255;
// LVGL declarations // LVGL declarations
@ -109,74 +90,6 @@ PubSubClient client(espClient);
// Helper Functions // Helper Functions
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
// Display flushing
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area,
lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushPixelsDMA((uint16_t *)&color_p->full, w * h);
tft.endWrite();
lv_disp_flush_ready(disp);
}
// Read the touchpad
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
// int16_t touchX, touchY;
touchPoint = touch.getPoint();
int16_t touchX = touchPoint.x;
int16_t touchY = touchPoint.y;
bool touched = false;
if ((touchX > 0) || (touchY > 0)) {
touched = true;
standbyTimer = SLEEP_TIMEOUT;
}
if (!touched) {
data->state = LV_INDEV_STATE_REL;
} else {
data->state = LV_INDEV_STATE_PR;
// Set the coordinates
data->point.x = screenWidth - touchX;
data->point.y = screenHeight - touchY;
// Serial.print( "touchpoint: x" );
// Serial.print( touchX );
// Serial.print( " y" );
// Serial.println( touchY );
// tft.drawFastHLine(0, screenHeight - touchY, screenWidth, TFT_RED);
// tft.drawFastVLine(screenWidth - touchX, 0, screenHeight, TFT_RED);
}
}
void activityDetection() {
static int accXold;
static int accYold;
static int accZold;
int accX = IMU.readFloatAccelX() * 1000;
int accY = IMU.readFloatAccelY() * 1000;
int accZ = IMU.readFloatAccelZ() * 1000;
// determine motion value as da/dt
motion = (abs(accXold - accX) + abs(accYold - accY) + abs(accZold - accZ));
// Calculate time to standby
standbyTimer -= 100;
if (standbyTimer < 0)
standbyTimer = 0;
// If the motion exceeds the threshold, the standbyTimer is reset
if (motion > MOTION_THRESHOLD)
standbyTimer = SLEEP_TIMEOUT;
// Store the current acceleration and time
accXold = accX;
accYold = accY;
accZold = accZ;
}
void configIMUInterrupts() { void configIMUInterrupts() {
uint8_t dataToWrite = 0; uint8_t dataToWrite = 0;
@ -191,31 +104,31 @@ void configIMUInterrupts() {
// dataToWrite |= 0x04;//Y low // dataToWrite |= 0x04;//Y low
dataToWrite |= 0x02; // X high dataToWrite |= 0x02; // X high
// dataToWrite |= 0x01;//X low // dataToWrite |= 0x01;//X low
if (wakeupByIMUEnabled) if (hal->wakeupByIMUEnabled)
IMU.writeRegister(LIS3DH_INT1_CFG, 0b00101010); hal->IMU.writeRegister(LIS3DH_INT1_CFG, 0b00101010);
else else
IMU.writeRegister(LIS3DH_INT1_CFG, 0b00000000); hal->IMU.writeRegister(LIS3DH_INT1_CFG, 0b00000000);
// LIS3DH_INT1_THS // LIS3DH_INT1_THS
dataToWrite = 0; dataToWrite = 0;
// Provide 7 bit value, 0x7F always equals max range by accelRange setting // Provide 7 bit value, 0x7F always equals max range by accelRange setting
dataToWrite |= 0x45; dataToWrite |= 0x45;
IMU.writeRegister(LIS3DH_INT1_THS, dataToWrite); hal->IMU.writeRegister(LIS3DH_INT1_THS, dataToWrite);
// LIS3DH_INT1_DURATION // LIS3DH_INT1_DURATION
dataToWrite = 0; dataToWrite = 0;
// minimum duration of the interrupt // minimum duration of the interrupt
// LSB equals 1/(sample rate) // LSB equals 1/(sample rate)
dataToWrite |= 0x00; // 1 * 1/50 s = 20ms dataToWrite |= 0x00; // 1 * 1/50 s = 20ms
IMU.writeRegister(LIS3DH_INT1_DURATION, dataToWrite); hal->IMU.writeRegister(LIS3DH_INT1_DURATION, dataToWrite);
// LIS3DH_CTRL_REG5 // LIS3DH_CTRL_REG5
// Int1 latch interrupt and 4D on int1 (preserve fifo en) // Int1 latch interrupt and 4D on int1 (preserve fifo en)
IMU.readRegister(&dataToWrite, LIS3DH_CTRL_REG5); hal->IMU.readRegister(&dataToWrite, LIS3DH_CTRL_REG5);
dataToWrite &= 0xF3; // Clear bits of interest dataToWrite &= 0xF3; // Clear bits of interest
dataToWrite |= 0x08; // Latch interrupt (Cleared by reading int1_src) dataToWrite |= 0x08; // Latch interrupt (Cleared by reading int1_src)
// dataToWrite |= 0x04; //Pipe 4D detection from 6D recognition to int1? // dataToWrite |= 0x04; //Pipe 4D detection from 6D recognition to int1?
IMU.writeRegister(LIS3DH_CTRL_REG5, dataToWrite); hal->IMU.writeRegister(LIS3DH_CTRL_REG5, dataToWrite);
// LIS3DH_CTRL_REG3 // LIS3DH_CTRL_REG3
// Choose source for pin 1 // Choose source for pin 1
@ -226,24 +139,25 @@ void configIMUInterrupts() {
// dataToWrite |= 0x10; //Data ready // dataToWrite |= 0x10; //Data ready
// dataToWrite |= 0x04; //FIFO watermark // dataToWrite |= 0x04; //FIFO watermark
// dataToWrite |= 0x02; //FIFO overrun // dataToWrite |= 0x02; //FIFO overrun
IMU.writeRegister(LIS3DH_CTRL_REG3, dataToWrite); hal->IMU.writeRegister(LIS3DH_CTRL_REG3, dataToWrite);
} }
// Enter Sleep Mode // Enter Sleep Mode
void enterSleep() { void enterSleep() {
// Save settings to internal flash memory // Save settings to internal flash memory
preferences.putBool("wkpByIMU", wakeupByIMUEnabled); preferences.putBool("wkpByIMU", hal->wakeupByIMUEnabled);
preferences.putUChar("blBrightness", backlight_brightness); preferences.putUChar("blBrightness", backlight_brightness);
preferences.putUChar("currentDevice", currentDevice); preferences.putUChar("currentDevice", currentDevice);
if (!preferences.getBool("alreadySetUp")) if (!preferences.getBool("alreadySetUp"))
preferences.putBool("alreadySetUp", true); preferences.putBool("alreadySetUp", true);
preferences.end(); preferences.end();
// Configure IMU // Configure hal->IMU
uint8_t intDataRead; uint8_t intDataRead;
IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // clear interrupt hal->IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // clear interrupt
configIMUInterrupts(); configIMUInterrupts();
IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // really clear interrupt hal->IMU.readRegister(&intDataRead,
LIS3DH_INT1_SRC); // really clear interrupt
#ifdef ENABLE_WIFI #ifdef ENABLE_WIFI
// Power down modem // Power down modem
@ -315,8 +229,6 @@ void WiFiEvent(WiFiEvent_t event) {
void setup() { void setup() {
setCpuFrequencyMhz(240); // Make sure ESP32 is running at full speed
// Find out wakeup cause // Find out wakeup cause
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT1) { if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT1) {
if (log(esp_sleep_get_ext1_wakeup_status()) / log(2) == 13) if (log(esp_sleep_get_ext1_wakeup_status()) / log(2) == 13)
@ -327,52 +239,6 @@ void setup() {
wakeup_reason = WAKEUP_BY_RESET; wakeup_reason = WAKEUP_BY_RESET;
} }
// --- IO Initialization ---
// Button Pin Definition
pinMode(SW_1, OUTPUT);
pinMode(SW_2, OUTPUT);
pinMode(SW_3, OUTPUT);
pinMode(SW_4, OUTPUT);
pinMode(SW_5, OUTPUT);
pinMode(SW_A, INPUT);
pinMode(SW_B, INPUT);
pinMode(SW_C, INPUT);
pinMode(SW_D, INPUT);
pinMode(SW_E, INPUT);
// Power Pin Definition
pinMode(CRG_STAT, INPUT_PULLUP);
pinMode(ADC_BAT, INPUT);
// IR Pin Definition
pinMode(IR_RX, INPUT);
pinMode(IR_LED, OUTPUT);
pinMode(IR_VCC, OUTPUT);
digitalWrite(IR_LED, HIGH); // HIGH off - LOW on
digitalWrite(IR_VCC, LOW); // HIGH on - LOW off
// LCD Pin Definition
pinMode(LCD_EN, OUTPUT);
digitalWrite(LCD_EN, HIGH);
pinMode(LCD_BL, OUTPUT);
digitalWrite(LCD_BL, HIGH);
// Other Pin Definition
pinMode(ACC_INT, INPUT);
pinMode(USER_LED, OUTPUT);
digitalWrite(USER_LED, LOW);
// Release GPIO hold in case we are coming out of standby
gpio_hold_dis((gpio_num_t)SW_1);
gpio_hold_dis((gpio_num_t)SW_2);
gpio_hold_dis((gpio_num_t)SW_3);
gpio_hold_dis((gpio_num_t)SW_4);
gpio_hold_dis((gpio_num_t)SW_5);
gpio_hold_dis((gpio_num_t)LCD_EN);
gpio_hold_dis((gpio_num_t)LCD_BL);
gpio_deep_sleep_hold_dis();
// Configure the backlight PWM // Configure the backlight PWM
// Manual setup because ledcSetup() briefly turns on the backlight // Manual setup because ledcSetup() briefly turns on the backlight
ledc_channel_config_t ledc_channel_left; ledc_channel_config_t ledc_channel_left;
@ -400,13 +266,11 @@ void setup() {
// Restore settings from internal flash memory // Restore settings from internal flash memory
preferences.begin("settings", false); preferences.begin("settings", false);
if (preferences.getBool("alreadySetUp")) { if (preferences.getBool("alreadySetUp")) {
wakeupByIMUEnabled = preferences.getBool("wkpByIMU"); hal->wakeupByIMUEnabled = preferences.getBool("wkpByIMU");
backlight_brightness = preferences.getUChar("blBrightness"); backlight_brightness = preferences.getUChar("blBrightness");
currentDevice = preferences.getUChar("currentDevice"); currentDevice = preferences.getUChar("currentDevice");
} }
// Setup TFT
// Slowly charge the VSW voltage to prevent a brownout // Slowly charge the VSW voltage to prevent a brownout
// Workaround for hardware rev 1! // Workaround for hardware rev 1!
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
@ -416,23 +280,18 @@ void setup() {
} }
delay(100); // Wait for the LCD driver to power on delay(100); // Wait for the LCD driver to power on
tft.init();
tft.initDMA();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setSwapBytes(true);
// Setup touchscreen // Setup touchscreen
Wire.begin(SDA, SCL, Wire.begin(SDA, SCL,
400000); // Configure i2c pins and set frequency to 400kHz 400000); // Configure i2c pins and set frequency to 400kHz
touch.begin(128); // Initialize touchscreen and set sensitivity threshold
auto hal = std::make_shared<HardwareRevX>(); hal = HardwareRevX::getInstance();
hal->initLVGL(my_disp_flush, my_touchpad_read); hal->init();
auto ui = std::make_shared<OmoteUI>(hal); auto ui = OmoteUI::getInstance(hal);
ui->layout_UI(); ui->layout_UI();
hal->touch.begin(128); // Initialize touchscreen and set sensitivity threshold
#ifdef ENABLE_WIFI #ifdef ENABLE_WIFI
// Setup WiFi // Setup WiFi
WiFi.setHostname("OMOTE"); // define hostname WiFi.setHostname("OMOTE"); // define hostname
@ -441,18 +300,19 @@ void setup() {
WiFi.setSleep(true); WiFi.setSleep(true);
#endif #endif
// Setup IMU // Setup hal->IMU
IMU.settings.accelSampleRate = hal->IMU.settings.accelSampleRate =
50; // Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz 50; // Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz
IMU.settings.accelRange = 2; // Max G force readable. Can be: 2, 4, 8, 16 hal->IMU.settings.accelRange =
IMU.settings.adcEnabled = 0; 2; // Max G force readable. Can be: 2, 4, 8, 16
IMU.settings.tempEnabled = 0; hal->IMU.settings.adcEnabled = 0;
IMU.settings.xAccelEnabled = 1; hal->IMU.settings.tempEnabled = 0;
IMU.settings.yAccelEnabled = 1; hal->IMU.settings.xAccelEnabled = 1;
IMU.settings.zAccelEnabled = 1; hal->IMU.settings.yAccelEnabled = 1;
IMU.begin(); hal->IMU.settings.zAccelEnabled = 1;
hal->IMU.begin();
uint8_t intDataRead; uint8_t intDataRead;
IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // clear interrupt hal->IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // clear interrupt
// Setup IR // Setup IR
IrSender.begin(); IrSender.begin();
@ -477,7 +337,7 @@ void loop() {
fadeInTimer + backlight_brightness) { // Fade in the backlight brightness fadeInTimer + backlight_brightness) { // Fade in the backlight brightness
ledcWrite(5, millis() - fadeInTimer); ledcWrite(5, millis() - fadeInTimer);
} else { // Dim Backlight before entering standby } else { // Dim Backlight before entering standby
if (standbyTimer < 2000) if (hal->standbyTimer < 2000)
ledcWrite(5, 85); // Backlight dim ledcWrite(5, 85); // Backlight dim
else else
ledcWrite(5, backlight_brightness); // Backlight on ledcWrite(5, backlight_brightness); // Backlight on
@ -492,8 +352,8 @@ void loop() {
// Refresh IMU data at 10Hz // Refresh IMU data at 10Hz
static unsigned long IMUTaskTimer = millis(); static unsigned long IMUTaskTimer = millis();
if (millis() - IMUTaskTimer >= 100) { if (millis() - IMUTaskTimer >= 100) {
activityDetection(); hal->activityDetection();
if (standbyTimer == 0) { if (hal->standbyTimer == 0) {
Serial.println("Entering Sleep Mode. Goodbye."); Serial.println("Entering Sleep Mode. Goodbye.");
enterSleep(); enterSleep();
} }
@ -536,7 +396,7 @@ void loop() {
i++) { // Handle multiple keys (Not really necessary in this case) i++) { // Handle multiple keys (Not really necessary in this case)
if (customKeypad.key[i].kstate == PRESSED || if (customKeypad.key[i].kstate == PRESSED ||
customKeypad.key[i].kstate == HOLD) { customKeypad.key[i].kstate == HOLD) {
standbyTimer = hal->standbyTimer =
SLEEP_TIMEOUT; // Reset the sleep timer when a button is pressed SLEEP_TIMEOUT; // Reset the sleep timer when a button is pressed
int keyCode = customKeypad.key[i].kcode; int keyCode = customKeypad.key[i].kcode;
Serial.println(customKeypad.key[i].kchar); Serial.println(customKeypad.key[i].kchar);