Implement M5Stack Cardputer + minor Tactility improvements (#331)
- Implement M5Stack Cardputer: display, SD card and keyboard - `St7789Display` now supports a "gap" configuration - `ElfApp` has improved errors
This commit is contained in:
parent
d83b98e99b
commit
62c613477a
9
.github/workflows/build-firmware.yml
vendored
9
.github/workflows/build-firmware.yml
vendored
@ -153,6 +153,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
board_id: lilygo-tlora-pager
|
board_id: lilygo-tlora-pager
|
||||||
arch: esp32s3
|
arch: esp32s3
|
||||||
|
m5stack-cardputer:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: "Build"
|
||||||
|
uses: ./.github/actions/build-firmware
|
||||||
|
with:
|
||||||
|
board_id: m5stack-cardputer
|
||||||
|
arch: esp32s3
|
||||||
m5stack-core2:
|
m5stack-core2:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@ -43,6 +43,8 @@ menu "Tactility App"
|
|||||||
bool "LilyGo T-Deck"
|
bool "LilyGo T-Deck"
|
||||||
config TT_BOARD_LILYGO_TLORA_PAGER
|
config TT_BOARD_LILYGO_TLORA_PAGER
|
||||||
bool "LilyGo T-Lora Pager"
|
bool "LilyGo T-Lora Pager"
|
||||||
|
config TT_BOARD_M5STACK_CARDPUTER
|
||||||
|
bool "M5Stack Cardputer"
|
||||||
config TT_BOARD_M5STACK_CORE2
|
config TT_BOARD_M5STACK_CORE2
|
||||||
bool "M5Stack Core2"
|
bool "M5Stack Core2"
|
||||||
config TT_BOARD_M5STACK_CORES3
|
config TT_BOARD_M5STACK_CORES3
|
||||||
|
|||||||
@ -41,6 +41,9 @@
|
|||||||
#elif (defined(CONFIG_TT_BOARD_ELECROW_CROWPANEL_BASIC_50))
|
#elif (defined(CONFIG_TT_BOARD_ELECROW_CROWPANEL_BASIC_50))
|
||||||
#define TT_BOARD_HARDWARE &crowpanel_basic_50
|
#define TT_BOARD_HARDWARE &crowpanel_basic_50
|
||||||
#include "CrowPanelBasic50.h"
|
#include "CrowPanelBasic50.h"
|
||||||
|
#elif defined(CONFIG_TT_BOARD_M5STACK_CARDPUTER)
|
||||||
|
#include "M5stackCardputer.h"
|
||||||
|
#define TT_BOARD_HARDWARE &m5stack_cardputer
|
||||||
#elif defined(CONFIG_TT_BOARD_M5STACK_CORE2)
|
#elif defined(CONFIG_TT_BOARD_M5STACK_CORE2)
|
||||||
#include "M5stackCore2.h"
|
#include "M5stackCore2.h"
|
||||||
#define TT_BOARD_HARDWARE &m5stack_core2
|
#define TT_BOARD_HARDWARE &m5stack_core2
|
||||||
|
|||||||
7
Boards/M5stackCardputer/CMakeLists.txt
Normal file
7
Boards/M5stackCardputer/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
SRCS ${SOURCE_FILES}
|
||||||
|
INCLUDE_DIRS "Source"
|
||||||
|
REQUIRES Tactility esp_lvgl_port esp_lcd ST7789 PwmBacklight driver vfs fatfs
|
||||||
|
)
|
||||||
10
Boards/M5stackCardputer/Source/InitBoot.cpp
Normal file
10
Boards/M5stackCardputer/Source/InitBoot.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <PwmBacklight.h>
|
||||||
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "Cardputer";
|
||||||
|
|
||||||
|
bool initBoot() {
|
||||||
|
TT_LOG_I(TAG, "initBoot");
|
||||||
|
|
||||||
|
return driver::pwmbacklight::init(GPIO_NUM_38, 256);
|
||||||
|
}
|
||||||
3
Boards/M5stackCardputer/Source/InitBoot.h
Normal file
3
Boards/M5stackCardputer/Source/InitBoot.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool initBoot();
|
||||||
123
Boards/M5stackCardputer/Source/M5stackCardputer.cpp
Normal file
123
Boards/M5stackCardputer/Source/M5stackCardputer.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#include "M5stackCardputer.h"
|
||||||
|
#include "InitBoot.h"
|
||||||
|
#include "devices/Display.h"
|
||||||
|
#include "devices/SdCard.h"
|
||||||
|
#include "devices/CardputerEncoder.h"
|
||||||
|
#include "devices/CardputerKeyboard.h"
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
|
|
||||||
|
#define SPI_TRANSFER_SIZE_LIMIT (LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
createSdCard(),
|
||||||
|
createDisplay(),
|
||||||
|
std::make_shared<CardputerKeyboard>(),
|
||||||
|
std::make_shared<CardputerEncoder>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration m5stack_cardputer = {
|
||||||
|
.initBoot = initBoot,
|
||||||
|
.createDevices = createDevices,
|
||||||
|
.i2c = {
|
||||||
|
// Only available on Cardputer Adv (enabling it breaks the keyboard on a Cardputer v1.1)
|
||||||
|
i2c::Configuration {
|
||||||
|
.name = "Internal",
|
||||||
|
.port = I2C_NUM_0,
|
||||||
|
.initMode = i2c::InitMode::Disabled,
|
||||||
|
.isMutable = true,
|
||||||
|
.config = (i2c_config_t) {
|
||||||
|
.mode = I2C_MODE_MASTER,
|
||||||
|
.sda_io_num = GPIO_NUM_8,
|
||||||
|
.scl_io_num = GPIO_NUM_9,
|
||||||
|
.sda_pullup_en = true,
|
||||||
|
.scl_pullup_en = true,
|
||||||
|
.master = {
|
||||||
|
.clk_speed = 400000
|
||||||
|
},
|
||||||
|
.clk_flags = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.spi {
|
||||||
|
// Display
|
||||||
|
spi::Configuration {
|
||||||
|
.device = SPI2_HOST,
|
||||||
|
.dma = SPI_DMA_CH_AUTO,
|
||||||
|
.config = {
|
||||||
|
.mosi_io_num = GPIO_NUM_35,
|
||||||
|
.miso_io_num = GPIO_NUM_NC,
|
||||||
|
.sclk_io_num = GPIO_NUM_36,
|
||||||
|
.quadwp_io_num = GPIO_NUM_NC,
|
||||||
|
.quadhd_io_num = GPIO_NUM_NC,
|
||||||
|
.data4_io_num = GPIO_NUM_NC,
|
||||||
|
.data5_io_num = GPIO_NUM_NC,
|
||||||
|
.data6_io_num = GPIO_NUM_NC,
|
||||||
|
.data7_io_num = GPIO_NUM_NC,
|
||||||
|
.data_io_default_level = false,
|
||||||
|
.max_transfer_sz = SPI_TRANSFER_SIZE_LIMIT,
|
||||||
|
.flags = 0,
|
||||||
|
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||||
|
.intr_flags = 0
|
||||||
|
},
|
||||||
|
.initMode = spi::InitMode::ByTactility,
|
||||||
|
.isMutable = false,
|
||||||
|
.lock = tt::lvgl::getSyncLock()
|
||||||
|
},
|
||||||
|
// SDCard
|
||||||
|
spi::Configuration {
|
||||||
|
.device = SPI3_HOST,
|
||||||
|
.dma = SPI_DMA_CH_AUTO,
|
||||||
|
.config = {
|
||||||
|
.mosi_io_num = GPIO_NUM_14,
|
||||||
|
.miso_io_num = GPIO_NUM_39,
|
||||||
|
.sclk_io_num = GPIO_NUM_40,
|
||||||
|
.quadwp_io_num = GPIO_NUM_NC,
|
||||||
|
.quadhd_io_num = GPIO_NUM_NC,
|
||||||
|
.data4_io_num = GPIO_NUM_NC,
|
||||||
|
.data5_io_num = GPIO_NUM_NC,
|
||||||
|
.data6_io_num = GPIO_NUM_NC,
|
||||||
|
.data7_io_num = GPIO_NUM_NC,
|
||||||
|
.data_io_default_level = false,
|
||||||
|
.max_transfer_sz = 0,
|
||||||
|
.flags = 0,
|
||||||
|
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||||
|
.intr_flags = 0
|
||||||
|
},
|
||||||
|
.initMode = spi::InitMode::ByTactility,
|
||||||
|
.isMutable = false,
|
||||||
|
.lock = nullptr
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
.uart {
|
||||||
|
uart::Configuration {
|
||||||
|
.name = "Grove",
|
||||||
|
.port = UART_NUM_1,
|
||||||
|
.rxPin = GPIO_NUM_32,
|
||||||
|
.txPin = GPIO_NUM_33,
|
||||||
|
.rtsPin = GPIO_NUM_NC,
|
||||||
|
.ctsPin = GPIO_NUM_NC,
|
||||||
|
.rxBufferSize = 1024,
|
||||||
|
.txBufferSize = 1024,
|
||||||
|
.config = {
|
||||||
|
.baud_rate = 115200,
|
||||||
|
.data_bits = UART_DATA_8_BITS,
|
||||||
|
.parity = UART_PARITY_DISABLE,
|
||||||
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||||
|
.rx_flow_ctrl_thresh = 0,
|
||||||
|
.source_clk = UART_SCLK_DEFAULT,
|
||||||
|
.flags = {
|
||||||
|
.allow_pd = 0,
|
||||||
|
.backup_before_sleep = 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
5
Boards/M5stackCardputer/Source/M5stackCardputer.h
Normal file
5
Boards/M5stackCardputer/Source/M5stackCardputer.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
|
||||||
|
extern const tt::hal::Configuration m5stack_cardputer;
|
||||||
54
Boards/M5stackCardputer/Source/devices/CardputerEncoder.cpp
Normal file
54
Boards/M5stackCardputer/Source/devices/CardputerEncoder.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "CardputerEncoder.h"
|
||||||
|
|
||||||
|
void CardputerEncoder::readCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
||||||
|
CardputerEncoder* self = static_cast<CardputerEncoder*>(lv_indev_get_user_data(indev));
|
||||||
|
|
||||||
|
self->keyboard.updateKeyList();
|
||||||
|
|
||||||
|
data->state = LV_INDEV_STATE_RELEASED;
|
||||||
|
|
||||||
|
if (self->keyboard.keyList().size() != self->lastKeyNum) {
|
||||||
|
// If key pressed
|
||||||
|
if (self->keyboard.keyList().size() != 0) {
|
||||||
|
// Update states and values
|
||||||
|
self->keyboard.updateKeysState();
|
||||||
|
if (self->keyboard.keysState().fn) {
|
||||||
|
if (self->keyboard.keysState().enter) {
|
||||||
|
data->key = LV_KEY_ENTER;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else {
|
||||||
|
for (auto& i : self->keyboard.keysState().values) {
|
||||||
|
if (i == ';') { // Up
|
||||||
|
data->enc_diff = -1;
|
||||||
|
} else if (i == '.') { // Down
|
||||||
|
data->enc_diff = 1;
|
||||||
|
}
|
||||||
|
break; // We only care about the first value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self->lastKeyNum = self->keyboard.keyList().size();
|
||||||
|
} else {
|
||||||
|
self->lastKeyNum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardputerEncoder::startLvgl(lv_display_t* display) {
|
||||||
|
keyboard.init();
|
||||||
|
|
||||||
|
lvglDevice = lv_indev_create();
|
||||||
|
lv_indev_set_type(lvglDevice, LV_INDEV_TYPE_ENCODER);
|
||||||
|
lv_indev_set_read_cb(lvglDevice, &readCallback);
|
||||||
|
lv_indev_set_display(lvglDevice, display);
|
||||||
|
lv_indev_set_user_data(lvglDevice, this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardputerEncoder::stopLvgl() {
|
||||||
|
lv_indev_delete(lvglDevice);
|
||||||
|
lvglDevice = nullptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
29
Boards/M5stackCardputer/Source/devices/CardputerEncoder.h
Normal file
29
Boards/M5stackCardputer/Source/devices/CardputerEncoder.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/encoder/EncoderDevice.h>
|
||||||
|
|
||||||
|
#include "keyboard/keyboard.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around the keyboard that uses the following buttons to simulate an encoder:
|
||||||
|
* - Up
|
||||||
|
* - Down
|
||||||
|
* - ok (fn + enter)
|
||||||
|
*/
|
||||||
|
class CardputerEncoder final : public tt::hal::encoder::EncoderDevice {
|
||||||
|
KEYBOARD::Keyboard keyboard;
|
||||||
|
int lastKeyNum = 0;
|
||||||
|
lv_indev_t* _Nullable lvglDevice = nullptr;
|
||||||
|
|
||||||
|
static void readCallback(lv_indev_t* indev, lv_indev_data_t* data);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::string getName() const override { return "Cardputer Encoder"; }
|
||||||
|
std::string getDescription() const override { return "Cardputer keyboard up/down acting as encoder"; }
|
||||||
|
|
||||||
|
bool startLvgl(lv_display_t* display) override;
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
|
lv_indev_t* _Nullable getLvglIndev() override { return lvglDevice; }
|
||||||
|
};
|
||||||
90
Boards/M5stackCardputer/Source/devices/CardputerKeyboard.cpp
Normal file
90
Boards/M5stackCardputer/Source/devices/CardputerKeyboard.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "CardputerKeyboard.h"
|
||||||
|
|
||||||
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "Keyboard";
|
||||||
|
|
||||||
|
bool CardputerKeyboard::startLvgl(lv_display_t* display) {
|
||||||
|
keyboard.init();
|
||||||
|
|
||||||
|
lvglDevice = lv_indev_create();
|
||||||
|
lv_indev_set_type(lvglDevice, LV_INDEV_TYPE_KEYPAD);
|
||||||
|
lv_indev_set_read_cb(lvglDevice, &readCallback);
|
||||||
|
lv_indev_set_display(lvglDevice, display);
|
||||||
|
lv_indev_set_user_data(lvglDevice, this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardputerKeyboard::stopLvgl() {
|
||||||
|
lv_indev_delete(lvglDevice);
|
||||||
|
lvglDevice = nullptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardputerKeyboard::readCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
||||||
|
CardputerKeyboard* self = static_cast<CardputerKeyboard*>(lv_indev_get_user_data(indev));
|
||||||
|
|
||||||
|
data->key = 0;
|
||||||
|
data->state = LV_INDEV_STATE_RELEASED;
|
||||||
|
|
||||||
|
self->keyboard.updateKeyList();
|
||||||
|
|
||||||
|
if (self->keyboard.keyList().size() != self->lastKeyNum) {
|
||||||
|
// If key pressed
|
||||||
|
if (self->keyboard.keyList().size() != 0) {
|
||||||
|
// Update states and values
|
||||||
|
self->keyboard.updateKeysState();
|
||||||
|
if (!self->keyboard.keysState().fn) {
|
||||||
|
if (self->keyboard.keysState().enter) {
|
||||||
|
data->key = LV_KEY_ENTER;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else if (self->keyboard.keysState().space) {
|
||||||
|
data->key = ' ';
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else if (self->keyboard.keysState().del) {
|
||||||
|
data->key = LV_KEY_BACKSPACE;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else {
|
||||||
|
// Normal chars
|
||||||
|
for (auto& i : self->keyboard.keysState().values) {
|
||||||
|
data->key = i;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
break; // We only support 1 keypress for now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self->keyboard.keysState().del) {
|
||||||
|
TT_LOG_I(TAG, "del");
|
||||||
|
data->key = LV_KEY_DEL;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else {
|
||||||
|
for (auto& i : self->keyboard.keysState().values) {
|
||||||
|
if (i == ';') { // Up
|
||||||
|
data->key = LV_KEY_UP;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else if (i == '.') { // Down
|
||||||
|
data->key = LV_KEY_DOWN;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else if (i == ',') { // Left
|
||||||
|
data->key = LV_KEY_LEFT;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else if (i == '/') { // Right
|
||||||
|
data->key = LV_KEY_RIGHT;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else if (i == '`') { // Escape
|
||||||
|
data->key = LV_KEY_ESC;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
break; // We only support 1 keypress for now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self->lastKeyNum = self->keyboard.keyList().size();
|
||||||
|
} else {
|
||||||
|
self->lastKeyNum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Boards/M5stackCardputer/Source/devices/CardputerKeyboard.h
Normal file
26
Boards/M5stackCardputer/Source/devices/CardputerKeyboard.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/Thread.h>
|
||||||
|
#include <Tactility/hal/keyboard/KeyboardDevice.h>
|
||||||
|
|
||||||
|
#include "keyboard/keyboard.h"
|
||||||
|
|
||||||
|
class CardputerKeyboard : public tt::hal::keyboard::KeyboardDevice {
|
||||||
|
KEYBOARD::Keyboard keyboard;
|
||||||
|
int lastKeyNum = 0;
|
||||||
|
lv_indev_t* _Nullable lvglDevice = nullptr;
|
||||||
|
|
||||||
|
static void readCallback(lv_indev_t* indev, lv_indev_data_t* data);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::string getName() const override { return "Cardputer Keyboard"; }
|
||||||
|
std::string getDescription() const override { return "Cardputer internal keyboard"; }
|
||||||
|
|
||||||
|
bool startLvgl(lv_display_t* display) override;
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
|
bool isAttached() const override { return true; }
|
||||||
|
|
||||||
|
lv_indev_t* _Nullable getLvglIndev() override { return lvglDevice; }
|
||||||
|
};
|
||||||
28
Boards/M5stackCardputer/Source/devices/Display.cpp
Normal file
28
Boards/M5stackCardputer/Source/devices/Display.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include <PwmBacklight.h>
|
||||||
|
#include <St7789Display.h>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
|
auto configuration = std::make_unique<St7789Display::Configuration>(
|
||||||
|
LCD_SPI_HOST,
|
||||||
|
LCD_PIN_CS,
|
||||||
|
LCD_PIN_DC,
|
||||||
|
LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
LCD_VERTICAL_RESOLUTION,
|
||||||
|
nullptr,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
53, // Should be 52 according to https://github.com/m5stack/M5GFX/blob/master/src/M5GFX.cpp but this leaves a gap at the bottom
|
||||||
|
40
|
||||||
|
);
|
||||||
|
|
||||||
|
configuration->resetPin = LCD_PIN_RESET;
|
||||||
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
|
auto display = std::make_shared<St7789Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
|
}
|
||||||
15
Boards/M5stackCardputer/Source/devices/Display.h
Normal file
15
Boards/M5stackCardputer/Source/devices/Display.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define LCD_SPI_HOST SPI2_HOST
|
||||||
|
#define LCD_PIN_CS GPIO_NUM_37
|
||||||
|
#define LCD_PIN_DC GPIO_NUM_34 // RS
|
||||||
|
#define LCD_PIN_RESET GPIO_NUM_33
|
||||||
|
#define LCD_HORIZONTAL_RESOLUTION 240
|
||||||
|
#define LCD_VERTICAL_RESOLUTION 135
|
||||||
|
#define LCD_DRAW_BUFFER_HEIGHT (LCD_VERTICAL_RESOLUTION / 10)
|
||||||
|
#define LCD_DRAW_BUFFER_SIZE (LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT)
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
25
Boards/M5stackCardputer/Source/devices/SdCard.cpp
Normal file
25
Boards/M5stackCardputer/Source/devices/SdCard.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "SdCard.h"
|
||||||
|
|
||||||
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
|
|
||||||
|
constexpr auto SDCARD_PIN_CS = GPIO_NUM_12;
|
||||||
|
constexpr auto LCD_PIN_CS = GPIO_NUM_37;
|
||||||
|
|
||||||
|
using tt::hal::sdcard::SpiSdCardDevice;
|
||||||
|
|
||||||
|
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||||
|
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
||||||
|
SDCARD_PIN_CS,
|
||||||
|
GPIO_NUM_NC,
|
||||||
|
GPIO_NUM_NC,
|
||||||
|
GPIO_NUM_NC,
|
||||||
|
SdCardDevice::MountBehaviour::AtBoot,
|
||||||
|
tt::hal::spi::getLock(SPI3_HOST),
|
||||||
|
std::vector { LCD_PIN_CS },
|
||||||
|
SPI3_HOST
|
||||||
|
);
|
||||||
|
|
||||||
|
return std::make_shared<SpiSdCardDevice>(
|
||||||
|
std::move(configuration)
|
||||||
|
);
|
||||||
|
}
|
||||||
7
Boards/M5stackCardputer/Source/devices/SdCard.h
Normal file
7
Boards/M5stackCardputer/Source/devices/SdCard.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tactility/hal/sdcard/SdCardDevice.h"
|
||||||
|
|
||||||
|
using tt::hal::sdcard::SdCardDevice;
|
||||||
|
|
||||||
|
std::shared_ptr<SdCardDevice> createSdCard();
|
||||||
31
Boards/M5stackCardputer/Source/keyboard/README.md
Normal file
31
Boards/M5stackCardputer/Source/keyboard/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# keyboard folder
|
||||||
|
|
||||||
|
The keyboard code in this folder is from https://github.com/m5stack/M5Cardputer-UserDemo/tree/main/main/hal/keyboard
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
The original license is an MIT license:
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 M5Stack
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
```
|
||||||
266
Boards/M5stackCardputer/Source/keyboard/keyboard.cpp
Normal file
266
Boards/M5stackCardputer/Source/keyboard/keyboard.cpp
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
/**
|
||||||
|
* @file keyboard.cpp
|
||||||
|
* @author Forairaaaaa
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2023-09-22
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
|
||||||
|
#define digitalWrite(pin, level) gpio_set_level((gpio_num_t)pin, level)
|
||||||
|
#define digitalRead(pin) gpio_get_level((gpio_num_t)pin)
|
||||||
|
|
||||||
|
|
||||||
|
using namespace KEYBOARD;
|
||||||
|
|
||||||
|
void Keyboard::_set_output(const std::vector<int>& pinList, uint8_t output)
|
||||||
|
{
|
||||||
|
output = output & 0B00000111;
|
||||||
|
|
||||||
|
digitalWrite(pinList[0], (output & 0B00000001));
|
||||||
|
digitalWrite(pinList[1], (output & 0B00000010));
|
||||||
|
digitalWrite(pinList[2], (output & 0B00000100));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Keyboard::_get_input(const std::vector<int>& pinList)
|
||||||
|
{
|
||||||
|
uint8_t buffer = 0x00;
|
||||||
|
uint8_t pin_value = 0x00;
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
pin_value = (digitalRead(pinList[i]) == 1) ? 0x00 : 0x01;
|
||||||
|
pin_value = pin_value << i;
|
||||||
|
buffer = buffer | pin_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Keyboard::init()
|
||||||
|
{
|
||||||
|
for (auto i : output_list)
|
||||||
|
{
|
||||||
|
gpio_reset_pin((gpio_num_t)i);
|
||||||
|
gpio_set_direction((gpio_num_t)i, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_set_pull_mode((gpio_num_t)i, GPIO_PULLUP_PULLDOWN);
|
||||||
|
digitalWrite(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i : input_list)
|
||||||
|
{
|
||||||
|
gpio_reset_pin((gpio_num_t)i);
|
||||||
|
gpio_set_direction((gpio_num_t)i, GPIO_MODE_INPUT);
|
||||||
|
gpio_set_pull_mode((gpio_num_t)i, GPIO_PULLUP_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
_set_output(output_list, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Point2D_t Keyboard::getKey()
|
||||||
|
{
|
||||||
|
Point2D_t coor;
|
||||||
|
coor.x = -1;
|
||||||
|
coor.y = -1;
|
||||||
|
|
||||||
|
uint8_t input_value = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
_set_output(output_list, i);
|
||||||
|
// printf("% 3d,\t", get_input(inputList));
|
||||||
|
|
||||||
|
input_value = _get_input(input_list);
|
||||||
|
|
||||||
|
/* If key pressed */
|
||||||
|
if (input_value) {
|
||||||
|
|
||||||
|
/* Get X */
|
||||||
|
for (int j = 0; j < 7; j++) {
|
||||||
|
if (input_value == X_map_chart[j].value) {
|
||||||
|
coor.x = (i > 3) ? X_map_chart[j].x_1 : X_map_chart[j].x_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Y */
|
||||||
|
coor.y = (i > 3) ? (i - 4) : i;
|
||||||
|
|
||||||
|
/* Keep the same as picture */
|
||||||
|
coor.y = -coor.y;
|
||||||
|
coor.y = coor.y + 3;
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("%d,%d\n", x, y);
|
||||||
|
return coor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Keyboard::getKeyNum(Point2D_t keyCoor)
|
||||||
|
{
|
||||||
|
uint8_t ret = 0;
|
||||||
|
|
||||||
|
if ((keyCoor.x < 0) || (keyCoor.y < 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (keyCoor.y * 14) + (keyCoor.x + 1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Keyboard::updateKeyList()
|
||||||
|
{
|
||||||
|
_key_list_buffer.clear();
|
||||||
|
|
||||||
|
Point2D_t coor;
|
||||||
|
|
||||||
|
uint8_t input_value = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
_set_output(output_list, i);
|
||||||
|
input_value = _get_input(input_list);
|
||||||
|
|
||||||
|
/* If key pressed */
|
||||||
|
if (input_value) {
|
||||||
|
/* Get X */
|
||||||
|
for (int j = 0; j < 7; j++) {
|
||||||
|
if (input_value & (0x01 << j)) {
|
||||||
|
coor.x = (i > 3) ? X_map_chart[j].x_1 : X_map_chart[j].x_2;
|
||||||
|
|
||||||
|
/* Get Y */
|
||||||
|
coor.y = (i > 3) ? (i - 4) : i;
|
||||||
|
// printf("%d,%d\t", coor.x, coor.y);
|
||||||
|
|
||||||
|
/* Keep the same as picture */
|
||||||
|
coor.y = -coor.y;
|
||||||
|
coor.y = coor.y + 3;
|
||||||
|
|
||||||
|
_key_list_buffer.push_back(coor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Keyboard::isKeyPressing(int keyNum)
|
||||||
|
{
|
||||||
|
if (_key_list_buffer.size())
|
||||||
|
{
|
||||||
|
for (const auto& i : _key_list_buffer)
|
||||||
|
{
|
||||||
|
if (getKeyNum(i) == keyNum)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
void Keyboard::updateKeysState()
|
||||||
|
{
|
||||||
|
_keys_state_buffer.reset();
|
||||||
|
_key_values_without_special_keys.clear();
|
||||||
|
|
||||||
|
// Get special keys
|
||||||
|
for (auto& i : _key_list_buffer)
|
||||||
|
{
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "tab") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.tab = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "fn") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.fn = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "shift") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.shift = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "ctrl") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.ctrl = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "opt") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.opt = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "alt") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.alt = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "del") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.del = true;
|
||||||
|
_keys_state_buffer.hidKey.push_back(KEY_BACKSPACE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "enter") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.enter = true;
|
||||||
|
_keys_state_buffer.hidKey.push_back(KEY_ENTER);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(getKeyValue(i).value_first, "space") == 0)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.space = true;
|
||||||
|
_keys_state_buffer.hidKey.push_back(KEY_SPACE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_key_values_without_special_keys.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deal what left
|
||||||
|
for (auto& i : _key_values_without_special_keys)
|
||||||
|
{
|
||||||
|
if (_keys_state_buffer.ctrl || _keys_state_buffer.shift || _is_caps_locked)
|
||||||
|
{
|
||||||
|
_keys_state_buffer.values.push_back(*getKeyValue(i).value_second);
|
||||||
|
_keys_state_buffer.hidKey.push_back(getKeyValue(i).value_num_second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_keys_state_buffer.values.push_back(*getKeyValue(i).value_first);
|
||||||
|
_keys_state_buffer.hidKey.push_back(getKeyValue(i).value_num_first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Keyboard::isChanged()
|
||||||
|
{
|
||||||
|
if (_last_key_size != _key_list_buffer.size())
|
||||||
|
{
|
||||||
|
_last_key_size = _key_list_buffer.size();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
192
Boards/M5stackCardputer/Source/keyboard/keyboard.h
Normal file
192
Boards/M5stackCardputer/Source/keyboard/keyboard.h
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
* @file keyboard.h
|
||||||
|
* @author Forairaaaaa
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2023-09-22
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include "keymap.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace KEYBOARD
|
||||||
|
{
|
||||||
|
struct Chart_t
|
||||||
|
{
|
||||||
|
uint8_t value;
|
||||||
|
uint8_t x_1;
|
||||||
|
uint8_t x_2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Point2D_t
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<int> output_list = {8, 9, 11};
|
||||||
|
const std::vector<int> input_list = {13, 15, 3, 4, 5, 6, 7};
|
||||||
|
// const std::vector<int> input_list = {1, 2, 3, 4, 5, 6, 7};
|
||||||
|
|
||||||
|
const Chart_t X_map_chart[7] =
|
||||||
|
{
|
||||||
|
{1, 0, 1},
|
||||||
|
{2, 2, 3},
|
||||||
|
{4, 4, 5},
|
||||||
|
{8, 6, 7},
|
||||||
|
{16, 8, 9},
|
||||||
|
{32, 10, 11},
|
||||||
|
{64, 12, 13}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyValue_t
|
||||||
|
{
|
||||||
|
const char* value_first;
|
||||||
|
const int value_num_first;
|
||||||
|
const char* value_second;
|
||||||
|
const int value_num_second;
|
||||||
|
};
|
||||||
|
|
||||||
|
const KeyValue_t _key_value_map[4][14] = {
|
||||||
|
{{"`", KEY_GRAVE, "~", KEY_GRAVE},
|
||||||
|
{"1", KEY_1, "!", KEY_1},
|
||||||
|
{"2", KEY_2, "@", KEY_2},
|
||||||
|
{"3", KEY_3, "#", KEY_3},
|
||||||
|
{"4", KEY_4, "$", KEY_4},
|
||||||
|
{"5", KEY_5, "%", KEY_5},
|
||||||
|
{"6", KEY_6, "^", KEY_6},
|
||||||
|
{"7", KEY_7, "&", KEY_7},
|
||||||
|
{"8", KEY_8, "*", KEY_KPASTERISK},
|
||||||
|
{"9", KEY_9, "(", KEY_KPLEFTPAREN},
|
||||||
|
{"0", KEY_0, ")", KEY_KPRIGHTPAREN},
|
||||||
|
{"-", KEY_MINUS, "_", KEY_KPMINUS},
|
||||||
|
{"=", KEY_EQUAL, "+", KEY_KPPLUS},
|
||||||
|
{"del", KEY_BACKSPACE, "del", KEY_BACKSPACE}},
|
||||||
|
{{"tab", KEY_TAB, "tab", KEY_TAB},
|
||||||
|
{"q", KEY_Q, "Q", KEY_Q},
|
||||||
|
{"w", KEY_W, "W", KEY_W},
|
||||||
|
{"e", KEY_E, "E", KEY_E},
|
||||||
|
{"r", KEY_R, "R", KEY_R},
|
||||||
|
{"t", KEY_T, "T", KEY_T},
|
||||||
|
{"y", KEY_Y, "Y", KEY_Y},
|
||||||
|
{"u", KEY_U, "U", KEY_U},
|
||||||
|
{"i", KEY_I, "I", KEY_I},
|
||||||
|
{"o", KEY_O, "O", KEY_O},
|
||||||
|
{"p", KEY_P, "P", KEY_P},
|
||||||
|
{"[", KEY_LEFTBRACE, "{", KEY_LEFTBRACE},
|
||||||
|
{"]", KEY_RIGHTBRACE, "}", KEY_RIGHTBRACE},
|
||||||
|
{"\\", KEY_BACKSLASH, "|", KEY_BACKSLASH}},
|
||||||
|
{{"fn", 0, "fn", 0},
|
||||||
|
{"shift", 0, "shift", 0},
|
||||||
|
{"a", KEY_A, "A", KEY_A},
|
||||||
|
{"s", KEY_S, "S", KEY_S},
|
||||||
|
{"d", KEY_D, "D", KEY_D},
|
||||||
|
{"f", KEY_F, "F", KEY_F},
|
||||||
|
{"g", KEY_G, "G", KEY_G},
|
||||||
|
{"h", KEY_H, "H", KEY_H},
|
||||||
|
{"j", KEY_J, "J", KEY_J},
|
||||||
|
{"k", KEY_K, "K", KEY_K},
|
||||||
|
{"l", KEY_L, "L", KEY_L},
|
||||||
|
{";", KEY_SEMICOLON, ":", KEY_SEMICOLON},
|
||||||
|
{"'", KEY_APOSTROPHE, "\"", KEY_APOSTROPHE},
|
||||||
|
{"enter", KEY_ENTER, "enter", KEY_ENTER}},
|
||||||
|
{{"ctrl", KEY_LEFTCTRL, "ctrl", KEY_LEFTCTRL},
|
||||||
|
{"opt", 0, "opt", 0},
|
||||||
|
{"alt", KEY_LEFTALT, "alt", KEY_LEFTALT},
|
||||||
|
{"z", KEY_Z, "Z", KEY_Z},
|
||||||
|
{"x", KEY_X, "X", KEY_X},
|
||||||
|
{"c", KEY_C, "C", KEY_C},
|
||||||
|
{"v", KEY_V, "V", KEY_V},
|
||||||
|
{"b", KEY_B, "B", KEY_B},
|
||||||
|
{"n", KEY_N, "N", KEY_N},
|
||||||
|
{"m", KEY_M, "M", KEY_M},
|
||||||
|
{",", KEY_COMMA, "<", KEY_COMMA},
|
||||||
|
{".", KEY_DOT, ">", KEY_DOT},
|
||||||
|
{"/", KEY_KPSLASH, "?", KEY_KPSLASH},
|
||||||
|
{"space", KEY_SPACE, "space", KEY_SPACE}}};
|
||||||
|
|
||||||
|
class Keyboard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct KeysState
|
||||||
|
{
|
||||||
|
bool tab = false;
|
||||||
|
bool fn = false;
|
||||||
|
bool shift = false;
|
||||||
|
bool ctrl = false;
|
||||||
|
bool opt = false;
|
||||||
|
bool alt = false;
|
||||||
|
bool del = false;
|
||||||
|
bool enter = false;
|
||||||
|
bool space = false;
|
||||||
|
|
||||||
|
std::vector<char> values;
|
||||||
|
std::vector<int> hidKey;
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
tab = false;
|
||||||
|
fn = false;
|
||||||
|
shift = false;
|
||||||
|
ctrl = false;
|
||||||
|
opt = false;
|
||||||
|
alt = false;
|
||||||
|
del = false;
|
||||||
|
enter = false;
|
||||||
|
space = false;
|
||||||
|
|
||||||
|
values.clear();
|
||||||
|
hidKey.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Point2D_t> _key_list_buffer;
|
||||||
|
|
||||||
|
std::vector<Point2D_t> _key_values_without_special_keys;
|
||||||
|
KeysState _keys_state_buffer;
|
||||||
|
|
||||||
|
bool _is_caps_locked;
|
||||||
|
uint8_t _last_key_size;
|
||||||
|
|
||||||
|
|
||||||
|
void _set_output(const std::vector<int>& pinList, uint8_t output);
|
||||||
|
uint8_t _get_input(const std::vector<int>& pinList);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Keyboard() :
|
||||||
|
_is_caps_locked(false),
|
||||||
|
_last_key_size(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
Point2D_t getKey();
|
||||||
|
|
||||||
|
uint8_t getKeyNum(Point2D_t keyCoor);
|
||||||
|
|
||||||
|
void updateKeyList();
|
||||||
|
inline std::vector<KEYBOARD::Point2D_t>& keyList() { return _key_list_buffer; }
|
||||||
|
|
||||||
|
inline KeyValue_t getKeyValue(const Point2D_t& keyCoor) { return _key_value_map[keyCoor.y][keyCoor.x]; }
|
||||||
|
|
||||||
|
bool isKeyPressing(int keyNum);
|
||||||
|
|
||||||
|
void updateKeysState();
|
||||||
|
inline KeysState& keysState() { return _keys_state_buffer; }
|
||||||
|
|
||||||
|
inline bool capslocked(void) { return _is_caps_locked; }
|
||||||
|
inline void setCapsLocked(bool isLocked) { _is_caps_locked = isLocked; }
|
||||||
|
|
||||||
|
bool isChanged();
|
||||||
|
inline uint8_t isPressed() { return _key_list_buffer.size(); }
|
||||||
|
};
|
||||||
|
}
|
||||||
366
Boards/M5stackCardputer/Source/keyboard/keymap.h
Normal file
366
Boards/M5stackCardputer/Source/keyboard/keymap.h
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of esp32s3-keyboard.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020-2021 Yuquan He <heyuquan20b at ict dot ac dot cn>
|
||||||
|
* (Institute of Computing Technology, Chinese Academy of Sciences)
|
||||||
|
*
|
||||||
|
* esp32s3-keyboard is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* esp32s3-keyboard is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with esp32s3-keyboard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* USB HID format: 8 bytes
|
||||||
|
* Byte 0: Keyboard modifier bits (SHIFT, ALT, CTRL etc)
|
||||||
|
* Byte 1: reserved
|
||||||
|
* Byte 2-7: Up to six keyboard usage indexes representing the keys that are
|
||||||
|
* currently "pressed". Order is not important, a key is either
|
||||||
|
* pressed (present in the buffer) or not pressed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MY_KEYMAP_H
|
||||||
|
#define MY_KEYMAP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifier masks - used for the first byte in the HID report.
|
||||||
|
* NOTE: The second byte in the report is reserved, 0x00
|
||||||
|
*/
|
||||||
|
#define KEY_MOD_LCTRL 0x01
|
||||||
|
#define KEY_MOD_LSHIFT 0x02
|
||||||
|
#define KEY_MOD_LALT 0x04
|
||||||
|
#define KEY_MOD_LMETA 0x08
|
||||||
|
#define KEY_MOD_RCTRL 0x10
|
||||||
|
#define KEY_MOD_RSHIFT 0x20
|
||||||
|
#define KEY_MOD_RALT 0x40
|
||||||
|
#define KEY_MOD_RMETA 0x80
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan codes - last N slots in the HID report (usually 6).
|
||||||
|
* 0x00 if no key pressed.
|
||||||
|
*
|
||||||
|
* If more than N keys are pressed, the HID reports
|
||||||
|
* KEY_ERR_OVF in all slots to indicate this condition.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KEY_NONE 0x00 // No key pressed
|
||||||
|
#define KEY_ERR_OVF \
|
||||||
|
0x01 // Keyboard Error Roll Over - used for all slots if too many keys are
|
||||||
|
// pressed ("Phantom key")
|
||||||
|
// 0x02 // Keyboard POST Fail
|
||||||
|
// 0x03 // Keyboard Error Undefined
|
||||||
|
#define KEY_A 0x04 // Keyboard a and A
|
||||||
|
#define KEY_B 0x05 // Keyboard b and B
|
||||||
|
#define KEY_C 0x06 // Keyboard c and C
|
||||||
|
#define KEY_D 0x07 // Keyboard d and D
|
||||||
|
#define KEY_E 0x08 // Keyboard e and E
|
||||||
|
#define KEY_F 0x09 // Keyboard f and F
|
||||||
|
#define KEY_G 0x0a // Keyboard g and G
|
||||||
|
#define KEY_H 0x0b // Keyboard h and H
|
||||||
|
#define KEY_I 0x0c // Keyboard i and I
|
||||||
|
#define KEY_J 0x0d // Keyboard j and J
|
||||||
|
#define KEY_K 0x0e // Keyboard k and K
|
||||||
|
#define KEY_L 0x0f // Keyboard l and L
|
||||||
|
#define KEY_M 0x10 // Keyboard m and M
|
||||||
|
#define KEY_N 0x11 // Keyboard n and N
|
||||||
|
#define KEY_O 0x12 // Keyboard o and O
|
||||||
|
#define KEY_P 0x13 // Keyboard p and P
|
||||||
|
#define KEY_Q 0x14 // Keyboard q and Q
|
||||||
|
#define KEY_R 0x15 // Keyboard r and R
|
||||||
|
#define KEY_S 0x16 // Keyboard s and S
|
||||||
|
#define KEY_T 0x17 // Keyboard t and T
|
||||||
|
#define KEY_U 0x18 // Keyboard u and U
|
||||||
|
#define KEY_V 0x19 // Keyboard v and V
|
||||||
|
#define KEY_W 0x1a // Keyboard w and W
|
||||||
|
#define KEY_X 0x1b // Keyboard x and X
|
||||||
|
#define KEY_Y 0x1c // Keyboard y and Y
|
||||||
|
#define KEY_Z 0x1d // Keyboard z and Z
|
||||||
|
|
||||||
|
#define KEY_1 0x1e // Keyboard 1 and !
|
||||||
|
#define KEY_2 0x1f // Keyboard 2 and @
|
||||||
|
#define KEY_3 0x20 // Keyboard 3 and #
|
||||||
|
#define KEY_4 0x21 // Keyboard 4 and $
|
||||||
|
#define KEY_5 0x22 // Keyboard 5 and %
|
||||||
|
#define KEY_6 0x23 // Keyboard 6 and ^
|
||||||
|
#define KEY_7 0x24 // Keyboard 7 and &
|
||||||
|
#define KEY_8 0x25 // Keyboard 8 and *
|
||||||
|
#define KEY_9 0x26 // Keyboard 9 and (
|
||||||
|
#define KEY_0 0x27 // Keyboard 0 and )
|
||||||
|
|
||||||
|
#define KEY_ENTER 0x28 // Keyboard Return (ENTER)
|
||||||
|
#define KEY_ESC 0x29 // Keyboard ESCAPE
|
||||||
|
#define KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace)
|
||||||
|
#define KEY_TAB 0x2b // Keyboard Tab
|
||||||
|
#define KEY_SPACE 0x2c // Keyboard Spacebar
|
||||||
|
#define KEY_MINUS 0x2d // Keyboard - and _
|
||||||
|
#define KEY_EQUAL 0x2e // Keyboard = and +
|
||||||
|
#define KEY_LEFTBRACE 0x2f // Keyboard [ and {
|
||||||
|
#define KEY_RIGHTBRACE 0x30 // Keyboard ] and }
|
||||||
|
#define KEY_BACKSLASH 0x31 // Keyboard \ and |
|
||||||
|
#define KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~
|
||||||
|
#define KEY_SEMICOLON 0x33 // Keyboard ; and :
|
||||||
|
#define KEY_APOSTROPHE 0x34 // Keyboard ' and "
|
||||||
|
#define KEY_GRAVE 0x35 // Keyboard ` and ~
|
||||||
|
#define KEY_COMMA 0x36 // Keyboard , and <
|
||||||
|
#define KEY_DOT 0x37 // Keyboard . and >
|
||||||
|
#define KEY_SLASH 0x38 // Keyboard / and ?
|
||||||
|
#define KEY_CAPSLOCK 0x39 // Keyboard Caps Lock
|
||||||
|
|
||||||
|
#define KEY_F1 0x3a // Keyboard F1
|
||||||
|
#define KEY_F2 0x3b // Keyboard F2
|
||||||
|
#define KEY_F3 0x3c // Keyboard F3
|
||||||
|
#define KEY_F4 0x3d // Keyboard F4
|
||||||
|
#define KEY_F5 0x3e // Keyboard F5
|
||||||
|
#define KEY_F6 0x3f // Keyboard F6
|
||||||
|
#define KEY_F7 0x40 // Keyboard F7
|
||||||
|
#define KEY_F8 0x41 // Keyboard F8
|
||||||
|
#define KEY_F9 0x42 // Keyboard F9
|
||||||
|
#define KEY_F10 0x43 // Keyboard F10
|
||||||
|
#define KEY_F11 0x44 // Keyboard F11
|
||||||
|
#define KEY_F12 0x45 // Keyboard F12
|
||||||
|
|
||||||
|
#define KEY_PRTSC 0x46 // Keyboard Print Screen
|
||||||
|
#define KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
|
||||||
|
#define KEY_PAUSE 0x48 // Keyboard Pause
|
||||||
|
#define KEY_INSERT 0x49 // Keyboard Insert
|
||||||
|
#define KEY_HOME 0x4a // Keyboard Home
|
||||||
|
#define KEY_PAGEUP 0x4b // Keyboard Page Up
|
||||||
|
// #define KEY_DELETE 0x4c // Keyboard Delete Forward
|
||||||
|
#define KEY_DELETE 0xD4 // Keyboard Delete Forward
|
||||||
|
#define KEY_END 0x4d // Keyboard End
|
||||||
|
#define KEY_PAGEDOWN 0x4e // Keyboard Page Down
|
||||||
|
#define KEY_RIGHT 0x4f // Keyboard Right Arrow
|
||||||
|
#define KEY_LEFT 0x50 // Keyboard Left Arrow
|
||||||
|
#define KEY_DOWN 0x51 // Keyboard Down Arrow
|
||||||
|
#define KEY_UP 0x52 // Keyboard Up Arrow
|
||||||
|
|
||||||
|
#define KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear
|
||||||
|
#define KEY_KPSLASH 0x54 // Keypad /
|
||||||
|
#define KEY_KPASTERISK 0x55 // Keypad *
|
||||||
|
#define KEY_KPMINUS 0x56 // Keypad -
|
||||||
|
#define KEY_KPPLUS 0x57 // Keypad +
|
||||||
|
#define KEY_KPENTER 0x58 // Keypad ENTER
|
||||||
|
#define KEY_KP1 0x59 // Keypad 1 and End
|
||||||
|
#define KEY_KP2 0x5a // Keypad 2 and Down Arrow
|
||||||
|
#define KEY_KP3 0x5b // Keypad 3 and PageDn
|
||||||
|
#define KEY_KP4 0x5c // Keypad 4 and Left Arrow
|
||||||
|
#define KEY_KP5 0x5d // Keypad 5
|
||||||
|
#define KEY_KP6 0x5e // Keypad 6 and Right Arrow
|
||||||
|
#define KEY_KP7 0x5f // Keypad 7 and Home
|
||||||
|
#define KEY_KP8 0x60 // Keypad 8 and Up Arrow
|
||||||
|
#define KEY_KP9 0x61 // Keypad 9 and Page Up
|
||||||
|
#define KEY_KP0 0x62 // Keypad 0 and Insert
|
||||||
|
#define KEY_KPDOT 0x63 // Keypad . and Delete
|
||||||
|
|
||||||
|
#define KEY_102ND 0x64 // Keyboard Non-US \ and |
|
||||||
|
#define KEY_COMPOSE 0x65 // Keyboard Application
|
||||||
|
#define KEY_POWER 0x66 // Keyboard Power
|
||||||
|
#define KEY_KPEQUAL 0x67 // Keypad =
|
||||||
|
|
||||||
|
#define KEY_F13 0x68 // Keyboard F13
|
||||||
|
#define KEY_F14 0x69 // Keyboard F14
|
||||||
|
#define KEY_F15 0x6a // Keyboard F15
|
||||||
|
#define KEY_F16 0x6b // Keyboard F16
|
||||||
|
#define KEY_F17 0x6c // Keyboard F17
|
||||||
|
#define KEY_F18 0x6d // Keyboard F18
|
||||||
|
#define KEY_F19 0x6e // Keyboard F19
|
||||||
|
#define KEY_F20 0x6f // Keyboard F20
|
||||||
|
#define KEY_F21 0x70 // Keyboard F21
|
||||||
|
#define KEY_F22 0x71 // Keyboard F22
|
||||||
|
#define KEY_F23 0x72 // Keyboard F23
|
||||||
|
#define KEY_F24 0x73 // Keyboard F24
|
||||||
|
|
||||||
|
#define KEY_OPEN 0x74 // Keyboard Execute
|
||||||
|
#define KEY_HELP 0x75 // Keyboard Help
|
||||||
|
#define KEY_PROPS 0x76 // Keyboard Menu
|
||||||
|
#define KEY_FRONT 0x77 // Keyboard Select
|
||||||
|
#define KEY_STOP 0x78 // Keyboard Stop
|
||||||
|
#define KEY_AGAIN 0x79 // Keyboard Again
|
||||||
|
#define KEY_UNDO 0x7a // Keyboard Undo
|
||||||
|
#define KEY_CUT 0x7b // Keyboard Cut
|
||||||
|
#define KEY_COPY 0x7c // Keyboard Copy
|
||||||
|
#define KEY_PASTE 0x7d // Keyboard Paste
|
||||||
|
#define KEY_FIND 0x7e // Keyboard Find
|
||||||
|
#define KEY_MUTE 0x7f // Keyboard Mute
|
||||||
|
#define KEY_VOLUMEUP 0x80 // Keyboard Volume Up
|
||||||
|
#define KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down
|
||||||
|
// 0x82 Keyboard Locking Caps Lock
|
||||||
|
// 0x83 Keyboard Locking Num Lock
|
||||||
|
// 0x84 Keyboard Locking Scroll Lock
|
||||||
|
#define KEY_KPCOMMA 0x85 // Keypad Comma
|
||||||
|
// 0x86 Keypad Equal Sign
|
||||||
|
#define KEY_RO 0x87 // Keyboard International1
|
||||||
|
#define KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2
|
||||||
|
#define KEY_YEN 0x89 // Keyboard International3
|
||||||
|
#define KEY_HENKAN 0x8a // Keyboard International4
|
||||||
|
#define KEY_MUHENKAN 0x8b // Keyboard International5
|
||||||
|
#define KEY_KPJPCOMMA 0x8c // Keyboard International6
|
||||||
|
// 0x8d Keyboard International7
|
||||||
|
// 0x8e Keyboard International8
|
||||||
|
// 0x8f Keyboard International9
|
||||||
|
#define KEY_HANGEUL 0x90 // Keyboard LANG1
|
||||||
|
#define KEY_HANJA 0x91 // Keyboard LANG2
|
||||||
|
#define KEY_KATAKANA 0x92 // Keyboard LANG3
|
||||||
|
#define KEY_HIRAGANA 0x93 // Keyboard LANG4
|
||||||
|
#define KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5
|
||||||
|
// 0x95 Keyboard LANG6
|
||||||
|
// 0x96 Keyboard LANG7
|
||||||
|
// 0x97 Keyboard LANG8
|
||||||
|
// 0x98 Keyboard LANG9
|
||||||
|
// 0x99 Keyboard Alternate Erase
|
||||||
|
// 0x9a Keyboard SysReq/Attention
|
||||||
|
// 0x9b Keyboard Cancel
|
||||||
|
// 0x9c Keyboard Clear
|
||||||
|
// 0x9d Keyboard Prior
|
||||||
|
// 0x9e Keyboard Return
|
||||||
|
// 0x9f Keyboard Separator
|
||||||
|
// 0xa0 Keyboard Out
|
||||||
|
// 0xa1 Keyboard Oper
|
||||||
|
// 0xa2 Keyboard Clear/Again
|
||||||
|
// 0xa3 Keyboard CrSel/Props
|
||||||
|
// 0xa4 Keyboard ExSel
|
||||||
|
|
||||||
|
// 0xb0 Keypad 00
|
||||||
|
// 0xb1 Keypad 000
|
||||||
|
// 0xb2 Thousands Separator
|
||||||
|
// 0xb3 Decimal Separator
|
||||||
|
// 0xb4 Currency Unit
|
||||||
|
// 0xb5 Currency Sub-unit
|
||||||
|
#define KEY_KPLEFTPAREN 0xb6 // Keypad (
|
||||||
|
#define KEY_KPRIGHTPAREN 0xb7 // Keypad )
|
||||||
|
// 0xb8 Keypad {
|
||||||
|
// 0xb9 Keypad }
|
||||||
|
// 0xba Keypad Tab
|
||||||
|
#define KEY_KPBACKSPACE 0xbb // Keypad Backspace
|
||||||
|
// 0xbc Keypad A
|
||||||
|
// 0xbd Keypad B
|
||||||
|
// 0xbe Keypad C
|
||||||
|
// 0xbf Keypad D
|
||||||
|
// 0xc0 Keypad E
|
||||||
|
// 0xc1 Keypad F
|
||||||
|
// 0xc2 Keypad XOR
|
||||||
|
// 0xc3 Keypad ^
|
||||||
|
// 0xc4 Keypad %
|
||||||
|
// 0xc5 Keypad <
|
||||||
|
// 0xc6 Keypad >
|
||||||
|
// 0xc7 Keypad &
|
||||||
|
// 0xc8 Keypad &&
|
||||||
|
// 0xc9 Keypad |
|
||||||
|
// 0xca Keypad ||
|
||||||
|
// 0xcb Keypad :
|
||||||
|
// 0xcc Keypad #
|
||||||
|
// 0xcd Keypad Space
|
||||||
|
// 0xce Keypad @
|
||||||
|
// 0xcf Keypad !
|
||||||
|
// 0xd0 Keypad Memory Store
|
||||||
|
// 0xd1 Keypad Memory Recall
|
||||||
|
// 0xd2 Keypad Memory Clear
|
||||||
|
// 0xd3 Keypad Memory Add
|
||||||
|
// 0xd4 Keypad Memory Subtract
|
||||||
|
// 0xd5 Keypad Memory Multiply
|
||||||
|
// 0xd6 Keypad Memory Divide
|
||||||
|
// 0xd7 Keypad +/-
|
||||||
|
// 0xd8 Keypad Clear
|
||||||
|
// 0xd9 Keypad Clear Entry
|
||||||
|
// 0xda Keypad Binary
|
||||||
|
// 0xdb Keypad Octal
|
||||||
|
// 0xdc Keypad Decimal
|
||||||
|
// 0xdd Keypad Hexadecimal
|
||||||
|
|
||||||
|
#define KEY_LEFTCTRL 0xe0 // Keyboard Left Control
|
||||||
|
#define KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift
|
||||||
|
#define KEY_LEFTALT 0xe2 // Keyboard Left Alt
|
||||||
|
#define KEY_LEFTMETA 0xe3 // Keyboard Left GUI
|
||||||
|
#define KEY_RIGHTCTRL 0xe4 // Keyboard Right Control
|
||||||
|
#define KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift
|
||||||
|
#define KEY_RIGHTALT 0xe6 // Keyboard Right Alt
|
||||||
|
#define KEY_RIGHTMETA 0xe7 // Keyboard Right GUI
|
||||||
|
|
||||||
|
#define KEY_MEDIA_PLAYPAUSE 0xe8
|
||||||
|
#define KEY_MEDIA_STOPCD 0xe9
|
||||||
|
#define KEY_MEDIA_PREVIOUSSONG 0xea
|
||||||
|
#define KEY_MEDIA_NEXTSONG 0xeb
|
||||||
|
#define KEY_MEDIA_EJECTCD 0xec
|
||||||
|
#define KEY_MEDIA_VOLUMEUP 0xed
|
||||||
|
#define KEY_MEDIA_VOLUMEDOWN 0xee
|
||||||
|
#define KEY_MEDIA_MUTE 0xef
|
||||||
|
#define KEY_MEDIA_WWW 0xf0
|
||||||
|
#define KEY_MEDIA_BACK 0xf1
|
||||||
|
#define KEY_MEDIA_FORWARD 0xf2
|
||||||
|
#define KEY_MEDIA_STOP 0xf3
|
||||||
|
#define KEY_MEDIA_FIND 0xf4
|
||||||
|
#define KEY_MEDIA_SCROLLUP 0xf5
|
||||||
|
#define KEY_MEDIA_SCROLLDOWN 0xf6
|
||||||
|
#define KEY_MEDIA_EDIT 0xf7
|
||||||
|
#define KEY_MEDIA_SLEEP 0xf8
|
||||||
|
#define KEY_MEDIA_COFFEE 0xf9
|
||||||
|
#define KEY_MEDIA_REFRESH 0xfa
|
||||||
|
#define KEY_MEDIA_CALC 0xfb
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Generic Control
|
||||||
|
KEY_CONSUMER_CONTROL = 0x0001,
|
||||||
|
|
||||||
|
// Power Control
|
||||||
|
KEY_CONSUMER_POWER = 0x0030,
|
||||||
|
KEY_CONSUMER_RESET = 0x0031,
|
||||||
|
KEY_CONSUMER_SLEEP = 0x0032,
|
||||||
|
|
||||||
|
// Screen Brightness
|
||||||
|
KEY_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F,
|
||||||
|
KEY_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070,
|
||||||
|
|
||||||
|
// These HID usages operate only on mobile systems (battery powered) and
|
||||||
|
// require Windows 8 (build 8302 or greater).
|
||||||
|
KEY_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C,
|
||||||
|
KEY_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6,
|
||||||
|
KEY_CONSUMER_WIRELESS_RADIO_LED = 0x00C7,
|
||||||
|
KEY_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8,
|
||||||
|
|
||||||
|
// Media Control
|
||||||
|
KEY_CONSUMER_PLAY_PAUSE = 0x00CD,
|
||||||
|
KEY_CONSUMER_SCAN_NEXT = 0x00B5,
|
||||||
|
KEY_CONSUMER_SCAN_PREVIOUS = 0x00B6,
|
||||||
|
KEY_CONSUMER_STOP = 0x00B7,
|
||||||
|
KEY_CONSUMER_VOLUME = 0x00E0,
|
||||||
|
KEY_CONSUMER_MUTE = 0x00E2,
|
||||||
|
KEY_CONSUMER_BASS = 0x00E3,
|
||||||
|
KEY_CONSUMER_TREBLE = 0x00E4,
|
||||||
|
KEY_CONSUMER_BASS_BOOST = 0x00E5,
|
||||||
|
KEY_CONSUMER_VOLUME_INCREMENT = 0x00E9,
|
||||||
|
KEY_CONSUMER_VOLUME_DECREMENT = 0x00EA,
|
||||||
|
KEY_CONSUMER_BASS_INCREMENT = 0x0152,
|
||||||
|
KEY_CONSUMER_BASS_DECREMENT = 0x0153,
|
||||||
|
KEY_CONSUMER_TREBLE_INCREMENT = 0x0154,
|
||||||
|
KEY_CONSUMER_TREBLE_DECREMENT = 0x0155,
|
||||||
|
|
||||||
|
// Application Launcher
|
||||||
|
KEY_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183,
|
||||||
|
KEY_CONSUMER_AL_EMAIL_READER = 0x018A,
|
||||||
|
KEY_CONSUMER_AL_CALCULATOR = 0x0192,
|
||||||
|
KEY_CONSUMER_AL_LOCAL_BROWSER = 0x0194,
|
||||||
|
|
||||||
|
// Browser/Explorer Specific
|
||||||
|
KEY_CONSUMER_AC_SEARCH = 0x0221,
|
||||||
|
KEY_CONSUMER_AC_HOME = 0x0223,
|
||||||
|
KEY_CONSUMER_AC_BACK = 0x0224,
|
||||||
|
KEY_CONSUMER_AC_FORWARD = 0x0225,
|
||||||
|
KEY_CONSUMER_AC_STOP = 0x0226,
|
||||||
|
KEY_CONSUMER_AC_REFRESH = 0x0227,
|
||||||
|
KEY_CONSUMER_AC_BOOKMARKS = 0x022A,
|
||||||
|
|
||||||
|
// Mouse Horizontal scroll
|
||||||
|
KEY_CONSUMER_AC_PAN = 0x0238,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -53,6 +53,8 @@ function(INIT_TACTILITY_GLOBALS SDKCONFIG_FILE)
|
|||||||
set(TACTILITY_BOARD_PROJECT LilygoTdeck)
|
set(TACTILITY_BOARD_PROJECT LilygoTdeck)
|
||||||
elseif (board_id STREQUAL "lilygo-tlora-pager")
|
elseif (board_id STREQUAL "lilygo-tlora-pager")
|
||||||
set(TACTILITY_BOARD_PROJECT LilygoTLoraPager)
|
set(TACTILITY_BOARD_PROJECT LilygoTLoraPager)
|
||||||
|
elseif (board_id STREQUAL "m5stack-cardputer")
|
||||||
|
set(TACTILITY_BOARD_PROJECT M5stackCardputer)
|
||||||
elseif (board_id STREQUAL "m5stack-core2")
|
elseif (board_id STREQUAL "m5stack-core2")
|
||||||
set(TACTILITY_BOARD_PROJECT M5stackCore2)
|
set(TACTILITY_BOARD_PROJECT M5stackCore2)
|
||||||
elseif (board_id STREQUAL "m5stack-cores3")
|
elseif (board_id STREQUAL "m5stack-cores3")
|
||||||
|
|||||||
@ -69,6 +69,9 @@ release m5stack-core2
|
|||||||
|
|
||||||
releaseSdk release/TactilitySDK-esp32
|
releaseSdk release/TactilitySDK-esp32
|
||||||
|
|
||||||
|
build m5stack-cardputer
|
||||||
|
release m5stack-cardputer
|
||||||
|
|
||||||
build m5stack-cores3
|
build m5stack-cores3
|
||||||
release m5stack-cores3
|
release m5stack-cores3
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
## Medium Priority
|
## Medium Priority
|
||||||
|
|
||||||
|
- Implement `uninstall` action in `tactility.py`
|
||||||
|
- Improve EspLcdDisplay to contain all the standard configuration options, and implement a default init function. Add a configuration class.
|
||||||
- Statusbar icon that shows low/critical memory warnings
|
- Statusbar icon that shows low/critical memory warnings
|
||||||
- Make WiFi setup app that starts an access point and hosts a webpage to set up the device.
|
- Make WiFi setup app that starts an access point and hosts a webpage to set up the device.
|
||||||
This will be useful for devices without a screen, a small screen or a non-touch screen.
|
This will be useful for devices without a screen, a small screen or a non-touch screen.
|
||||||
@ -27,6 +29,8 @@
|
|||||||
- Try out ILI9342 https://github.com/jbrilha/esp_lcd_ili9342
|
- Try out ILI9342 https://github.com/jbrilha/esp_lcd_ili9342
|
||||||
- All drivers (e.g. display, touch, etc.) should call stop() in their destructor, or at least assert that they should not be running.
|
- All drivers (e.g. display, touch, etc.) should call stop() in their destructor, or at least assert that they should not be running.
|
||||||
- Bug: Turn on WiFi (when testing it wasn't connected/connecting - just active). Open chat. Observe crash.
|
- Bug: Turn on WiFi (when testing it wasn't connected/connecting - just active). Open chat. Observe crash.
|
||||||
|
- Toolbar: when the title doesn't fit, scroll the text instead of splitting it onto a new line (try on Waveshare 1.47")
|
||||||
|
- UI: create UI size classification (e.g. "compact" for tiny screens without touch)
|
||||||
|
|
||||||
## Lower Priority
|
## Lower Priority
|
||||||
|
|
||||||
|
|||||||
@ -92,6 +92,13 @@ bool St7789Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lc
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gap_x = configuration->swapXY ? configuration->gapY : configuration->gapX;
|
||||||
|
int gap_y = configuration->swapXY ? configuration->gapX : configuration->gapY;
|
||||||
|
if (esp_lcd_panel_set_gap(panelHandle, gap_x, gap_y) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "Failed to set panel gap");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,12 +32,16 @@ public:
|
|||||||
bool mirrorX = false,
|
bool mirrorX = false,
|
||||||
bool mirrorY = false,
|
bool mirrorY = false,
|
||||||
bool invertColor = false,
|
bool invertColor = false,
|
||||||
uint32_t bufferSize = 0 // Size in pixel count. 0 means default, which is 1/10 of the screen size
|
uint32_t bufferSize = 0, // Size in pixel count. 0 means default, which is 1/10 of the screen size
|
||||||
|
int gapX = 0,
|
||||||
|
int gapY = 0
|
||||||
) : spiHostDevice(spiHostDevice),
|
) : spiHostDevice(spiHostDevice),
|
||||||
csPin(csPin),
|
csPin(csPin),
|
||||||
dcPin(dcPin),
|
dcPin(dcPin),
|
||||||
horizontalResolution(horizontalResolution),
|
horizontalResolution(horizontalResolution),
|
||||||
verticalResolution(verticalResolution),
|
verticalResolution(verticalResolution),
|
||||||
|
gapX(gapX),
|
||||||
|
gapY(gapY),
|
||||||
swapXY(swapXY),
|
swapXY(swapXY),
|
||||||
mirrorX(mirrorX),
|
mirrorX(mirrorX),
|
||||||
mirrorY(mirrorY),
|
mirrorY(mirrorY),
|
||||||
@ -58,6 +62,8 @@ public:
|
|||||||
size_t transactionQueueDepth = 10;
|
size_t transactionQueueDepth = 10;
|
||||||
unsigned int horizontalResolution;
|
unsigned int horizontalResolution;
|
||||||
unsigned int verticalResolution;
|
unsigned int verticalResolution;
|
||||||
|
int gapX;
|
||||||
|
int gapY;
|
||||||
bool swapXY = false;
|
bool swapXY = false;
|
||||||
bool mirrorX = false;
|
bool mirrorX = false;
|
||||||
bool mirrorY = false;
|
bool mirrorY = false;
|
||||||
|
|||||||
@ -36,6 +36,17 @@ static size_t elfManifestSetCount = 0;
|
|||||||
static ElfManifest elfManifest;
|
static ElfManifest elfManifest;
|
||||||
static std::shared_ptr<Lock> elfManifestLock = std::make_shared<Mutex>();
|
static std::shared_ptr<Lock> elfManifestLock = std::make_shared<Mutex>();
|
||||||
|
|
||||||
|
static std::string getErrorCodeString(int error_code) {
|
||||||
|
switch (error_code) {
|
||||||
|
case ENOMEM:
|
||||||
|
return "out of memory";
|
||||||
|
case ENOSYS:
|
||||||
|
return "missing symbol";
|
||||||
|
default:
|
||||||
|
return std::format("code {}", error_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ElfApp : public App {
|
class ElfApp : public App {
|
||||||
|
|
||||||
const std::string appPath;
|
const std::string appPath;
|
||||||
@ -77,8 +88,8 @@ class ElfApp : public App {
|
|||||||
auto relocate_result = esp_elf_relocate(&elf, elfFileData.get());
|
auto relocate_result = esp_elf_relocate(&elf, elfFileData.get());
|
||||||
if (relocate_result != 0) {
|
if (relocate_result != 0) {
|
||||||
// Note: the result code mapes to values from cstdlib's errno.h
|
// Note: the result code mapes to values from cstdlib's errno.h
|
||||||
lastError = std::format("Failed to load executable (error code {})", -relocate_result);
|
lastError = getErrorCodeString(-relocate_result);
|
||||||
TT_LOG_E(TAG, "%s", lastError.c_str());
|
TT_LOG_E(TAG, "Application failed to load: %s", lastError.c_str());
|
||||||
elfFileData = nullptr;
|
elfFileData = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,11 +41,11 @@ public:
|
|||||||
~LvglSync() override = default;
|
~LvglSync() override = default;
|
||||||
|
|
||||||
bool lock(TickType_t timeoutTicks) const override {
|
bool lock(TickType_t timeoutTicks) const override {
|
||||||
return tt::lvgl::lock(timeoutTicks);
|
return lvgl::lock(timeoutTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unlock() const override {
|
bool unlock() const override {
|
||||||
tt::lvgl::unlock();
|
lvgl::unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
56
sdkconfig.board.m5stack-cardputer
Normal file
56
sdkconfig.board.m5stack-cardputer
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Software defaults
|
||||||
|
# Increase stack size for WiFi (fixes crash after scan)
|
||||||
|
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072
|
||||||
|
CONFIG_LV_FONT_MONTSERRAT_14=y
|
||||||
|
CONFIG_LV_FONT_MONTSERRAT_18=y
|
||||||
|
CONFIG_LV_USE_USER_DATA=y
|
||||||
|
CONFIG_LV_USE_FS_STDIO=y
|
||||||
|
CONFIG_LV_FS_STDIO_LETTER=65
|
||||||
|
CONFIG_LV_FS_STDIO_PATH=""
|
||||||
|
CONFIG_LV_FS_STDIO_CACHE_SIZE=4096
|
||||||
|
CONFIG_LV_USE_LODEPNG=y
|
||||||
|
CONFIG_LV_USE_BUILTIN_MALLOC=n
|
||||||
|
CONFIG_LV_USE_CLIB_MALLOC=y
|
||||||
|
CONFIG_LV_USE_MSGBOX=n
|
||||||
|
CONFIG_LV_USE_SPINNER=n
|
||||||
|
CONFIG_LV_USE_WIN=n
|
||||||
|
CONFIG_LV_USE_SNAPSHOT=y
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
|
CONFIG_FREERTOS_SMP=n
|
||||||
|
CONFIG_FREERTOS_UNICORE=n
|
||||||
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=5120
|
||||||
|
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
||||||
|
CONFIG_FATFS_LFN_HEAP=y
|
||||||
|
CONFIG_FATFS_VOLUME_COUNT=3
|
||||||
|
CONFIG_FATFS_SECTOR_512=y
|
||||||
|
CONFIG_WL_SECTOR_SIZE_512=y
|
||||||
|
CONFIG_WL_SECTOR_SIZE=512
|
||||||
|
CONFIG_WL_SECTOR_MODE_SAFE=y
|
||||||
|
CONFIG_WL_SECTOR_MODE=1
|
||||||
|
|
||||||
|
# Hardware: Main
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4mb.csv"
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions-4mb.csv"
|
||||||
|
CONFIG_TT_BOARD_M5STACK_CARDPUTER=y
|
||||||
|
CONFIG_TT_BOARD_NAME="M5Stack Cardputer"
|
||||||
|
CONFIG_TT_BOARD_ID="m5stack-cardputer"
|
||||||
|
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||||
|
CONFIG_IDF_TARGET="esp32s3"
|
||||||
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||||
|
CONFIG_FLASHMODE_QIO=y
|
||||||
|
# SPI Flash (can set back to 80MHz after ESP-IDF bug is resolved)
|
||||||
|
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||||
|
# LVGL
|
||||||
|
CONFIG_LV_DPI_DEF=139
|
||||||
|
CONFIG_LV_DISP_DEF_REFR_PERIOD=10
|
||||||
|
CONFIG_LV_THEME_DEFAULT_DARK=y
|
||||||
|
# USB
|
||||||
|
CONFIG_TINYUSB_MSC_ENABLED=y
|
||||||
|
CONFIG_TINYUSB_MSC_MOUNT_PATH="/sdcard"
|
||||||
|
# Memory protection
|
||||||
|
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n
|
||||||
|
CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=n
|
||||||
Loading…
x
Reference in New Issue
Block a user