Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: separates display and touch modules #16

Merged
merged 9 commits into from
Jun 1, 2024
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
PIN_KEY: "test"
WIFI_SSID: "test"
WIFI_PASSWORD: "test"
TOUCH_FORCE_CALIBRATION: 1
run: pio run

- name: Create build
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export MQTT_PORT="1883"
export MQTT_SERVER="192.168.0.1"
export MQTT_USERNAME="test"
export MQTT_PASSWORD="test"
export TOUCH_FORCE_CALIBRATION=0
```

> **INFO**: Wi-Fi variables are required because this project uses the NTP server to set its time.
Expand All @@ -129,8 +130,10 @@ export MQTT_PASSWORD="test"

> **INFO**: `MQTT` env variables are optional. To enable the board to receive secrets from an mqtt broker, `MQTT_SERVER` and `MQTT_PORT` must be specified.

3. run `platformio run --environment esp32-cyd` to build the application
4. upload the code to your board using `platformio run --target upload --upload-port ${DEVICE_PATH} --target monitor --environment esp32-cyd`.
> **INFO**: `TOUCH_FORCE_CALIBRATION` env variable is optional, and it can be either `0` or `1`. If its value was set to `1` before a build, the touch calibration flow will run during boot as shown in the following picture: <img src="./images/touch-calibration-flow.png">

1. run `platformio run --environment esp32-cyd` to build the application
2. upload the code to your board using `platformio run --target upload --upload-port ${DEVICE_PATH} --target monitor --environment esp32-cyd`.

> **WARNING**: Remember to substitue `${DEVICE_PATH}` with the value you got in step 1.

Expand Down Expand Up @@ -223,7 +226,6 @@ When the ESP32-MFA-Authenticator extension is enabled, a new button called "regi

> **INFO:** the above steps are summarizing my initial plan.


### 🔜 Group TOTP Codes

I work with a customer that has multiple AWS accounts, and each has its own MFA Virtual device. To help me to easily find the MFA TOTP codes for a group of accounts that belongs to the same customer, I decided to create a way to group TOTP codes together on its own separate view. Each group of TOTP secrets will result in a page on the TOTP Screen. The User can select the page by swiping to the right or left. With this feature, Users will be able to manage multiple virtual MFA devices for multiple customers using the same device. To further secure TOTPs for a group, the User will be able to set a PIN code for a group. If PIN code is set for that group, a PIN Screen appears before the group of TOTPs can be rendered. There will also still exist the Global PIN code, which protects all TOTPs.
Expand Down
Binary file added images/touch-calibration-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 8 additions & 7 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ framework = arduino
monitor_speed = 115200
lib_deps =
https://github.com/lvgl/lvgl.git#v8.3.11
https://github.com/ddxfish/XPT2046_Bitbang_Arduino_Library.git#e8da3dc41f1bd47510e6e61c93463fa1f8fe5586
https://github.com/ddxfish/XPT2046_Bitbang_Arduino_Library.git#7b20b1aaaa8fa151bb0f3f8276b806647094c00a
https://github.com/Bodmer/TFT_eSPI.git#v2.5.33
https://github.com/adafruit/SdFat.git#2.2.3
https://github.com/adafruit/Adafruit_NeoPixel#v1.1.2
Expand All @@ -40,15 +40,14 @@ build_flags =
-D MQTT_PASSWORD=\"${sysenv.MQTT_PASSWORD}\"
-D PIN_HASH=\"${sysenv.PIN_HASH}\"
-D PIN_KEY=\"${sysenv.PIN_KEY}\"
-D TOUCH_FORCE_CALIBRATION=${sysenv.TOUCH_FORCE_CALIBRATION}
-D DISPLAY_WIDTH=320
-D DISPLAY_HEIGHT=240
-D USER_SETUP_LOADED=1
-D TFT_RGB_ORDER=TFT_RGB
-D LVGL_DISPLAY_WIDTH=320
-D LVGL_DISPLAY_HEIGHT=240
-D ILI9341_DRIVER=1
-D LCD_WIDTH=320
-D LCD_HEIGHT=240
-D TFT_WIDTH=320
-D TFT_HEIGHT=240
-D TFT_WIDTH=DISPLAY_WIDTH
-D TFT_HEIGHT=DISPLAY_HEIGHT
-D TFT_MISO=19
-D TFT_MOSI=13
-D TFT_SCLK=14
Expand All @@ -65,5 +64,7 @@ build_flags =
-D TOUCH_CS=33
-D TF_CS=5
-D ENABLE_FAT12_SUPPORT=1
-D LVGL_DISPLAY_WIDTH=DISPLAY_WIDTH
-D LVGL_DISPLAY_HEIGHT=DISPLAY_HEIGHT
-D LV_CONF_PATH="${PROJECT_DIR}/lv_conf.h"
-I include ;
20 changes: 20 additions & 0 deletions src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,23 @@
// UI
#define PIN_SCREEN_NAME "pin"
#define TOTP_SCREEN_NAME "totp"

// TOUCH
#define TOUCH_DOUBLE_TOUCH_INTERVAL 300
#define TOUCH_X_MIN 132
#define TOUCH_X_MAX 1869
#define TOUCH_Y_MIN 132
#define TOUCH_Y_MAX 1784

#ifndef TOUCH_FORCE_CALIBRATION
#define TOUCH_FORCE_CALIBRATION 0
#endif

// DISPLAY
#define LVGL_TICK_PERIOD_MS 1
#define LVGL_BUFFER_PIXELS (TFT_WIDTH * TFT_HEIGHT / 4)
#define LVGL_BUFFER_MALLOC_FLAGS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#define PWM_CHANNEL_BCKL (SOC_LEDC_CHANNEL_NUM - 1)
#define PWM_FREQ_BCKL 400
#define PWM_BITS_BCKL 8
#define PWM_MAX_BCKL ((1 << PWM_BITS_BCKL) - 1)
64 changes: 64 additions & 0 deletions src/display.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include <string.h>
#include "constants.h"

TFT_eSPI tft = TFT_eSPI();
static lv_disp_drv_t disp_drv;

void on_display_change(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);

for (int y = area->y1; y <= area->y2; y++)
{
for (int x = area->x1; x <= area->x2; x++)
{
uint32_t buffer_pos = (y - area->y1) * w + (x - area->x1);
uint16_t color = color_p[buffer_pos].full;
tft.writeColor(color, 1);
}
}

tft.endWrite();
lv_disp_flush_ready(disp);
}

void init_display()
{
pinMode(TFT_BCKL, OUTPUT);
digitalWrite(TFT_BCKL, HIGH);

Serial.println("Backlight enabled.");

lv_init();
Serial.println("LVGL initialized.");

tft.begin();
tft.setSwapBytes(true);
Serial.println("TFT initialized.");
tft.setRotation(2); /* Landscape orientation */
Serial.println("TFT rotation set.");

lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = DISPLAY_WIDTH;
disp_drv.ver_res = DISPLAY_HEIGHT;
disp_drv.flush_cb = on_display_change;
disp_drv.draw_buf = (lv_disp_draw_buf_t *)malloc(sizeof(lv_disp_draw_buf_t));
disp_drv.antialiasing = 1;
void *drawBuffer = heap_caps_malloc(sizeof(lv_color_t) * LVGL_BUFFER_PIXELS, LVGL_BUFFER_MALLOC_FLAGS);
lv_disp_draw_buf_init(disp_drv.draw_buf, drawBuffer, NULL, LVGL_BUFFER_PIXELS);
lv_disp_t *disp = lv_disp_drv_register(&disp_drv);
Serial.println("LVGL display driver registered.");
lv_obj_clean(lv_scr_act());

ledcSetup(PWM_CHANNEL_BCKL, PWM_FREQ_BCKL, PWM_BITS_BCKL);
ledcAttachPin(21, PWM_CHANNEL_BCKL);
ledcWrite(PWM_CHANNEL_BCKL, 0.5 * PWM_MAX_BCKL);
}
14 changes: 14 additions & 0 deletions src/display.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef LVGL_DISPLAY_H
#define LVGL_DISPLAY_H

// Includes
#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include "constants.h"

// Function declarations
void init_display();

#endif // LVGL_DISPLAY_H
12 changes: 9 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#include "mfa.hpp"
#include "totp-map.h"
#include "file.hpp"
#include "tft-touch.hpp"
#include "display.hpp"
#include "touch.hpp"
#include "wifi.hpp"
#include "mqtt.hpp"

Expand All @@ -31,10 +32,15 @@ void setup()
init_mqtt();

// SETUP SCREEN
init_display_and_touch();
init_display();

// SETUP UI
// TODO: create setup screen with steps for configuring WIFI, MQTT and calibrate touch
ui_init();

// SETUP TOUCH
// NOTE: touch comes after initializing UI because I plan to add a manual calibration screen
init_touch();
}

void loop()
Expand Down Expand Up @@ -77,5 +83,5 @@ void loop()
}
}

display_and_touch_handler();
ui_task_handler();
}
140 changes: 0 additions & 140 deletions src/tft-touch.cpp

This file was deleted.

34 changes: 0 additions & 34 deletions src/tft-touch.hpp

This file was deleted.

Loading
Loading