Adds the Pancake C5 board (ESP32-C5, ST7796 320x480, FT6336 capacitive touch)

This Pancake C5 Hardware Is already supported by other firmware...
-Ghost ESP (Release v2.0)
-Launcher(Beta Release)

I left the CI build step commented out like the V8 build until... you are ready.

- configs.h: MARAUDER_PANCAKE board defines, pins, battery (MAX17048),
  cap-touch I2C, and screen geometry. Status-bar icon x-positions and
  packet-monitor geometry generalized to SB_*/PKT_* macros so the wider
  320px panel lays out correctly (identical results on existing 240px
  boards).
- Display.cpp/.h: FT6336 capacitive touch path (rotation-aware, edge
  exclusion) gated on HAS_CAP_TOUCH; ft6336.h driver added.
- MenuFunctions.cpp / WiFiScan.cpp: hardcoded status-bar and oscilloscope
  pixel coords replaced with the new screen-size macros.
- User_Setup_marauder_pancake.h + User_Setup_Select.h entry.
- build_parallel.yml: Pancake matrix entry added but commented out
This commit is contained in:
H4W9
2026-06-29 13:19:19 -05:00
parent b6f211c014
commit c315419e94
9 changed files with 430 additions and 64 deletions
+4 -1
View File
@@ -38,6 +38,9 @@ jobs:
- { name: "M5Cardputer ADV", flag: "MARAUDER_CARDPUTER_ADV", fbqn: "esp32:esp32:esp32s3:PartitionScheme=min_spiffs,FlashSize=8M,PSRAM=disabled", file_name: "m5cardputer_adv", tft: true, tft_file: "User_Setup_marauder_m5cardputer_adv.h", build_dir: "esp32s3", addr: "0x1000", idf_ver: "2.0.11", nimble_ver: "1.3.8", esp_async: "bigbrodude6119/ESPAsyncWebServer", esp_async_ver: "master" }
- { name: "ESP32-C5-DevKitC-1", flag: "MARAUDER_C5", fbqn: "esp32:esp32:esp32c5:FlashSize=8M,PartitionScheme=min_spiffs,PSRAM=enabled", file_name: "esp32c5devkitc1", tft: false, tft_file: "", build_dir: "esp32c5", addr: "0x2000", idf_ver: "3.3.4", nimble_ver: "2.3.8", esp_async: "bigbrodude6119/ESPAsyncWebServer", esp_async_ver: "master" }
- { name: "M5NanoC6", flag: "MARAUDER_M5_NANO_C6", fbqn: "esp32:esp32:esp32c6:CDCOnBoot=cdc,PartitionScheme=min_spiffs", file_name: "m5nanoc6", tft: false, tft_file: "", build_dir: "esp32c6", addr: "0x2000", idf_ver: "3.3.4", nimble_ver: "2.3.8", esp_async: "bigbrodude6119/ESPAsyncWebServer", esp_async_ver: "master" }
# Marauder Pancake (ESP32-C5) — disabled until the custom TFT_eSPI-ESP32-C5 library
# is added to the repo and a "Use custom TFT_eSPI for ESP32-C5" copy step is restored.
#- { name: "Marauder Pancake", flag: "MARAUDER_PANCAKE", fbqn: "esp32:esp32:esp32c5:FlashSize=8M,PartitionScheme=default_8MB,PSRAM=enabled", file_name: "pancake", tft: true, tft_file: "User_Setup_marauder_pancake.h", build_dir: "esp32c5", addr: "0x2000", idf_ver: "3.3.4", nimble_ver: "2.3.8", esp_async: "bigbrodude6119/ESPAsyncWebServer", esp_async_ver: "master" }
steps:
- name: Checkout Code
@@ -111,7 +114,7 @@ jobs:
repository: Bodmer/TFT_eSPI
ref: V2.5.34
path: CustomTFT_eSPI
- name: Install XPT2046_Touchscreen
uses: actions/checkout@v2
with:
+1
View File
@@ -37,6 +37,7 @@
//#include <User_Setup_marauder_m5cardputer.h>
//#include <User_Setup_marauder_m5cardputer_adv.h>
//#include <User_Setup_cyd_3_5_inch.h>
//#include <User_Setup_marauder_pancake.h>
//#include <User_Setups/Setup1_ILI9341.h> // Setup file configured for my ILI9341
//#include <User_Setups/Setup2_ST7735.h> // Setup file configured for my ST7735
+55
View File
@@ -0,0 +1,55 @@
// USER DEFINED SETTINGS
// TFT_eSPI setup for Marauder Pancake (ESP32-C5-DevKitC-1 + ILI9341 3.5")
// ##################################################################################
// Section 1. Driver
// ##################################################################################
//#define ILI9341_DRIVER
#define ST7796_DRIVER
// 3.5-inch portrait panel native resolution
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
// If colours are inverted (white shows as black) then uncomment one of the next
// 2 lines try both options, one of the options should correct the inversion.
#define TFT_INVERSION_ON
// #define TFT_INVERSION_OFF
// ##################################################################################
// Section 2. Pin assignments (Pancake hardware)
// ##################################################################################
#define TFT_MISO 4
#define TFT_MOSI 24
#define TFT_SCLK 23
#define TFT_CS 5 // TFT chip select
#define TFT_DC 3 // Data/command
#define TFT_RST 2 // Reset
#define TFT_BL 26 // Backlight
#define TOUCH_CS -1 // No resistive touch chip; FT6336 is I2C-only
// ##################################################################################
// Section 3. Fonts
// ##################################################################################
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
// #define LOAD_FONT6
// #define LOAD_FONT7
// #define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT
// ##################################################################################
// Section 4. SPI speed
// ##################################################################################
#define SPI_FREQUENCY 27000000
#define SPI_READ_FREQUENCY 20000000
#define SPI_TOUCH_FREQUENCY 2500000
+76 -17
View File
@@ -41,8 +41,47 @@ int8_t Display::menuButton(uint16_t *x, uint16_t *y, bool pressed, bool check_ho
uint8_t Display::updateTouch(uint16_t *x, uint16_t *y, uint16_t threshold) {
#ifdef HAS_ILI9341
if (!this->headless_mode)
#ifndef HAS_CYD_TOUCH
if (!this->headless_mode) {
#ifdef HAS_CAP_TOUCH
// FT6336 capacitive touch: rotation-aware + edge exclusion
{
uint16_t raw_x, raw_y;
if (!ft6336_read_raw(&raw_x, &raw_y)) return 0;
// Discard touches within PANCAKE_TOUCH_MARGIN pixels of any panel edge
#define PANCAKE_PANEL_W TFT_WIDTH
#define PANCAKE_PANEL_H TFT_HEIGHT
#define PANCAKE_TOUCH_MARGIN 5
if (raw_x < PANCAKE_TOUCH_MARGIN || raw_x >= (PANCAKE_PANEL_W - PANCAKE_TOUCH_MARGIN)) return 0;
if (raw_y < PANCAKE_TOUCH_MARGIN || raw_y >= (PANCAKE_PANEL_H - PANCAKE_TOUCH_MARGIN)) return 0;
// Transform panel-native portrait coords to screen coords per rotation
uint8_t rot = this->tft.getRotation();
switch (rot) {
case 0: // Portrait
*x = raw_x;
*y = raw_y;
break;
case 1: // Landscape 90 CW
*x = raw_y;
*y = (PANCAKE_PANEL_W - 1) - raw_x;
break;
case 2: // Portrait 180
*x = (PANCAKE_PANEL_W - 1) - raw_x;
*y = (PANCAKE_PANEL_H - 1) - raw_y;
break;
case 3: // Landscape 270 CW
*x = (PANCAKE_PANEL_H - 1) - raw_y;
*y = raw_x;
break;
default:
*x = raw_x;
*y = raw_y;
break;
}
return 1;
}
#elif !defined(HAS_CYD_TOUCH)
return this->tft.getTouch(x, y, threshold);
#else
if (this->touchscreen.tirqTouched() && this->touchscreen.touched()) {
@@ -80,8 +119,9 @@ uint8_t Display::updateTouch(uint16_t *x, uint16_t *y, uint16_t threshold) {
else
return 0;
#endif
else
} else {
return !this->headless_mode;
}
#endif
return 0;
@@ -118,7 +158,7 @@ void Display::init() {
}
void Display::setCalData(bool landscape) {
#ifndef HAS_CYD_TOUCH
#if !defined(HAS_CYD_TOUCH) && !defined(HAS_CAP_TOUCH)
if (!landscape) {
#ifdef TFT_SHIELD
uint16_t calData[5] = { 275, 3494, 361, 3528, 4 }; // tft.setRotation(0); // Portrait with TFT Shield
@@ -167,6 +207,10 @@ void Display::RunSetup() {
this->touchscreen.begin(touchscreenSPI);
this->touchscreen.setRotation(0);
#endif
#ifdef HAS_CAP_TOUCH
ft6336_init();
#endif
tft.init();
@@ -176,7 +220,7 @@ void Display::RunSetup() {
#ifdef HAS_ILI9341
#ifndef HAS_CYD_TOUCH
#if !defined(HAS_CYD_TOUCH) && !defined(HAS_CAP_TOUCH)
this->setCalData();
#endif
@@ -200,14 +244,13 @@ void Display::RunSetup() {
void Display::tftDrawGraphObjects(byte x_scale)
{
//draw the graph objects
tft.fillRect(11, 5, x_scale+1, 120, TFT_BLACK); // positive start point
tft.fillRect(11, 121, x_scale+1, 119, TFT_BLACK); // negative start point
tft.drawFastVLine(10, 5, 230, TFT_WHITE); // y axis
tft.drawFastHLine(10, HEIGHT_1 - 1, 310, TFT_WHITE); // x axis
tft.fillRect(11, 5, x_scale+1, PKT_HALF, TFT_BLACK); // positive start point
tft.fillRect(11, PKT_HALF + 1, x_scale+1, PKT_HALF - 1, TFT_BLACK); // negative start point
tft.drawFastVLine(10, 5, PKT_HALF * 2 - 10, TFT_WHITE); // y axis
tft.drawFastHLine(10, HEIGHT_1 - 1, PKT_AXIS_W, TFT_WHITE); // x axis
tft.setTextColor(TFT_YELLOW); tft.setTextSize(1); // set parameters for y axis labels
//tft.setCursor(3, 116); tft.print(midway); // "0" at center of ya axis
tft.setCursor(3, 6); tft.print("+"); // "+' at top of y axis
tft.setCursor(3, 228); tft.print("0"); // "-" at bottom of y axis
tft.setCursor(3, 6); tft.print("+"); // '+' at top of y axis
tft.setCursor(3, PKT_HALF * 2 - 12); tft.print("0"); // "0" near baseline
}
void Display::tftDrawEapolColorKey(bool filter)
@@ -297,6 +340,9 @@ void Display::tftDrawYScaleButtons(byte y_scale)
}
void Display::tftDrawChannelScaleButtons(int set_channel, bool lnd_an) {
#ifdef MARAUDER_PANCAKE
TOP_FIXED_AREA_2 = lnd_an ? 48 : 64;
#endif
if (lnd_an) {
tft.drawFastVLine(178, 0, 20, TFT_WHITE);
tft.setCursor(145, 21); tft.setTextColor(TFT_WHITE); tft.setTextSize(1); tft.print(text10); tft.print(set_channel);
@@ -354,6 +400,9 @@ void Display::tftDrawChannelScaleButtons(int set_channel, bool lnd_an) {
}
void Display::tftDrawChanHopButton(bool lnd_an, bool en) {
#ifdef MARAUDER_PANCAKE
TOP_FIXED_AREA_2 = lnd_an ? 48 : 64;
#endif
if (lnd_an) {
if (!en) {
key[CHAN_HOP_INDEX].initButton(&tft, // Exit box
@@ -412,6 +461,9 @@ void Display::tftDrawChanHopButton(bool lnd_an, bool en) {
}
void Display::tftDrawExitScaleButtons(bool lnd_an) {
#ifdef MARAUDER_PANCAKE
TOP_FIXED_AREA_2 = lnd_an ? 48 : 64;
#endif
//tft.drawFastVLine(178, 0, 20, TFT_WHITE);
//tft.setCursor(145, 21); tft.setTextColor(TFT_WHITE); tft.setTextSize(1); tft.print("Channel:"); tft.print(set_channel);
@@ -473,6 +525,9 @@ void Display::touchToExit()
// Function to just draw the screen black
void Display::clearScreen()
{
#ifdef MARAUDER_PANCAKE
TOP_FIXED_AREA_2 = 48;
#endif
//Serial.println(F("clearScreen()"));
#ifndef MARAUDER_V7
tft.fillScreen(TFT_BLACK);
@@ -573,11 +628,15 @@ void Display::displayBuffer(bool do_clear)
screen_buffer->add(display_buffer->shift());
for (int i = 0; i < this->screen_buffer->size(); i++) {
#ifdef HAS_TOUCH
tft.setCursor(xPos, (i * 12) + ((TFT_HEIGHT / 6) * 1.3));
#else
tft.setCursor(xPos, (i * 12) + (TFT_HEIGHT / 6));
#endif
#ifdef MARAUDER_PANCAKE
tft.setCursor(xPos, (i * TEXT_HEIGHT) + TOP_FIXED_AREA_2);
#else
#ifdef HAS_TOUCH
tft.setCursor(xPos, (i * 12) + ((TFT_HEIGHT / 6) * 1.3));
#else
tft.setCursor(xPos, (i * 12) + (TFT_HEIGHT / 6));
#endif
#endif
this->processAndPrintString(tft, this->screen_buffer->get(i));
}
+4
View File
@@ -20,6 +20,10 @@
#include <XPT2046_Touchscreen.h>
#endif
#ifdef HAS_CAP_TOUCH
#include "ft6336.h"
#endif
// WiFi stuff
#define OTA_UPDATE 100
#define SHOW_INFO 101
+33 -33
View File
@@ -259,10 +259,10 @@ void MenuFunctions::main(uint32_t currentTime)
if (pressed &&
(wifi_scan_obj.currentScanMode == WIFI_SCAN_WAR_DRIVE ||
wifi_scan_obj.currentScanMode == WIFI_SCAN_STATION_WAR_DRIVE)) {
if (t_y >= 270) {
if (t_y >= (SCREEN_HEIGHT - 50)) {
wifi_scan_obj.tagPOI(nullptr);
// Brief green flash
display_obj.tft.fillRect(0, 270, 240, 50, TFT_GREEN);
display_obj.tft.fillRect(0, SCREEN_HEIGHT - 50, SCREEN_WIDTH, 50, TFT_GREEN);
display_obj.tft.setTextSize(2);
#ifdef HAS_GPS
if (gps_obj.getFixStatus())
@@ -272,7 +272,7 @@ void MenuFunctions::main(uint32_t currentTime)
display_obj.tft.setTextColor(TFT_BLACK, TFT_RED);
String poiFlash = "POI (" + String(wifi_scan_obj.poiCount) + ")";
int16_t flashWidth = poiFlash.length() * 12;
display_obj.tft.setCursor((240 - flashWidth) / 2, 287);
display_obj.tft.setCursor((SCREEN_WIDTH - flashWidth) / 2, SCREEN_HEIGHT - 33);
display_obj.tft.print(poiFlash);
delay(200);
x = -1;
@@ -961,15 +961,15 @@ void MenuFunctions::battery2(bool initial)
else the_color = TFT_GREEN;
display_obj.tft.setTextColor(the_color, STATUSBAR_COLOR);
display_obj.tft.fillRect(186, 0, 50, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
display_obj.tft.drawXBitmap(186,
display_obj.tft.fillRect(SB_TOUCH_X, 0, 50, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
display_obj.tft.drawXBitmap(SB_TOUCH_X,
0,
menu_icons[STATUS_BAT],
16,
16,
STATUSBAR_COLOR,
the_color);
display_obj.tft.drawString((String) battery_analog + "%", 204, 0, 2);
display_obj.tft.drawString((String) battery_analog + "%", SB_BAT_X, 0, 2);
}
#else
void MenuFunctions::battery(bool initial)
@@ -991,7 +991,7 @@ void MenuFunctions::battery(bool initial)
display_obj.tft.setCursor(0, 1);
/*if (!this->disable_touch) {
display_obj.tft.drawXBitmap(186,
display_obj.tft.drawXBitmap(SB_TOUCH_X,
0,
menu_icons[STATUS_BAT],
16,
@@ -1000,9 +1000,9 @@ void MenuFunctions::battery(bool initial)
the_color);
}*/
#if defined(MARAUDER_CARDPUTER) || defined(MARAUDER_CARDPUTER_ADV)
display_obj.tft.drawString((String)battery_obj.battery_level + "%", 204, 0, 1);
display_obj.tft.drawString((String)battery_obj.battery_level + "%", SB_BAT_X, 0, 1);
#else
display_obj.tft.drawString((String)battery_obj.battery_level + "%", 204, 0, 2);
display_obj.tft.drawString((String)battery_obj.battery_level + "%", SB_BAT_X, 0, 2);
#endif
}
#endif
@@ -1093,13 +1093,13 @@ void MenuFunctions::updateStatusBar()
wifi_scan_obj.free_ram = String(esp_get_free_heap_size());
if ((wifi_scan_obj.free_ram != wifi_scan_obj.old_free_ram) || (status_changed)) {
wifi_scan_obj.old_free_ram = wifi_scan_obj.free_ram;
//display_obj.tft.fillRect(100, 0, 60, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
//display_obj.tft.fillRect(SB_MEM_X, 0, 60, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
#ifdef HAS_FULL_SCREEN
#ifndef HAS_PSRAM
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", 100, 0, 2);
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", SB_MEM_X, 0, 2);
#else
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", 100, 0, 1);
display_obj.tft.drawString("P:" + String(getPSRAMUsagePercent()) + "%", 100, 8, 1);
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", SB_MEM_X, 0, 1);
display_obj.tft.drawString("P:" + String(getPSRAMUsagePercent()) + "%", SB_MEM_X, 8, 1);
#endif
#endif
@@ -1110,14 +1110,14 @@ void MenuFunctions::updateStatusBar()
// Draw battery info
MenuFunctions::battery(false);
display_obj.tft.fillRect(186, 0, 16, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
display_obj.tft.fillRect(SB_TOUCH_X, 0, 16, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
// Disable touch stuff
#ifdef HAS_ILI9341
#ifdef HAS_BUTTONS
if (this->disable_touch) {
display_obj.tft.setCursor(0, 1);
display_obj.tft.drawXBitmap(186,
display_obj.tft.drawXBitmap(SB_TOUCH_X,
0,
menu_icons[DISABLE_TOUCH],
16,
@@ -1127,7 +1127,7 @@ void MenuFunctions::updateStatusBar()
}
else {
display_obj.tft.setCursor(0, 1);
display_obj.tft.drawXBitmap(186,
display_obj.tft.drawXBitmap(SB_TOUCH_X,
0,
menu_icons[DISABLE_TOUCH],
16,
@@ -1146,7 +1146,7 @@ void MenuFunctions::updateStatusBar()
the_color = TFT_RED;
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170,
display_obj.tft.drawXBitmap(SB_SD_X,
0,
menu_icons[STATUS_SD],
16,
@@ -1164,7 +1164,7 @@ void MenuFunctions::updateStatusBar()
// WiFi connection status stuff
if (wifi_scan_obj.wifi_connected) {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - 16,
display_obj.tft.drawXBitmap(SB_WIFI_X,
0,
menu_icons[JOINED],
16,
@@ -1174,7 +1174,7 @@ void MenuFunctions::updateStatusBar()
#endif
} else {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - 16,
display_obj.tft.drawXBitmap(SB_WIFI_X,
0,
menu_icons[JOINED],
16,
@@ -1187,7 +1187,7 @@ void MenuFunctions::updateStatusBar()
// Force PMKID stuff
if ((wifi_scan_obj.force_pmkid) || (wifi_scan_obj.ep_deauth)) {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - (16 * 2),
display_obj.tft.drawXBitmap(SB_FORCE_X,
0,
menu_icons[FORCE],
16,
@@ -1197,7 +1197,7 @@ void MenuFunctions::updateStatusBar()
#endif
} else {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - (16 * 2),
display_obj.tft.drawXBitmap(SB_FORCE_X,
0,
menu_icons[FORCE],
16,
@@ -1271,13 +1271,13 @@ void MenuFunctions::drawStatusBar()
// RAM Stuff
wifi_scan_obj.free_ram = String(esp_get_free_heap_size());
wifi_scan_obj.old_free_ram = wifi_scan_obj.free_ram;
display_obj.tft.fillRect(100, 0, 60, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
display_obj.tft.fillRect(SB_MEM_X, 0, 60, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
#ifdef HAS_FULL_SCREEN
#ifndef HAS_PSRAM
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", 100, 0, 2);
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", SB_MEM_X, 0, 2);
#else
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", 100, 0, 1);
display_obj.tft.drawString("P:" + String(getPSRAMUsagePercent()) + "%", 100, 8, 1);
display_obj.tft.drawString("D:" + String(getDRAMUsagePercent()) + "%", SB_MEM_X, 0, 1);
display_obj.tft.drawString("P:" + String(getPSRAMUsagePercent()) + "%", SB_MEM_X, 8, 1);
#endif
#endif
@@ -1287,7 +1287,7 @@ void MenuFunctions::drawStatusBar()
MenuFunctions::battery(true);
display_obj.tft.fillRect(186, 0, 16, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
display_obj.tft.fillRect(SB_TOUCH_X, 0, 16, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
// Disable touch stuff
@@ -1295,7 +1295,7 @@ void MenuFunctions::drawStatusBar()
#ifdef HAS_BUTTONS
if (this->disable_touch) {
display_obj.tft.setCursor(0, 1);
display_obj.tft.drawXBitmap(186,
display_obj.tft.drawXBitmap(SB_TOUCH_X,
0,
menu_icons[DISABLE_TOUCH],
16,
@@ -1305,7 +1305,7 @@ void MenuFunctions::drawStatusBar()
}
else {
display_obj.tft.setCursor(0, 1);
display_obj.tft.drawXBitmap(186,
display_obj.tft.drawXBitmap(SB_TOUCH_X,
0,
menu_icons[DISABLE_TOUCH],
16,
@@ -1325,7 +1325,7 @@ void MenuFunctions::drawStatusBar()
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170,
display_obj.tft.drawXBitmap(SB_SD_X,
0,
menu_icons[STATUS_SD],
16,
@@ -1343,7 +1343,7 @@ void MenuFunctions::drawStatusBar()
// WiFi connection status stuff
if (wifi_scan_obj.wifi_connected) {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - 16,
display_obj.tft.drawXBitmap(SB_WIFI_X,
0,
menu_icons[JOINED],
16,
@@ -1353,7 +1353,7 @@ void MenuFunctions::drawStatusBar()
#endif
} else {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - 16,
display_obj.tft.drawXBitmap(SB_WIFI_X,
0,
menu_icons[JOINED],
16,
@@ -1366,7 +1366,7 @@ void MenuFunctions::drawStatusBar()
// Force PMKID stuff
if ((wifi_scan_obj.force_pmkid) || (wifi_scan_obj.ep_deauth)) {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - (16 * 2),
display_obj.tft.drawXBitmap(SB_FORCE_X,
0,
menu_icons[FORCE],
16,
@@ -1376,7 +1376,7 @@ void MenuFunctions::drawStatusBar()
#endif
} else {
#ifdef HAS_FULL_SCREEN
display_obj.tft.drawXBitmap(170 - (16 * 2),
display_obj.tft.drawXBitmap(SB_FORCE_X,
0,
menu_icons[FORCE],
16,
+17 -13
View File
@@ -4102,7 +4102,11 @@ void WiFiScan::RunPacketMonitor(uint8_t scan_mode, uint16_t color) {
(scan_mode != WIFI_SCAN_CHAN_ACT)) {
#ifdef HAS_SCREEN
display_obj.init();
display_obj.tft.setRotation(1);
#ifdef HAS_CAP_TOUCH
display_obj.tft.setRotation(3); // Pancake: landscape-3
#else
display_obj.tft.setRotation(1);
#endif
display_obj.tft.fillScreen(TFT_BLACK);
#endif
@@ -4116,7 +4120,7 @@ void WiFiScan::RunPacketMonitor(uint8_t scan_mode, uint16_t color) {
//display_obj.tft.setFreeFont(1);
display_obj.tft.setFreeFont(NULL);
display_obj.tft.setTextSize(1);
display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); // Buttons
display_obj.tft.fillRect(127, 0, WIDTH_1 - 127, 28, TFT_BLACK); // Buttons
display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // color key
delay(10);
@@ -5125,12 +5129,12 @@ void WiFiScan::displayWardriveStats() {
#endif
// POI button — full width bottom bar
display_obj.tft.drawRect(0, 270, 240, 50, TFT_MAGENTA);
display_obj.tft.drawRect(0, SCREEN_HEIGHT - 50, SCREEN_WIDTH, 50, TFT_MAGENTA);
display_obj.tft.setTextSize(2);
display_obj.tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
String poiText = "POI (" + String(this->poiCount) + ")";
int16_t poiTextWidth = poiText.length() * 12; // 12px per char at size 2
display_obj.tft.setCursor((240 - poiTextWidth) / 2, 287);
display_obj.tft.setCursor((SCREEN_WIDTH - poiTextWidth) / 2, SCREEN_HEIGHT - 33);
display_obj.tft.print(poiText);
#endif
@@ -8901,7 +8905,7 @@ bool WiFiScan::filterActive() {
void WiFiScan::packetMonitorMain(uint32_t currentTime) {
for (x_pos = (11 + x_scale); x_pos <= 320; x_pos = x_pos)
for (x_pos = (11 + x_scale); x_pos <= WIDTH_1; x_pos = x_pos)
{
currentTime = millis();
do_break = false;
@@ -9038,19 +9042,19 @@ bool WiFiScan::filterActive() {
display_obj.tft.drawLine(x_pos - x_scale, y_pos_y_old, x_pos, y_pos_y, TFT_RED);
//Draw preceding black 'boxes' to erase old plot lines, !!!WEIRD CODE TO COMPENSATE FOR BUTTONS AND COLOR KEY SO 'ERASER' DOESN'T ERASE BUTTONS AND COLOR KEY!!!
if ((x_pos <= 90) || ((x_pos >= 117) && (x_pos <= 320))) //above x axis
display_obj.tft.fillRect(x_pos+1, 28, 10, 93, TFT_BLACK); //compensate for buttons!
if ((x_pos <= 90) || ((x_pos >= 117) && (x_pos <= WIDTH_1))) //above x axis
display_obj.tft.fillRect(x_pos+1, 28, 10, PKT_HALF - 27, TFT_BLACK); //compensate for buttons!
else
display_obj.tft.fillRect(x_pos+1, 0, 10, 121, TFT_BLACK); //don't compensate for buttons!
display_obj.tft.fillRect(x_pos+1, 0, 10, PKT_HALF + 1, TFT_BLACK); //don't compensate for buttons!
if (x_pos < 0) // below x axis
display_obj.tft.fillRect(x_pos+1, 121, 10, 88, TFT_CYAN);
display_obj.tft.fillRect(x_pos+1, PKT_HALF + 1, 10, PKT_HALF - 32, TFT_CYAN);
else
display_obj.tft.fillRect(x_pos+1, 121, 10, 118, TFT_BLACK);
display_obj.tft.fillRect(x_pos+1, PKT_HALF + 1, 10, PKT_HALF - 2, TFT_BLACK);
if ( (y_pos_x == 120) || (y_pos_y == 120) || (y_pos_z == 120) )
display_obj.tft.drawFastHLine(10, 120, 310, TFT_WHITE); // x axis
if ( (y_pos_x == PKT_HALF) || (y_pos_y == PKT_HALF) || (y_pos_z == PKT_HALF) )
display_obj.tft.drawFastHLine(10, PKT_HALF, PKT_AXIS_W, TFT_WHITE); // x axis
y_pos_x_old = y_pos_x; //set old y pos values to current y pos values
y_pos_y_old = y_pos_y;
@@ -9061,7 +9065,7 @@ bool WiFiScan::filterActive() {
}
display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); //erase XY buttons and any lines behind them
display_obj.tft.fillRect(127, 0, WIDTH_1 - 127, 28, TFT_BLACK); //erase XY buttons and any lines behind them
display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // key
display_obj.tftDrawXScaleButtons(x_scale); //re-draw stuff
+168
View File
@@ -33,6 +33,7 @@
//#define MARAUDER_CARDPUTER
//#define MARAUDER_CARDPUTER_ADV
//#define MARAUDER_V8
//#define MARAUDER_PANCAKE
//#define MARAUDER_MINI_V3
//#define MARAUDER_M5_NANO_C6
//#define DUAL_MINI_C5
@@ -103,6 +104,8 @@
#define HARDWARE_NAME "ESP32-C5 DevKit"
#elif defined(MARAUDER_V8)
#define HARDWARE_NAME "Marauder v8"
#elif defined(MARAUDER_PANCAKE)
#define HARDWARE_NAME "Pancake Marauder V8"
#elif defined(MARAUDER_MINI_V3)
#define HARDWARE_NAME "Marauder Mini v3"
#elif defined(DUAL_MINI_C5)
@@ -516,6 +519,29 @@
#define HAS_ACT_LED
#endif
#ifdef MARAUDER_PANCAKE
#define HAS_TOUCH
#define HAS_CAP_TOUCH
//#define HAS_FLIPPER_LED
//#define FLIPPER_ZERO_HAT
#define HAS_BATTERY
#define HAS_BT
//#define HAS_BUTTONS
#define HAS_NEOPIXEL_LED
//#define HAS_PWR_MGMT
#define HAS_SCREEN
#define HAS_FULL_SCREEN
#define HAS_GPS
#define HAS_C5_SD
#define HAS_SD
#define USE_SD
#define HAS_DUAL_BAND
#define HAS_PSRAM
//#define HAS_TEMP_SENSOR
#define HAS_NIMBLE_2
#define HAS_IDF_3
#endif
#ifdef MARAUDER_MINI_V3
//#define HAS_TOUCH
//#define HAS_FLIPPER_LED
@@ -1299,6 +1325,75 @@
#define KIT_LED_BUILTIN 13
#endif
#if defined(MARAUDER_PANCAKE)
#define CHAN_PER_PAGE 7
#define SCREEN_CHAR_WIDTH 40
#define HAS_ILI9341
#define BANNER_TEXT_SIZE 2
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 480
#endif
#define GRAPH_VERT_LIM TFT_HEIGHT/2 - 1
#define EXT_BUTTON_WIDTH 30
#define SCREEN_BUFFER
#define MAX_SCREEN_BUFFER 26
#define SCREEN_ORIENTATION 0
#define CHAR_WIDTH 12
#define SCREEN_WIDTH TFT_WIDTH
#define SCREEN_HEIGHT TFT_HEIGHT
#define HEIGHT_1 TFT_WIDTH
#define WIDTH_1 TFT_HEIGHT
#define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6)
#define TEXT_HEIGHT 16
#define BOT_FIXED_AREA 0
#define TOP_FIXED_AREA 48
#define YMAX 480
#define minimum(a,b) (((a) < (b)) ? (a) : (b))
//#define MENU_FONT NULL
#define MENU_FONT &FreeMono9pt7b // Winner
//#define MENU_FONT &FreeMonoBold9pt7b
//#define MENU_FONT &FreeSans9pt7b
//#define MENU_FONT &FreeSansBold9pt7b
#define BUTTON_SCREEN_LIMIT 18
#define BUTTON_ARRAY_LEN BUTTON_SCREEN_LIMIT
#define STATUS_BAR_WIDTH 16
#define LVGL_TICK_PERIOD 6
#define FRAME_X 100
#define FRAME_Y 64
#define FRAME_W TFT_WIDTH / 2
#define FRAME_H 50
// Red zone size
#define REDBUTTON_X FRAME_X
#define REDBUTTON_Y FRAME_Y
#define REDBUTTON_W (FRAME_W/2)
#define REDBUTTON_H FRAME_H
// Green zone size
#define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
#define GREENBUTTON_Y FRAME_Y
#define GREENBUTTON_W (FRAME_W/2)
#define GREENBUTTON_H FRAME_H
#define STATUSBAR_COLOR 0x4A49
#define KIT_LED_BUILTIN 13
#endif
#if defined(MARAUDER_CYD_MICRO)
#define CHAN_PER_PAGE 7
@@ -2062,6 +2157,24 @@
//#define BUTTON_ARRAY_LEN 5
#endif
// Status bar right-side icon x-positions (SCREEN_WIDTH-relative)
// V8 (240px): SD=170 WiFi=154 Force=138 Touch=186 Bat=204
// Pancake (320px): SD=250 WiFi=234 Force=218 Touch=266 Bat=284
#define SB_MEM_X (SCREEN_WIDTH / 2 - 20) // D%/P% text: 120 on V8, 160 on Pancake
#define SB_SD_X (SCREEN_WIDTH - 70)
#define SB_WIFI_X (SCREEN_WIDTH - 86)
#define SB_FORCE_X (SCREEN_WIDTH - 102)
#define SB_TOUCH_X (SCREEN_WIDTH - 54)
#define SB_BAT_X (SCREEN_WIDTH - 36)
// Packet monitor oscilloscope geometry
// PKT_HALF = landscape height midpoint (zero-line y)
// PKT_AXIS_W = x-axis draw width
// HEIGHT_1 = TFT_WIDTH (landscape height): V8=240 Pancake=320
// WIDTH_1 = TFT_HEIGHT (landscape width): V8=320 Pancake=480
#define PKT_HALF (HEIGHT_1 / 2)
#define PKT_AXIS_W (WIDTH_1 - 10)
#if defined(MARAUDER_V8)
#define BANNER_TIME 100
@@ -2081,6 +2194,25 @@
//#define BUTTON_ARRAY_LEN 5
#endif
#if defined(MARAUDER_PANCAKE)
#define BANNER_TIME 100
#define COMMAND_PREFIX "!"
// Keypad start position, key sizes and spacing
#define KEY_X 160 // Centre of key
#define KEY_Y 59
#define KEY_W 320 // Width and height
#define KEY_H 22
#define KEY_SPACING_X 0 // X and Y gap
#define KEY_SPACING_Y 1
#define KEY_TEXTSIZE 1 // Font size multiplier
#define ICON_W 22
#define ICON_H 22
#define BUTTON_PADDING 22
//#define BUTTON_ARRAY_LEN 5
#endif
#if defined(MARAUDER_CYD_MICRO)
#define BANNER_TIME 100
@@ -2396,6 +2528,10 @@
#define SD_CS 10
#endif
#ifdef MARAUDER_PANCAKE
#define SD_CS 7
#endif
#ifdef MARAUDER_MINI_V3
#define SD_CS 10
#endif
@@ -2504,6 +2640,8 @@
#define MEM_LOWER_LIM 10000
#elif defined(MARAUDER_V8)
#define MEM_LOWER_LIM 10000
#elif defined(MARAUDER_PANCAKE)
#define MEM_LOWER_LIM 10000
#elif defined(MARAUDER_MINI_V3)
#define MEM_LOWER_LIM 10000
#else
@@ -2530,6 +2668,8 @@
#define PIN 27
#elif defined(MARAUDER_V8)
#define PIN 27
#elif defined(MARAUDER_PANCAKE)
#define PIN 27
#elif defined(MARAUDER_CARDPUTER_ADV)
#define PIN 21
#elif defined(MARAUDER_M5_NANO_C6)
@@ -2637,6 +2777,10 @@
#define GPS_SERIAL_INDEX 1
#define GPS_TX 14
#define GPS_RX 13
#elif defined(MARAUDER_PANCAKE)
#define GPS_SERIAL_INDEX 1
#define GPS_TX 14
#define GPS_RX 13
#elif defined(MARAUDER_MINI_V3)
#define GPS_SERIAL_INDEX 1
#define GPS_TX 14
@@ -2699,8 +2843,18 @@
#define HAS_MAX1704X
#undef HAS_AXP2101
#undef HAS_IP5306
#elif defined(MARAUDER_PANCAKE)
#define I2C_SDA 9
#define I2C_SCL 10
#define HAS_MAX1704X
// FT6336 cap touch - shares I2C bus with MAX17048
#define CTP_RST 8
#define CTP_SDA I2C_SDA
#define CTP_SCL I2C_SCL
#endif
// If we know what we have, we can delete what we're not using
#ifdef BATTERY_ADC_PIN
#undef HAS_AXP2101
@@ -2729,6 +2883,11 @@
#undef HAS_IP5306
#undef HAS_MAX1704X
#elif defined(HAS_MAX1704X)
#undef HAS_AXP2101
#undef HAS_IP5306
#undef HAS_AXP192
#else // punt
// #define HAS_AXP2101
@@ -2739,6 +2898,7 @@
#endif // HAS_BATTERY
//// MARAUDER TITLE STUFF
#ifdef MARAUDER_V4
#define MARAUDER_TITLE_BYTES 13578
@@ -2766,6 +2926,8 @@
#define MARAUDER_TITLE_BYTES 13578
#elif defined(MARAUDER_V8)
#define MARAUDER_TITLE_BYTES 13578
#elif defined(MARAUDER_PANCAKE)
#define MARAUDER_TITLE_BYTES 13578
#elif defined(MARAUDER_MINI_V3)
#define MARAUDER_TITLE_BYTES 13578
#else
@@ -2832,6 +2994,12 @@
#define SD_SCK TFT_SCLK
#endif
#ifdef MARAUDER_PANCAKE
#define SD_MISO TFT_MISO
#define SD_MOSI TFT_MOSI
#define SD_SCK TFT_SCLK
#endif
#ifdef MARAUDER_V4
#define SD_MISO TFT_MISO
#define SD_MOSI TFT_MOSI
+72
View File
@@ -0,0 +1,72 @@
#pragma once
#ifndef ft6336_h
#define ft6336_h
#ifdef HAS_CAP_TOUCH
#include <Wire.h>
#define FT6336_ADDR 0x38
#define FT6336_TD_STATUS 0x02
#define FT6336_T1_XH 0x03
static bool _ft6336_read(uint8_t reg, uint8_t *buf, uint8_t len) {
Wire.beginTransmission(FT6336_ADDR);
Wire.write(reg);
if (Wire.endTransmission(false) != 0) return false;
Wire.requestFrom((int)FT6336_ADDR, (int)len);
for (uint8_t i = 0; i < len; i++)
buf[i] = Wire.available() ? Wire.read() : 0;
return true;
}
static void ft6336_init() {
pinMode(CTP_RST, OUTPUT);
digitalWrite(CTP_RST, LOW);
delay(10);
digitalWrite(CTP_RST, HIGH);
delay(300);
Wire.begin(CTP_SDA, CTP_SCL, 400000U);
uint8_t chipId = 0;
Wire.beginTransmission(FT6336_ADDR);
Wire.write(0xA3);
if (Wire.endTransmission(false) == 0) {
Wire.requestFrom((int)FT6336_ADDR, 1);
if (Wire.available()) chipId = Wire.read();
}
Serial.printf("[Touch] FT6336U ID: 0x%02X%s\n",
chipId, chipId == 0x64 ? " (OK)" : " (unexpected)");
// Raise touch threshold to reduce phantom touches.
// Register 0x80 = IDTHRESHOLD, default 22. Higher = less sensitive.
// Range 0255; 40 is a good balance for panel-in-case use.
Wire.beginTransmission(FT6336_ADDR);
Wire.write(0x80);
Wire.write(40);
Wire.endTransmission();
}
// Reads raw panel coordinates (panel native portrait space: 0..319 × 0..479).
// Call this when you need to apply a rotation-specific transform.
static uint8_t ft6336_read_raw(uint16_t *raw_x, uint16_t *raw_y) {
uint8_t data[7];
if (!_ft6336_read(FT6336_TD_STATUS, data, 7)) return 0;
if ((data[0] & 0x0F) == 0) return 0;
*raw_x = ((uint16_t)(data[1] & 0x0F) << 8) | data[2];
*raw_y = ((uint16_t)(data[3] & 0x0F) << 8) | data[4];
return 1;
}
// Portrait-only convenience wrapper (rotation 0).
// For rotation-aware transforms, use ft6336_read_raw() via Display::updateTouch().
static uint8_t ft6336_update(uint16_t *x, uint16_t *y) {
uint16_t raw_x, raw_y;
if (!ft6336_read_raw(&raw_x, &raw_y)) return 0;
*x = (raw_x < SCREEN_WIDTH) ? raw_x : (uint16_t)(SCREEN_WIDTH - 1);
*y = (raw_y < SCREEN_HEIGHT) ? raw_y : (uint16_t)(SCREEN_HEIGHT - 1);
return 1;
}
#endif // HAS_CAP_TOUCH
#endif // ft6336_h