From bf1468e3755821e9c07f2cfb157509417b960b2a Mon Sep 17 00:00:00 2001 From: Pirata Date: Thu, 25 Sep 2025 05:54:28 -0300 Subject: [PATCH 1/5] merge adv keyboard to old code --- .github/workflows/buil_parallel.yml | 5 - boards/m5stack-cardputer-adv/interface.cpp | 419 ------------------ .../m5stack-cardputer-adv.ini | 141 ------ boards/m5stack-cardputer-adv/pins_arduino.h | 285 ------------ boards/m5stack-cardputer/interface.cpp | 383 ++++++++++++---- .../m5stack-cardputer/m5stack-cardputer.ini | 14 +- build.py | 49 ++ platformio.ini | 4 +- 8 files changed, 363 insertions(+), 937 deletions(-) delete mode 100644 boards/m5stack-cardputer-adv/interface.cpp delete mode 100644 boards/m5stack-cardputer-adv/m5stack-cardputer-adv.ini delete mode 100644 boards/m5stack-cardputer-adv/pins_arduino.h diff --git a/.github/workflows/buil_parallel.yml b/.github/workflows/buil_parallel.yml index 7a46c79cee..905940ed53 100644 --- a/.github/workflows/buil_parallel.yml +++ b/.github/workflows/buil_parallel.yml @@ -18,7 +18,6 @@ jobs: matrix: board: - { env: "m5stack-cardputer", family: "ESP32-S3",} - - { env: "m5stack-cardputer-adv", family: "ESP32-S3",} - { env: "m5stack-cplus2", family: "ESP32",} - { env: "m5stack-cplus1_1", family: "ESP32",} - { env: "LAUNCHER_m5stack-cplus1_1", family: "ESP32",} @@ -132,10 +131,6 @@ jobs: # pio run -e ${{ matrix.board.env }} -t build-firmware # Files are merged after build - js_content="{\"name\":\"${{ matrix.board.env }}\",\"new_install_prompt_erase\": true,\"builds\":[{\"chipFamily\":\"${{ matrix.board.family }}\",\"improv\":false,\"parts\":[{\"path\":\"Bruce-${{ matrix.board.env }}.bin\",\"offset\":0}]}]}" - - echo "$js_content" > "./Bruce-${{ matrix.board.env }}.json" - - name: Upload ${{ matrix.board.env }} uses: actions/upload-artifact@v4 with: diff --git a/boards/m5stack-cardputer-adv/interface.cpp b/boards/m5stack-cardputer-adv/interface.cpp deleted file mode 100644 index dd42989e32..0000000000 --- a/boards/m5stack-cardputer-adv/interface.cpp +++ /dev/null @@ -1,419 +0,0 @@ -#include "core/powerSave.h" -#include -#include -#include - -#include -Adafruit_TCA8418 *keyboard; - -// Keyboard state variables -bool fn_key_pressed = false; -bool shift_key_pressed = false; -bool caps_lock = false; - -// Key value mapping for 4x14 keyboard -struct KeyValue_t { - const char value_first; - const char value_second; - const char value_third; -}; - -const KeyValue_t _key_value_map[KB_ROWS][KB_COLS] = { - {{'`', '~', '`'}, - {'1', '!', '1'}, - {'2', '@', '2'}, - {'3', '#', '3'}, - {'4', '$', '4'}, - {'5', '%', '5'}, - {'6', '^', '6'}, - {'7', '&', '7'}, - {'8', '*', '8'}, - {'9', '(', '9'}, - {'0', ')', '0'}, - {'-', '_', '-'}, - {'=', '+', '='}, - {'\b', '\b', '\b'}}, // Backspace - - {{'\t', '\t', '\t'}, // Tab - {'q', 'Q', 'q'}, - {'w', 'W', 'w'}, - {'e', 'E', 'e'}, - {'r', 'R', 'r'}, - {'t', 'T', 't'}, - {'y', 'Y', 'y'}, - {'u', 'U', 'u'}, - {'i', 'I', 'i'}, - {'o', 'O', 'o'}, - {'p', 'P', 'p'}, - {'[', '{', '['}, - {']', '}', ']'}, - {'\\', '|', '\\'}}, - - {{0xFF, 0xFF, 0xFF}, // FN key (special) - {0x81, 0x81, 0x81}, // Shift key (special) - {'a', 'A', 'a'}, - {'s', 'S', 's'}, - {'d', 'D', 'd'}, - {'f', 'F', 'f'}, - {'g', 'G', 'g'}, - {'h', 'H', 'h'}, - {'j', 'J', 'j'}, - {'k', 'K', 'k'}, - {'l', 'L', 'l'}, - {';', ':', ';'}, - {'\'', '\"', '\''}, - {'\r', '\r', '\r'}}, // Enter - - {{0x80, 0x80, 0x80}, // Ctrl key (special) - {0x83, 0x83, 0x83}, // OPT key (special) - {0x82, 0x82, 0x82}, // Alt key (special) - {'z', 'Z', 'z'}, - {'x', 'X', 'x'}, - {'c', 'C', 'c'}, - {'v', 'V', 'v'}, - {'b', 'B', 'b'}, - {'n', 'N', 'n'}, - {'m', 'M', 'm'}, - {',', '<', ','}, - {'.', '>', '.'}, - {'/', '?', '/'}, - {' ', ' ', ' '}} -}; - -int handleSpecialKeys(uint8_t row, uint8_t col, bool pressed); -void mapRawKeyToPhysical(uint8_t rawValue, uint8_t &row, uint8_t &col); - -char getKeyChar(uint8_t row, uint8_t col) { - char keyVal; - if (fn_key_pressed) { - keyVal = _key_value_map[row][col].value_third; - } else if (shift_key_pressed ^ caps_lock) { - keyVal = _key_value_map[row][col].value_second; - } else { - keyVal = _key_value_map[row][col].value_first; - } - return keyVal; -} - -int handleSpecialKeys(uint8_t row, uint8_t col, bool pressed) { - char keyVal = _key_value_map[row][col].value_first; - switch (keyVal) { - case 0xFF: - if (pressed) fn_key_pressed = !fn_key_pressed; - return 1; - case 0x81: - shift_key_pressed = pressed; - if (pressed && fn_key_pressed) caps_lock = !caps_lock; - return 1; - default: break; - } - return 0; -} - -/*************************************************************************************** -** Function name: mapRawKeyToPhysical() -** Location: interface.cpp -** Description: initial mapping for keyboard -***************************************************************************************/ -void mapRawKeyToPhysical(uint8_t rawValue, uint8_t &row, uint8_t &col) { - switch(rawValue) { - case 1: row = 0; col = 0; break; // ESC/` - case 2: row = 1; col = 0; break; // Tab - case 3: row = 2; col = 0; break; // FN - case 4: row = 3; col = 0; break; // Ctrl - case 5: row = 0; col = 1; break; // 1 - case 6: row = 1; col = 1; break; // Q - case 7: row = 2; col = 1; break; // Shift - case 8: row = 3; col = 1; break; // Opt - case 11: row = 0; col = 2; break; // 2 - case 12: row = 1; col = 2; break; // W - case 13: row = 2; col = 2; break; // A - case 14: row = 3; col = 2; break; // Alt - case 15: row = 0; col = 3; break; // 3 - case 16: row = 1; col = 3; break; // E - case 17: row = 2; col = 3; break; // S - case 18: row = 3; col = 3; break; // Z - case 21: row = 0; col = 4; break; // 4 - case 22: row = 1; col = 4; break; // R - case 23: row = 2; col = 4; break; // D - case 24: row = 3; col = 4; break; // X - case 25: row = 0; col = 5; break; // 5 - case 26: row = 1; col = 5; break; // T - case 27: row = 2; col = 5; break; // F - case 28: row = 3; col = 5; break; // C - case 31: row = 0; col = 6; break; // 6 - case 32: row = 1; col = 6; break; // Y - case 33: row = 2; col = 6; break; // G - case 34: row = 3; col = 6; break; // V - case 35: row = 0; col = 7; break; // 7 - case 36: row = 1; col = 7; break; // U - case 37: row = 2; col = 7; break; // H - case 38: row = 3; col = 7; break; // B - case 41: row = 0; col = 8; break; // 8 - case 42: row = 1; col = 8; break; // I - case 43: row = 2; col = 8; break; // J - case 44: row = 3; col = 8; break; // N - case 45: row = 0; col = 9; break; // 9 - case 46: row = 1; col = 9; break; // O - case 47: row = 2; col = 9; break; // K - case 48: row = 3; col = 9; break; // M - case 51: row = 0; col = 10; break; // 0 - case 52: row = 1; col = 10; break; // P - case 53: row = 2; col = 10; break; // L - case 54: row = 3; col = 10; break; // , - case 55: row = 0; col = 11; break; // - - case 56: row = 1; col = 11; break; // [ - case 57: row = 2; col = 11; break; // ; - case 58: row = 3; col = 11; break; // . - case 61: row = 0; col = 12; break; // = - case 62: row = 1; col = 12; break; // ] - case 63: row = 2; col = 12; break; // ' - case 64: row = 3; col = 12; break; // / - case 65: row = 0; col = 13; break; // Backspace - case 66: row = 1; col = 13; break; // - case 67: row = 2; col = 13; break; // Enter - case 68: row = 3; col = 13; break; // Space - default: - row = 0; col = 0; - Serial.printf("Unknown raw value: %d\n", rawValue); - break; - } -} - -/*************************************************************************************** -** Function name: _setup_gpio() -** Location: main.cpp -** Description: initial setup for the device -***************************************************************************************/ -void _setup_gpio() { - Serial.println("=== SETTING UP 14x4 KEYBOARD ==="); - - Wire.begin(SDA, SCL); - delay(100); - - // Check if device exists - Wire.beginTransmission(KB_I2C_ADDRESS); - byte error = Wire.endTransmission(); - if (error != 0) { - Serial.printf("Keyboard not found at 0x%02X! Error: %d\n", KB_I2C_ADDRESS, error); - return; - } - - keyboard = new Adafruit_TCA8418(); - if (!keyboard->begin(KB_I2C_ADDRESS, &Wire)) { - Serial.println("Failed to initialize keyboard library"); - return; - } - - // Reset the device to ensure clean state - keyboard->writeRegister(TCA8418_REG_CFG, 0x00); - delay(10); - - // Configure for 4 rows and 14 columns - // Rows 0-3 as outputs, columns 4-17 as inputs - keyboard->writeRegister(TCA8418_REG_GPIO_DIR_1, 0x0F); // GPIO0-3: outputs, GPIO4-7: inputs - keyboard->writeRegister(TCA8418_REG_GPIO_DIR_2, 0xFF); // GPIO8-15: inputs - keyboard->writeRegister(TCA8418_REG_GPIO_DIR_3, 0x03); // GPIO16-17: inputs - - // Set all used pins as keypad - keyboard->writeRegister(TCA8418_REG_KP_GPIO_1, 0xFF); // GPIO0-7 as keypad - keyboard->writeRegister(TCA8418_REG_KP_GPIO_2, 0xFF); // GPIO8-15 as keypad - keyboard->writeRegister(TCA8418_REG_KP_GPIO_3, 0x03); // GPIO16-17 as keypad - - // Enable pull-ups on all inputs - keyboard->writeRegister(TCA8418_REG_GPIO_PULL_1, 0xF0); // Pull-ups on GPIO4-7 - keyboard->writeRegister(TCA8418_REG_GPIO_PULL_2, 0xFF); // Pull-ups on GPIO8-15 - keyboard->writeRegister(TCA8418_REG_GPIO_PULL_3, 0x03); // Pull-ups on GPIO16-17 - - // Configure interrupts - keyboard->writeRegister(TCA8418_REG_CFG, - TCA8418_REG_CFG_KE_IEN | // Enable key event interrupt - TCA8418_REG_CFG_AI // Auto-increment - ); - - // Clear interrupts - keyboard->writeRegister(TCA8418_REG_INT_STAT, 0xFF); - - Serial.println("14x4 keyboard configured successfully!"); -} - -#include -#include -#include -#include -/*************************************************************************************** -** Function name: getBattery() -** location: display.cpp -** Description: Delivers the battery value from 1-100 -***************************************************************************************/ -int getBattery() { - uint8_t percent; - uint8_t _batAdcCh = ADC1_GPIO10_CHANNEL; - uint8_t _batAdcUnit = 1; - static uint32_t lastVolt = 5000; - static unsigned long lastTime = 0; - - adc1_config_width(ADC_WIDTH_BIT_12); - adc1_config_channel_atten((adc1_channel_t)_batAdcCh, ADC_ATTEN_DB_12); - static esp_adc_cal_characteristics_t *adc_chars = nullptr; - static constexpr int BASE_VOLATAGE = 3600; - adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t)); - esp_adc_cal_characterize( - (adc_unit_t)_batAdcUnit, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, BASE_VOLATAGE, adc_chars - ); - int raw; - raw = adc1_get_raw((adc1_channel_t)_batAdcCh); - uint32_t volt = esp_adc_cal_raw_to_voltage(raw, adc_chars); - - float mv = volt * 2; - percent = (mv - 3300) * 100 / (float)(4150 - 3350); - - return (percent < 0) ? 0 : (percent >= 100) ? 100 : percent; -} -bool isCharging() { return false; } - -/********************************************************************* -** Function: setBrightness -** location: settings.cpp -** set brightness value -**********************************************************************/ -void _setBrightness(uint8_t brightval) { - if (brightval == 0) { - analogWrite(TFT_BL, brightval); - } else { - int bl = MINBRIGHT + round(((255 - MINBRIGHT) * brightval / 100)); - analogWrite(TFT_BL, bl); - } -} - -/********************************************************************* -** Function: InputHandler -** Handles the variables PrevPress, NextPress, SelPress, AnyKeyPress and EscPress -**********************************************************************/ -void InputHandler(void) { - static unsigned long tm = 0; - static unsigned long lastKeyTime = 0; - static uint8_t lastKeyValue = 0; - - if (millis() - tm < 200 && !LongPress) return; - - bool shoulder = digitalRead(0); - - bool arrow_up = false; - bool arrow_dw = false; - bool arrow_ry = false; - bool arrow_le = false; - - if (keyboard->available() > 0) { - int keyEvent = keyboard->getEvent(); - bool pressed = !(keyEvent & 0x80); // Bit 7: 0=pressed, 1=released - uint8_t value = keyEvent & 0x7F; // Bits 0-6: key value - - // Debounce check - if (millis() - lastKeyTime < 50 && value == lastKeyValue) { - return; - } - lastKeyTime = millis(); - lastKeyValue = value; - - // Map raw value to physical position - uint8_t row, col; - mapRawKeyToPhysical(value, row, col); - - Serial.printf("Key event: raw=%d, pressed=%d, row=%d, col=%d\n", - value, pressed, row, col); - - if (row >= KB_ROWS || col >= KB_COLS) { - Serial.printf("Invalid position: row=%d, col=%d\n", row, col); - return; - } - - if (!wakeUpScreen()) { - AnyKeyPress = true; - - if (handleSpecialKeys(row, col, pressed) > 0) goto END; - - if (pressed) { - keyStroke key; - char keyVal = getKeyChar(row, col); - - Serial.printf("Key pressed: %c (0x%02X) at row=%d, col=%d\n", - keyVal, keyVal, row, col); - - if (keyVal == 0x08) { - key.del = true; - key.word.emplace_back(KEY_BACKSPACE); - EscPress = true; - } else if (keyVal == 0x60) { - EscPress = true; - } else if (keyVal == 0x0D) { - key.enter = true; - key.word.emplace_back(KEY_ENTER); - SelPress = true; - } else if (keyVal == 0x09) { - key.word.emplace_back(KEY_TAB); - } else if (keyVal == 0xFF) { - key.fn = true; - } else if (keyVal == 0x81) { - key.modifier_keys.emplace_back(KEY_LEFT_SHIFT); - } else if (keyVal == 0x3B) { - arrow_up = true; - PrevPress = true; - } else if (keyVal == 0x80) { - key.modifier_keys.emplace_back(KEY_LEFT_CTRL); - } else if (keyVal == 0x82) { - key.modifier_keys.emplace_back(KEY_LEFT_ALT); - } else if (keyVal == 0x83) { - key.gui = true; - } else if (keyVal == 0x2E) { - arrow_dw = true; - NextPress = true; - } else if (keyVal == 0x2C) { - arrow_le = true; - PrevPress = true; - PrevPagePress = true; - key.word.emplace_back(keyVal); - } else if (keyVal == 0x13) { - PrevPagePress = true; - key.word.emplace_back(keyVal); - } else if (keyVal == 0x2F) { - arrow_ry = true; - NextPress = true; - NextPagePress = true; - key.word.emplace_back(keyVal); - } else { - key.word.emplace_back(keyVal); - } - - key.pressed = true; - KeyStroke = key; - tm = millis(); - } - } - } else if (shoulder == LOW) { - if (!wakeUpScreen()) { - AnyKeyPress = true; - SelPress = true; - tm = millis(); - } - } else { - KeyStroke.Clear(); - } - -END: - if (shoulder == LOW) tm = millis(); -} - -/********************************************************************* -** Function: powerOff -** location: mykeyboard.cpp -** Turns off the device (or try to) -**********************************************************************/ -void powerOff() {} - -/********************************************************************* -** Function: checkReboot -** location: mykeyboard.cpp -** Btn logic to tornoff the device (name is odd btw) -**********************************************************************/ -void checkReboot() {} diff --git a/boards/m5stack-cardputer-adv/m5stack-cardputer-adv.ini b/boards/m5stack-cardputer-adv/m5stack-cardputer-adv.ini deleted file mode 100644 index d3146ab442..0000000000 --- a/boards/m5stack-cardputer-adv/m5stack-cardputer-adv.ini +++ /dev/null @@ -1,141 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[env:m5stack-cardputer-adv] -board = m5stack-cardputer-adv -board_build.partitions = custom_8Mb.csv -build_src_filter =${env.build_src_filter} +<../boards/m5stack-cardputer-adv> -build_flags = - ${env.build_flags} - -Iboards/m5stack-cardputer-adv - -DCORE_DEBUG_LEVEL=5 - - ;Features Enabled - ;-DLITE_VERSION=1 ;limits some features to save space for M5Launcher Compatibility - ;Microphone - -DMIC_SPM1423=1 ;uncomment to enable Applicable for SPM1423 device - -DPIN_CLK=43 - -DI2S_SCLK_PIN=43 - -DI2S_DATA_PIN=46 - -DPIN_DATA=46 - - ;FM Radio - -DFM_SI4713=1 ;Uncomment to activate FM Radio using Adafruit Si4713 - -DFM_RSTPIN=40 - - ;RGB LED runned by xylopyrographer/LiteLED@^1.2.0 library - -DHAS_RGB_LED=1 - -DRGB_LED=21 - - ;Speaker to run music, compatible with NS4168 - -DHAS_NS4168_SPKR=1 ;uncomment to enable - -DBCLK=41 - -DWCLK=43 - -DDOUT=42 - -DMCLK=43 # Microphone CLK or WCLK - - ;Can run USB as HID - -DUSB_as_HID=1 - - ;Buttons configuration - -DHAS_BTN=0 - -DBTN_ALIAS='"Ok"' - -DBTN_PIN=0 - -DBTN_ACT=LOW - - ;Font sizes, depending on device - -DFP=1 - -DFM=2 - -DFG=3 - - ;-DALLOW_ALL_GPIO_FOR_IR_RF=1 ; Set this option to make use of all GPIOs, from 1 to 44 to be chosen, except TFT and SD pins - - ;Infrared Led default pin and state - -DIR_TX_PINS='{ {"Default", LED}, {"M5 IR Mod", GROVE_SDA}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' - -DIR_RX_PINS='{ {"M5 IR Mod", GROVE_SCL}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' - -DLED=44 - -DLED_ON=HIGH - -DLED_OFF=LOW - - ;Radio Frequency (one pin modules) pin setting - -DRF_TX_PINS='{ {"M5 RF433T", GROVE_SDA}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' - -DRF_RX_PINS='{ {"M5 RF433R", GROVE_SCL}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' - ; connection pins using microSD sniffer module https://www.sparkfun.com/products/9419 https://docs.m5stack.com/en/core/Cardputer - -DUSE_CC1101_VIA_SPI - -DCC1101_GDO0_PIN=GROVE_SDA - -DCC1101_SS_PIN=SPI_SS_PIN - -DCC1101_MOSI_PIN=SPI_MOSI_PIN - -DCC1101_SCK_PIN=SPI_SCK_PIN - -DCC1101_MISO_PIN=SPI_MISO_PIN - ;-DCC1101_GDO2_PIN=-1 - - ; connections are the same as CC1101 - -DUSE_NRF24_VIA_SPI - -DNRF24_CE_PIN=GROVE_SDA - -DNRF24_SS_PIN=SPI_SS_PIN - -DNRF24_MOSI_PIN=SPI_MOSI_PIN - -DNRF24_SCK_PIN=SPI_SCK_PIN - -DNRF24_MISO_PIN=SPI_MISO_PIN - - -DUSE_W5500_VIA_SPI - -DW5500_SS_PIN=SPI_SS_PIN - -DW5500_MOSI_PIN=SPI_MOSI_PIN - -DW5500_SCK_PIN=SPI_SCK_PIN - -DW5500_MISO_PIN=SPI_MISO_PIN - -DW5500_INT_PIN=GROVE_SDA - - ;Screen Setup - -DHAS_SCREEN=1 - -DROTATION=1 - -DBACKLIGHT=38 - -DMINBRIGHT=160 - - ;TFT_eSPI Setup - -DUSER_SETUP_LOADED=1 - -DUSE_HSPI_PORT=1 - -DST7789_2_DRIVER=1 - -DTFT_RGB_ORDER=1 - -DTFT_WIDTH=135 - -DTFT_HEIGHT=240 - -DTFT_BACKLIGHT_ON=1 - -DTFT_BL=38 - -DTFT_RST=33 - -DTFT_DC=34 - -DTFT_MOSI=35 - -DTFT_SCLK=36 - -DTFT_CS=37 - -DTOUCH_CS=-1 - -DSMOOTH_FONT=1 - -DSPI_FREQUENCY=20000000 - -DSPI_READ_FREQUENCY=20000000 - -DSPI_TOUCH_FREQUENCY=2500000 - - ;SD Card Setup pins - -DSDCARD_CS=12 - -DSDCARD_SCK=40 - -DSDCARD_MISO=39 - -DSDCARD_MOSI=14 - - ;Default I2C port - -DGROVE_SDA=2 - -DGROVE_SCL=1 - - ;Default SPI port - -DSPI_SCK_PIN=40 - -DSPI_MOSI_PIN=14 - -DSPI_MISO_PIN=39 - -DSPI_SS_PIN=GROVE_SCL - - -DDEVICE_NAME='"M5Stack Cardputer"' - -lib_deps = - ${env.lib_deps} - fastled/FastLED @3.9.4 - adafruit/Adafruit TCA8418 @ ^1.0.2 diff --git a/boards/m5stack-cardputer-adv/pins_arduino.h b/boards/m5stack-cardputer-adv/pins_arduino.h deleted file mode 100644 index 9bdf49e503..0000000000 --- a/boards/m5stack-cardputer-adv/pins_arduino.h +++ /dev/null @@ -1,285 +0,0 @@ -#ifndef Pins_Arduino_h -#define Pins_Arduino_h - -#include "soc/soc_caps.h" -#include - -#define USB_VID 0x303a -#define USB_PID 0x1001 - -#define HAS_KEYBOARD // has keyboard to use -#define HAS_KEYBOARD_HID // has keyboard to use -#define KB_HID_EXIT_MSG "fn + Ok to exit" -#define KB_I2C_ADDRESS 0x34 -#define KB_ROWS 4 -#define KB_COLS 14 - -#define TCA8418_REG_CFG 0x01 ///< Configuration register -#define TCA8418_REG_INT_STAT 0x02 ///< Interrupt status -#define TCA8418_REG_KEY_LCK_EC 0x03 ///< Key lock and event counter -#define TCA8418_REG_KEY_EVENT_A 0x04 ///< Key event register A -#define TCA8418_REG_KEY_EVENT_B 0x05 ///< Key event register B -#define TCA8418_REG_KEY_EVENT_C 0x06 ///< Key event register C -#define TCA8418_REG_KEY_EVENT_D 0x07 ///< Key event register D -#define TCA8418_REG_KEY_EVENT_E 0x08 ///< Key event register E -#define TCA8418_REG_KEY_EVENT_F 0x09 ///< Key event register F -#define TCA8418_REG_KEY_EVENT_G 0x0A ///< Key event register G -#define TCA8418_REG_KEY_EVENT_H 0x0B ///< Key event register H -#define TCA8418_REG_KEY_EVENT_I 0x0C ///< Key event register I -#define TCA8418_REG_KEY_EVENT_J 0x0D ///< Key event register J -#define TCA8418_REG_KP_LCK_TIMER 0x0E ///< Keypad lock1 to lock2 timer -#define TCA8418_REG_UNLOCK_1 0x0F ///< Unlock register 1 -#define TCA8418_REG_UNLOCK_2 0x10 ///< Unlock register 2 -#define TCA8418_REG_GPIO_INT_STAT_1 0x11 ///< GPIO interrupt status 1 -#define TCA8418_REG_GPIO_INT_STAT_2 0x12 ///< GPIO interrupt status 2 -#define TCA8418_REG_GPIO_INT_STAT_3 0x13 ///< GPIO interrupt status 3 -#define TCA8418_REG_GPIO_DAT_STAT_1 0x14 ///< GPIO data status 1 -#define TCA8418_REG_GPIO_DAT_STAT_2 0x15 ///< GPIO data status 2 -#define TCA8418_REG_GPIO_DAT_STAT_3 0x16 ///< GPIO data status 3 -#define TCA8418_REG_GPIO_DAT_OUT_1 0x17 ///< GPIO data out 1 -#define TCA8418_REG_GPIO_DAT_OUT_2 0x18 ///< GPIO data out 2 -#define TCA8418_REG_GPIO_DAT_OUT_3 0x19 ///< GPIO data out 3 -#define TCA8418_REG_GPIO_INT_EN_1 0x1A ///< GPIO interrupt enable 1 -#define TCA8418_REG_GPIO_INT_EN_2 0x1B ///< GPIO interrupt enable 2 -#define TCA8418_REG_GPIO_INT_EN_3 0x1C ///< GPIO interrupt enable 3 -#define TCA8418_REG_KP_GPIO_1 0x1D ///< Keypad/GPIO select 1 -#define TCA8418_REG_KP_GPIO_2 0x1E ///< Keypad/GPIO select 2 -#define TCA8418_REG_KP_GPIO_3 0x1F ///< Keypad/GPIO select 3 -#define TCA8418_REG_GPI_EM_1 0x20 ///< GPI event mode 1 -#define TCA8418_REG_GPI_EM_2 0x21 ///< GPI event mode 2 -#define TCA8418_REG_GPI_EM_3 0x22 ///< GPI event mode 3 -#define TCA8418_REG_GPIO_DIR_1 0x23 ///< GPIO data direction 1 -#define TCA8418_REG_GPIO_DIR_2 0x24 ///< GPIO data direction 2 -#define TCA8418_REG_GPIO_DIR_3 0x25 ///< GPIO data direction 3 -#define TCA8418_REG_GPIO_INT_LVL_1 0x26 ///< GPIO edge/level detect 1 -#define TCA8418_REG_GPIO_INT_LVL_2 0x27 ///< GPIO edge/level detect 2 -#define TCA8418_REG_GPIO_INT_LVL_3 0x28 ///< GPIO edge/level detect 3 -#define TCA8418_REG_DEBOUNCE_DIS_1 0x29 ///< Debounce disable 1 -#define TCA8418_REG_DEBOUNCE_DIS_2 0x2A ///< Debounce disable 2 -#define TCA8418_REG_DEBOUNCE_DIS_3 0x2B ///< Debounce disable 3 -#define TCA8418_REG_GPIO_PULL_1 0x2C ///< GPIO pull-up disable 1 -#define TCA8418_REG_GPIO_PULL_2 0x2D ///< GPIO pull-up disable 2 -#define TCA8418_REG_GPIO_PULL_3 0x2E ///< GPIO pull-up disable 3 -// #define TCA8418_REG_RESERVED 0x2F - -// FIELDS CONFIG REGISTER 1 -#define TCA8418_REG_CFG_AI 0x80 ///< Auto-increment for read/write -#define TCA8418_REG_CFG_GPI_E_CGF 0x40 ///< Event mode config -#define TCA8418_REG_CFG_OVR_FLOW_M 0x20 ///< Overflow mode enable -#define TCA8418_REG_CFG_INT_CFG 0x10 ///< Interrupt config -#define TCA8418_REG_CFG_OVR_FLOW_IEN 0x08 ///< Overflow interrupt enable -#define TCA8418_REG_CFG_K_LCK_IEN 0x04 ///< Keypad lock interrupt enable -#define TCA8418_REG_CFG_GPI_IEN 0x02 ///< GPI interrupt enable -#define TCA8418_REG_CFG_KE_IEN 0x01 ///< Key events interrupt enable - -// FIELDS INT_STAT REGISTER 2 -#define TCA8418_REG_STAT_CAD_INT 0x10 ///< Ctrl-alt-del seq status -#define TCA8418_REG_STAT_OVR_FLOW_INT 0x08 ///< Overflow interrupt status -#define TCA8418_REG_STAT_K_LCK_INT 0x04 ///< Key lock interrupt status -#define TCA8418_REG_STAT_GPI_INT 0x02 ///< GPI interrupt status -#define TCA8418_REG_STAT_K_INT 0x01 ///< Key events interrupt status - -// FIELDS KEY_LCK_EC REGISTER 3 -#define TCA8418_REG_LCK_EC_K_LCK_EN 0x40 ///< Key lock enable -#define TCA8418_REG_LCK_EC_LCK_2 0x20 ///< Keypad lock status 2 -#define TCA8418_REG_LCK_EC_LCK_1 0x10 ///< Keypad lock status 1 -#define TCA8418_REG_LCK_EC_KLEC_3 0x08 ///< Key event count bit 3 -#define TCA8418_REG_LCK_EC_KLEC_2 0x04 ///< Key event count bit 2 -#define TCA8418_REG_LCK_EC_KLEC_1 0x02 ///< Key event count bit 1 -#define TCA8418_REG_LCK_EC_KLEC_0 0x01 ///< Key event count bit 0 - -static const uint8_t TX = 43; -static const uint8_t RX = 44; - -static const uint8_t TXD2 = 1; -static const uint8_t RXD2 = 2; - -static const uint8_t SDA = 8; -static const uint8_t SCL = 9; - -static const uint8_t SS = 12; -static const uint8_t MOSI = 14; -static const uint8_t MISO = 39; -static const uint8_t SCK = 40; - -static const uint8_t G0 = 0; -static const uint8_t G1 = 1; -static const uint8_t G2 = 2; -static const uint8_t G3 = 3; -static const uint8_t G4 = 4; -static const uint8_t G5 = 5; -static const uint8_t G6 = 6; -static const uint8_t G7 = 7; -static const uint8_t G8 = 8; -static const uint8_t G9 = 9; -static const uint8_t G10 = 10; -static const uint8_t G11 = 11; -static const uint8_t G12 = 12; -static const uint8_t G13 = 13; -static const uint8_t G14 = 14; -static const uint8_t G15 = 15; -static const uint8_t G39 = 39; -static const uint8_t G40 = 40; -static const uint8_t G41 = 41; -static const uint8_t G42 = 42; -static const uint8_t G43 = 43; -static const uint8_t G44 = 44; -static const uint8_t G46 = 46; - -static const uint8_t ADC1 = 7; -static const uint8_t ADC2 = 8; - -#define SHIFT 0x80 -#define KEY_LEFT_CTRL 0x80 -#define KEY_LEFT_SHIFT 0x81 -#define KEY_LEFT_ALT 0x82 -#define KEY_FN 0xff -#define KEY_OPT 0x83 -#define KEY_BACKSPACE 0x2a -#define KEY_TAB 0x2b -#define KEY_ENTER 0x42 - -static const uint8_t _kb_asciimap[128] = { - 0x00, // NUL - 0x00, // SOH - 0x00, // STX - 0x00, // ETX - 0x00, // EOT - 0x00, // ENQ - 0x00, // ACK - 0x00, // BEL - KEY_BACKSPACE, // BS Backspace - KEY_TAB, // TAB Tab - KEY_ENTER, // LF Enter - 0x00, // VT - 0x00, // FF - 0x00, // CR - 0x00, // SO - 0x00, // SI - 0x00, // DEL - 0x00, // DC1 - 0x00, // DC2 - 0x00, // DC3 - 0x00, // DC4 - 0x00, // NAK - 0x00, // SYN - 0x00, // ETB - 0x00, // CAN - 0x00, // EM - 0x00, // SUB - 0x00, // ESC - 0x00, // FS - 0x00, // GS - 0x00, // RS - 0x00, // US - - 0x2c, // ' ' - 0x1e | SHIFT, // ! - 0x34 | SHIFT, // " - 0x20 | SHIFT, // # - 0x21 | SHIFT, // $ - 0x22 | SHIFT, // % - 0x24 | SHIFT, // & - 0x34, // ' - 0x26 | SHIFT, // ( - 0x27 | SHIFT, // ) - 0x25 | SHIFT, // * - 0x2e | SHIFT, // + - 0x36, // , - 0x2d, // - - 0x37, // . - 0x38, // / - 0x27, // 0 - 0x1e, // 1 - 0x1f, // 2 - 0x20, // 3 - 0x21, // 4 - 0x22, // 5 - 0x23, // 6 - 0x24, // 7 - 0x25, // 8 - 0x26, // 9 - 0x33 | SHIFT, // : - 0x33, // ; - 0x36 | SHIFT, // < - 0x2e, // = - 0x37 | SHIFT, // > - 0x38 | SHIFT, // ? - 0x1f | SHIFT, // @ - 0x04 | SHIFT, // A - 0x05 | SHIFT, // B - 0x06 | SHIFT, // C - 0x07 | SHIFT, // D - 0x08 | SHIFT, // E - 0x09 | SHIFT, // F - 0x0a | SHIFT, // G - 0x0b | SHIFT, // H - 0x0c | SHIFT, // I - 0x0d | SHIFT, // J - 0x0e | SHIFT, // K - 0x0f | SHIFT, // L - 0x10 | SHIFT, // M - 0x11 | SHIFT, // N - 0x12 | SHIFT, // O - 0x13 | SHIFT, // P - 0x14 | SHIFT, // Q - 0x15 | SHIFT, // R - 0x16 | SHIFT, // S - 0x17 | SHIFT, // T - 0x18 | SHIFT, // U - 0x19 | SHIFT, // V - 0x1a | SHIFT, // W - 0x1b | SHIFT, // X - 0x1c | SHIFT, // Y - 0x1d | SHIFT, // Z - 0x2f, // [ - 0x31, // bslash - 0x30, // ] - 0x23 | SHIFT, // ^ - 0x2d | SHIFT, // _ - 0x35, // ` - 0x04, // a - 0x05, // b - 0x06, // c - 0x07, // d - 0x08, // e - 0x09, // f - 0x0a, // g - 0x0b, // h - 0x0c, // i - 0x0d, // j - 0x0e, // k - 0x0f, // l - 0x10, // m - 0x11, // n - 0x12, // o - 0x13, // p - 0x14, // q - 0x15, // r - 0x16, // s - 0x17, // t - 0x18, // u - 0x19, // v - 0x1a, // w - 0x1b, // x - 0x1c, // y - 0x1d, // z - 0x2f | SHIFT, // { - 0x31 | SHIFT, // | - 0x30 | SHIFT, // } - 0x35 | SHIFT, // ~ - 0 // DEL -}; - -#define HAS_RGB_LED 1 -#define LED_TYPE SK6812 -#define LED_ORDER GRB -#define LED_TYPE_IS_RGBW 1 -#define LED_COUNT 1 -#define LED_COLOR_STEP 15 - -// Deepsleep -#define DEEPSLEEP_WAKEUP_PIN 0 -#define DEEPSLEEP_PIN_ACT LOW - -#endif /* Pins_Arduino_h */ diff --git a/boards/m5stack-cardputer/interface.cpp b/boards/m5stack-cardputer/interface.cpp index 7a8cedfb12..ee27fcb9ea 100644 --- a/boards/m5stack-cardputer/interface.cpp +++ b/boards/m5stack-cardputer/interface.cpp @@ -1,8 +1,76 @@ #include "core/powerSave.h" +#include +#include +#include #include -#include +// Cardputer and 1.1 keyboard Keyboard_Class Keyboard; +// TCA8418 keyboard controller for ADV variant +Adafruit_TCA8418 tca; +bool UseTCA8418 = false; // Set to true to use TCA8418 (Cardputer ADV) + +// Keyboard state variables +bool fn_key_pressed = false; +bool shift_key_pressed = false; +bool caps_lock = false; + +int handleSpecialKeys(uint8_t row, uint8_t col, bool pressed); +void mapRawKeyToPhysical(uint8_t rawValue, uint8_t &row, uint8_t &col); + +char getKeyChar(uint8_t row, uint8_t col) { + char keyVal; + if (shift_key_pressed ^ caps_lock) { + keyVal = _key_value_map[row][col].value_second; + } else { + keyVal = _key_value_map[row][col].value_first; + } + return keyVal; +} + +int handleSpecialKeys(uint8_t row, uint8_t col, bool pressed) { + char keyVal = _key_value_map[row][col].value_first; + switch (keyVal) { + case 0xFF: + fn_key_pressed = pressed; + if (fn_key_pressed) Serial.println("FN Pressed"); + else Serial.println("FN Released"); + return 1; + case 0x81: + shift_key_pressed = pressed; + if (shift_key_pressed) Serial.println("Shift Pressed"); + else Serial.println("Shift Released"); + if (shift_key_pressed && fn_key_pressed) { + caps_lock = !caps_lock; + if (caps_lock) Serial.println("CAPS Lock activated"); + else Serial.println("CAPS Lock DEactivated"); + shift_key_pressed = false; + fn_key_pressed = false; + } + return 1; + default: break; + } + return 0; +} + +/*************************************************************************************** +** Function name: mapRawKeyToPhysical() +** Location: interface.cpp +** Description: initial mapping for keyboard +***************************************************************************************/ +inline void mapRawKeyToPhysical(uint8_t keyvalue, uint8_t &row, uint8_t &col) { + const uint8_t u = keyvalue % 10; // 1..8 + const uint8_t t = keyvalue / 10; // 0..6 + + if (u >= 1 && u <= 8 && t <= 6) { + const uint8_t u0 = u - 1; // 0..7 + row = u0 & 0x03; // bits [1:0] => 0..3 + col = (t << 1) | (u0 >> 2); // t*2 + bit2(u0) => 0..13 + } else { + row = 0xFF; // invalid + col = 0xFF; + } +} /*************************************************************************************** ** Function name: _setup_gpio() @@ -10,15 +78,54 @@ Keyboard_Class Keyboard; ** Description: initial setup for the device ***************************************************************************************/ void _setup_gpio() { - Keyboard.begin(); + // Keyboard.begin(); pinMode(0, INPUT); - pinMode(10, INPUT); // Pin that reads the + pinMode(10, INPUT); // Pin that reads the Battery voltage + pinMode(5, OUTPUT); + // Set GPIO5 HIGH for SD card compatibility (thx for the tip @bmorcelli & 7h30th3r0n3) + digitalWrite(5, HIGH); } +bool kb_interrupt = false; +void IRAM_ATTR gpio_isr_handler(void *arg) { kb_interrupt = true; } +void _post_setup_gpio() { + // Initialize TCA8418 I2C keyboard controller + Serial.println("DEBUG: Cardputer ADV - Initializing TCA8418 keyboard"); + + // Use correct I2C pins for Cardputer ADV + Serial.printf("DEBUG: Initializing I2C with SDA=%d, SCL=%d\n", TCA8418_SDA_PIN, TCA8418_SCL_PIN); + Wire1.begin(TCA8418_SDA_PIN, TCA8418_SCL_PIN); + delay(100); + + // Scan I2C bus to see what's available + Serial.println("DEBUG: Scanning I2C bus..."); + byte found_devices = 0; + for (byte i = 1; i < 127; i++) { + Wire1.beginTransmission(i); + if (Wire1.endTransmission() == 0) { + Serial.printf("DEBUG: Found I2C device at address 0x%02X\n", i); + found_devices++; + } + } + Serial.printf("DEBUG: Found %d I2C devices\n", found_devices); -#include -#include -#include -#include + // Try to initialize TCA8418 + Serial.printf("DEBUG: Attempting to initialize TCA8418 at address 0x%02X\n", TCA8418_I2C_ADDR); + UseTCA8418 = tca.begin(TCA8418_I2C_ADDR, &Wire1); + + if (!UseTCA8418) { + Serial.println("ADV : Failed to initialize TCA8418!"); + Serial.println("Probable standard Cardputer detected, switching to Keyboard library"); + Wire1.end(); + Keyboard.begin(); + return; + } + + tca.matrix(7, 8); + tca.flush(); + pinMode(11, INPUT); + attachInterruptArg(digitalPinToInterrupt(11), gpio_isr_handler, &kb_interrupt, CHANGE); + tca.enableInterrupts(); +} /*************************************************************************************** ** Function name: getBattery() ** location: display.cpp @@ -26,29 +133,13 @@ void _setup_gpio() { ***************************************************************************************/ int getBattery() { uint8_t percent; - uint8_t _batAdcCh = ADC1_GPIO10_CHANNEL; - uint8_t _batAdcUnit = 1; - static uint32_t lastVolt = 5000; - static unsigned long lastTime = 0; - - adc1_config_width(ADC_WIDTH_BIT_12); - adc1_config_channel_atten((adc1_channel_t)_batAdcCh, ADC_ATTEN_DB_12); - static esp_adc_cal_characteristics_t *adc_chars = nullptr; - static constexpr int BASE_VOLATAGE = 3600; - adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t)); - esp_adc_cal_characterize( - (adc_unit_t)_batAdcUnit, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, BASE_VOLATAGE, adc_chars - ); - int raw; - raw = adc1_get_raw((adc1_channel_t)_batAdcCh); - uint32_t volt = esp_adc_cal_raw_to_voltage(raw, adc_chars); - - float mv = volt * 2; + uint32_t volt = analogReadMilliVolts(GPIO_NUM_10); + + float mv = volt; percent = (mv - 3300) * 100 / (float)(4150 - 3350); return (percent < 0) ? 0 : (percent >= 100) ? 100 : percent; } -bool isCharging() { return false; } /********************************************************************* ** Function: setBrightness @@ -70,74 +161,204 @@ void _setBrightness(uint8_t brightval) { **********************************************************************/ void InputHandler(void) { static unsigned long tm = 0; + + static bool sel = false; + static bool prev = false; + static bool next = false; + static bool up = false; + static bool down = false; + static bool esc = false; + static bool del = false; + + bool arrow_up = false; + bool arrow_dw = false; + bool arrow_ry = false; + bool arrow_le = false; if (millis() - tm < 200 && !LongPress) return; - bool shoulder = digitalRead(0); - Keyboard.update(); - if (Keyboard.isPressed() || shoulder == LOW) { + if (digitalRead(0) == LOW) { // GPIO0 button, shoulder button tm = millis(); - if (!wakeUpScreen()) AnyKeyPress = true; + if (!wakeUpScreen()) yield(); else return; - keyStroke key; - Keyboard_Class::KeysState status = Keyboard.keysState(); - bool arrow_up = false; - bool arrow_dw = false; - bool arrow_ry = false; - bool arrow_le = false; - if (shoulder == LOW) SelPress = true; - for (auto i : status.hid_keys) key.hid_keys.emplace_back(i); - for (auto i : status.word) { - if (i == '`' || i == KEY_BACKSPACE) EscPress = true; - - if (i == ';') { - arrow_up = true; - PrevPress = true; - } - if (i == '.') { - arrow_dw = true; - NextPress = true; - } - if (i == '/') { - arrow_ry = true; - NextPress = true; - NextPagePress = true; + SelPress = true; + AnyKeyPress = true; + } + + if (UseTCA8418) { + if (!kb_interrupt) { + if (!LongPress) { + sel = false; // avoid multiple selections + esc = false; // avoid multiple escapes } - if (i == ',') { - arrow_le = true; - PrevPress = true; - PrevPagePress = true; + NextPress = next; + PrevPress = prev; + UpPress = up; + DownPress = down; + if (!SelPress) SelPress = sel; + EscPress = esc; + if (del) { + KeyStroke.del = del; + KeyStroke.pressed = true; } - if (status.fn && arrow_up) key.word.emplace_back(0xDA); - else if (status.fn && arrow_dw) key.word.emplace_back(0xD9); - else if (status.fn && arrow_ry) key.word.emplace_back(0xD7); - else if (status.fn && arrow_le) key.word.emplace_back(0xD8); - else if (status.fn && i == '`') key.word.emplace_back(0xB1); - else key.word.emplace_back(i); + tm = millis(); + return; } - // Add CTRL, ALT and Tab to keytroke without modifier - key.alt = status.alt; - key.ctrl = status.ctrl; - key.gui = status.opt; - // Add Tab key - if (status.tab) key.word.emplace_back(0xB3); - - for (auto i : status.modifier_keys) key.modifier_keys.emplace_back(i); - skip_mod: - if (status.del) key.del = true; - if (status.enter) { - key.enter = true; - key.exit_key = true; - SelPress = true; + + // try to clear the IRQ flag + // if there are pending events it is not cleared + tca.writeRegister(TCA8418_REG_INT_STAT, 1); + int intstat = tca.readRegister(TCA8418_REG_INT_STAT); + if ((intstat & 0x01) == 0) { kb_interrupt = false; } + + if (tca.available() <= 0) return; + int keyEvent = tca.getEvent(); + bool pressed = (keyEvent & 0x80); // Bit 7: 1 Pressed, 0 Released + uint8_t value = keyEvent & 0x7F; // Bits 0-6: key value + + // Map raw value to physical position + uint8_t row, col; + mapRawKeyToPhysical(value, row, col); + + // Serial.printf("Key event: raw=%d, pressed=%d, row=%d, col=%d\n", value, pressed, row, col); + + if (row >= 4 || col >= 14) return; + + if (wakeUpScreen()) return; + + AnyKeyPress = true; + + if (handleSpecialKeys(row, col, pressed) > 0) return; + + if (!pressed) { + KeyStroke.Clear(); + LongPress = false; } - if (status.fn) key.fn = true; - if (key.fn && key.del) { + + keyStroke key; + char keyVal = getKeyChar(row, col); + + // Serial.printf("Key pressed: %c (0x%02X) at row=%d, col=%d\n", keyVal, keyVal, row, col); + + if (keyVal == KEY_BACKSPACE) { + del = pressed; + esc = pressed; + } else if (keyVal == '`') { + esc = pressed; + } else if (keyVal == KEY_ENTER) { + key.enter = pressed; + key.exit_key = pressed; + sel = pressed; + } else if (keyVal == ',' || keyVal == ';') { + prev = pressed; + if (keyVal == ',') arrow_le = pressed; + if (keyVal == ';') arrow_up = pressed; + } else if (keyVal == '/' || keyVal == '.') { + next = pressed; + if (keyVal == '/') arrow_ry = pressed; + if (keyVal == '.') arrow_dw = pressed; + } else if (keyVal == 0xFF) { + key.fn = pressed; + } else if (keyVal == KEY_LEFT_SHIFT) { + if (pressed) key.modifier_keys.emplace_back(KEY_LEFT_SHIFT); + } else if (keyVal == KEY_LEFT_CTRL) { + key.ctrl = pressed; + if (pressed) key.modifier_keys.emplace_back(KEY_LEFT_CTRL); + } else if (keyVal == KEY_LEFT_ALT) { + key.alt = pressed; + if (pressed) key.modifier_keys.emplace_back(KEY_LEFT_ALT); + } else if (keyVal == KEY_OPT) { + key.gui = pressed; + if (pressed) key.modifier_keys.emplace_back(KEY_OPT); + } + if (key.modifier_keys.size() == 0 && keyVal != 0xFF && keyVal != KEY_BACKSPACE && + keyVal != KEY_ENTER && keyVal != KEY_OPT) { + if (fn_key_pressed && arrow_up) key.word.emplace_back(0xDA); + else if (fn_key_pressed && arrow_dw) key.word.emplace_back(0xD9); + else if (fn_key_pressed && arrow_ry) key.word.emplace_back(0xD7); + else if (fn_key_pressed && arrow_le) key.word.emplace_back(0xD8); + else if (fn_key_pressed && keyVal == '`') key.word.emplace_back(0xB1); + else key.word.emplace_back(keyVal); + } + key.pressed = pressed; + if (del) { + key.del = del; + key.pressed = true; + } + if (fn_key_pressed && del) { key.word.emplace_back(0xD4); key.del = false; key.fn = false; + del = false; + fn_key_pressed = false; } - key.pressed = true; KeyStroke = key; - } else KeyStroke.Clear(); + NextPress = next; + PrevPress = prev; + UpPress = up; + DownPress = down; + SelPress = sel; + EscPress = esc; + tm = millis(); + } else { + if (Keyboard.isPressed()) { + tm = millis(); + if (!wakeUpScreen()) AnyKeyPress = true; + else return; + keyStroke key; + Keyboard_Class::KeysState status = Keyboard.keysState(); + for (auto i : status.hid_keys) key.hid_keys.emplace_back(i); + for (auto i : status.word) { + if (i == '`' || i == KEY_BACKSPACE) EscPress = true; + + if (i == ';') { + arrow_up = true; + PrevPress = true; + } + if (i == '.') { + arrow_dw = true; + NextPress = true; + } + if (i == '/') { + arrow_ry = true; + NextPress = true; + NextPagePress = true; + } + if (i == ',') { + arrow_le = true; + PrevPress = true; + PrevPagePress = true; + } + if (status.fn && arrow_up) key.word.emplace_back(0xDA); + else if (status.fn && arrow_dw) key.word.emplace_back(0xD9); + else if (status.fn && arrow_ry) key.word.emplace_back(0xD7); + else if (status.fn && arrow_le) key.word.emplace_back(0xD8); + else if (status.fn && i == '`') key.word.emplace_back(0xB1); + else key.word.emplace_back(i); + } + // Add CTRL, ALT and Tab to keytroke without modifier + key.alt = status.alt; + key.ctrl = status.ctrl; + key.gui = status.opt; + // Add Tab key + if (status.tab) key.word.emplace_back(0xB3); + + for (auto i : status.modifier_keys) key.modifier_keys.emplace_back(i); + if (status.del) key.del = true; + if (status.enter) { + key.enter = true; + key.exit_key = true; + SelPress = true; + } + if (status.fn) key.fn = true; + if (key.fn && key.del) { + key.word.emplace_back(0xD4); + key.del = false; + key.fn = false; + } + key.pressed = true; + KeyStroke = key; + } else KeyStroke.Clear(); + } } /********************************************************************* diff --git a/boards/m5stack-cardputer/m5stack-cardputer.ini b/boards/m5stack-cardputer/m5stack-cardputer.ini index 9c2339082f..1dae3c4896 100644 --- a/boards/m5stack-cardputer/m5stack-cardputer.ini +++ b/boards/m5stack-cardputer/m5stack-cardputer.ini @@ -17,6 +17,11 @@ build_flags = -Iboards/m5stack-cardputer -DCORE_DEBUG_LEVEL=5 + -DTCA8418_INT_PIN=11 + -DTCA8418_I2C_ADDR=0x34 + -DTCA8418_SDA_PIN=8 + -DTCA8418_SCL_PIN=9 + ;Features Enabled ;-DLITE_VERSION=1 ;limits some features to save space for M5Launcher Compatibility ;Microphone @@ -58,15 +63,15 @@ build_flags = ;-DALLOW_ALL_GPIO_FOR_IR_RF=1 ; Set this option to make use of all GPIOs, from 1 to 44 to be chosen, except TFT and SD pins ;Infrared Led default pin and state - -DIR_TX_PINS='{ {"Default", LED}, {"M5 IR Mod", GROVE_SDA}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' - -DIR_RX_PINS='{ {"M5 IR Mod", GROVE_SCL}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' + -DIR_TX_PINS='{ {"Default", LED}, {"M5 IR Mod", GROVE_SDA}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}, {"ADV 3", 3},{"ADV 4", 4},{"ADV 5", 5},{"ADV 6", 6},{"ADV 13", 13},{"ADV 15", 15} }' + -DIR_RX_PINS='{ {"M5 IR Mod", GROVE_SCL}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA},{"ADV 3", 3},{"ADV 4", 4},{"ADV 5", 5},{"ADV 6", 6},{"ADV 13", 13},{"ADV 15", 15}}' -DLED=44 -DLED_ON=HIGH -DLED_OFF=LOW ;Radio Frequency (one pin modules) pin setting - -DRF_TX_PINS='{ {"M5 RF433T", GROVE_SDA}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' - -DRF_RX_PINS='{ {"M5 RF433R", GROVE_SCL}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA}}' + -DRF_TX_PINS='{ {"M5 RF433T", GROVE_SDA}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA},{"ADV 3", 3},{"ADV 4", 4},{"ADV 5", 5},{"ADV 6", 6},{"ADV 13", 13},{"ADV 15", 15}}' + -DRF_RX_PINS='{ {"M5 RF433R", GROVE_SCL}, {"Grove W", GROVE_SCL}, {"Grove Y", GROVE_SDA},{"ADV 3", 3},{"ADV 4", 4},{"ADV 5", 5},{"ADV 6", 6},{"ADV 13", 13},{"ADV 15", 15}}' ; connection pins using microSD sniffer module https://www.sparkfun.com/products/9419 https://docs.m5stack.com/en/core/Cardputer -DUSE_CC1101_VIA_SPI -DCC1101_GDO0_PIN=GROVE_SDA @@ -138,3 +143,4 @@ build_flags = lib_deps = ${env.lib_deps} fastled/FastLED @3.9.4 + adafruit/Adafruit TCA8418 @ ^1.0.2 diff --git a/build.py b/build.py index 3f536ea35c..310c16027b 100644 --- a/build.py +++ b/build.py @@ -1,4 +1,5 @@ from pathlib import Path +import csv from SCons.Script import Import # Import PlatformIO's SCons environment @@ -58,6 +59,45 @@ def _merge_bins_callback(target, source, env): # Quote paths for Windows safety def q(p): return f"\"{p}\"" + # ---- Read partition CSV to get test partition size and ota_0 offset ---- + part_csv_name = board_config.get("build.partitions") or env.GetProjectOption( + "board_build.partitions", default="" + ) + part_csv = proj_dir / part_csv_name if part_csv_name else proj_dir / "partitions.csv" + ota_size = None + ota0_offset = None + if part_csv.exists(): + with open(part_csv, newline="") as f: + reader = csv.reader(f) + for row in reader: + if not row or row[0].startswith("#"): + continue + cols = [c.strip() for c in row] + if len(cols) < 5: + continue + name, ptype, subtype, offset, size = cols[:5] + subtype = subtype.lower() + if subtype == "ota_0" and ota_size is None: + try: + ota_size = int(size, 0) + ota0_offset = int(offset, 0) + except ValueError: + pass + + # ---- Firmware size check against test partition ---- + if ota_size: + fw_size = app_bin.stat().st_size + percent = (fw_size / ota_size) * 100 if ota_size else 0 + bar_len = 20 + filled = int(bar_len * fw_size / ota_size) + bar = "=" * filled + " " * (bar_len - filled) + print( + f"BRUCE: [{bar}] {percent:.1f}% (used 0x{fw_size:X} bytes of 0x{ota_size:X} of OTA partition)" + ) + if fw_size > ota_size: + print("[merge_bin] Error: firmware.bin exceeds OTA partition size") + env.Exit(1) + cmd = " ".join([ "pio pkg exec -p \"tool-esptoolpy\" -- esptool.py", "--chip", chip_arg, @@ -73,12 +113,21 @@ def q(p): return f"\"{p}\"" rc = env.Execute(cmd) if rc != 0: print(f"[merge_bin] Failed with exit code {rc}") + env.Exit(rc) else: try: size = out_bin.stat().st_size except FileNotFoundError: size = 0 print(f"[merge_bin] Success -> {out_bin} ({size} bytes)") + if ota0_offset: + if size < (ota0_offset + ota_size): + print("[Final bin] Valid bin to upload") + else: + print( + f"[Final bin] Error: bin size 0x{size:X} exceeds ota_0 offset 0x{(ota0_offset+ota_size):X}" + ) + env.Exit(1) # Automatically run after firmware.bin is generated senv.AddPostAction(str(app_bin), _merge_bins_callback) diff --git a/platformio.ini b/platformio.ini index 8b5e00c99e..0f5f875be9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -123,9 +123,9 @@ lib_deps = https://github.com/rennancockles/ESP-ChameleonUltra https://github.com/rennancockles/ESP-Amiibolink https://github.com/rennancockles/SimpleCLI - https://github.com/whywilson/ESP-PN532BLE + https://github.com/whywilson/ESP-PN532BLE#5d6cd47ddacf8a6e460bc3476ad6ab4c24816890 https://github.com/whywilson/ESP-PN532-UART@^0.0.2 - https://github.com/whywilson/ESP-PN532Killer@^0.0.6 + https://github.com/whywilson/ESP-PN532Killer@^0.0.7 NTPClient Timezone ESP32Time From 314a3bc690407044f570f094b1fcf45dd2a9f87c Mon Sep 17 00:00:00 2001 From: Pirata Date: Thu, 25 Sep 2025 06:02:42 -0300 Subject: [PATCH 2/5] sha --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 0f5f875be9..2f33cee6b2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -125,7 +125,7 @@ lib_deps = https://github.com/rennancockles/SimpleCLI https://github.com/whywilson/ESP-PN532BLE#5d6cd47ddacf8a6e460bc3476ad6ab4c24816890 https://github.com/whywilson/ESP-PN532-UART@^0.0.2 - https://github.com/whywilson/ESP-PN532Killer@^0.0.7 + https://github.com/whywilson/ESP-PN532Killer@#de149e1f15cf8225cae3fdddfe659b192831ecff NTPClient Timezone ESP32Time From 6590e208569a47529982a953e6ad3d1af6a8203f Mon Sep 17 00:00:00 2001 From: Pirata <104320209+bmorcelli@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:17:05 -0300 Subject: [PATCH 3/5] Update platformio.ini --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 2f33cee6b2..2d9ec7df2e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -125,7 +125,7 @@ lib_deps = https://github.com/rennancockles/SimpleCLI https://github.com/whywilson/ESP-PN532BLE#5d6cd47ddacf8a6e460bc3476ad6ab4c24816890 https://github.com/whywilson/ESP-PN532-UART@^0.0.2 - https://github.com/whywilson/ESP-PN532Killer@#de149e1f15cf8225cae3fdddfe659b192831ecff + https://github.com/whywilson/ESP-PN532Killer#de149e1f15cf8225cae3fdddfe659b192831ecff NTPClient Timezone ESP32Time From b66bf160e6a5d7aea861a5df7aa992e559b8a8d7 Mon Sep 17 00:00:00 2001 From: Pirata Date: Thu, 25 Sep 2025 17:13:33 -0300 Subject: [PATCH 4/5] Cardputer ADV Pin setup --- boards/ESP-General/ESP-General.ini | 1 + boards/m5stack-cardputer/interface.cpp | 8 +- custom_4Mb_full.csv | 4 +- src/core/configPins.cpp | 55 ++++++++++++- src/core/configPins.h | 49 ++++++++++- src/core/i2c_finder.cpp | 4 +- src/core/menu_items/ConfigMenu.cpp | 6 +- src/core/menu_items/GpsMenu.cpp | 5 +- src/core/serial_commands/util_commands.cpp | 78 +++++++++--------- src/core/settings.cpp | 94 ++++++++++++++++++++++ src/core/settings.h | 4 + src/core/utils.cpp | 8 +- src/modules/gps/gps_tracker.cpp | 8 +- src/modules/gps/wardriving.cpp | 8 +- src/modules/rfid/PN532.cpp | 11 +-- src/modules/rfid/RFID2.cpp | 4 +- src/modules/rfid/rfid125.h | 4 +- 17 files changed, 284 insertions(+), 67 deletions(-) diff --git a/boards/ESP-General/ESP-General.ini b/boards/ESP-General/ESP-General.ini index 9286b0d2c0..8de8b8e667 100644 --- a/boards/ESP-General/ESP-General.ini +++ b/boards/ESP-General/ESP-General.ini @@ -25,6 +25,7 @@ extends = env:esp32-s3-devkitc-1 [env:esp32-s3-devkitc-1] board = ESP-General +board_build.partitions = custom_8Mb.csv build_src_filter =${env.build_src_filter} +<../boards/ESP-General> build_flags = ${env.build_flags} diff --git a/boards/m5stack-cardputer/interface.cpp b/boards/m5stack-cardputer/interface.cpp index ee27fcb9ea..e800148b14 100644 --- a/boards/m5stack-cardputer/interface.cpp +++ b/boards/m5stack-cardputer/interface.cpp @@ -119,6 +119,9 @@ void _post_setup_gpio() { Keyboard.begin(); return; } + bruceConfigPins.gps_bus.rx = (gpio_num_t)15; + bruceConfigPins.gps_bus.tx = (gpio_num_t)13; + bruceConfig.gpsBaudrate = 115200; tca.matrix(7, 8); tca.flush(); @@ -229,10 +232,7 @@ void InputHandler(void) { if (handleSpecialKeys(row, col, pressed) > 0) return; - if (!pressed) { - KeyStroke.Clear(); - LongPress = false; - } + if (!pressed) { KeyStroke.Clear(); } keyStroke key; char keyVal = getKeyChar(row, col); diff --git a/custom_4Mb_full.csv b/custom_4Mb_full.csv index 651accff9d..446ccd64ce 100644 --- a/custom_4Mb_full.csv +++ b/custom_4Mb_full.csv @@ -1,4 +1,4 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x6000, -app0, app, ota_0, 0x10000, 0x380000, -spiffs, data, spiffs, 0x390000,0x70000, \ No newline at end of file +app0, app, ota_0, 0x10000, 0x390000, +spiffs, data, spiffs, 0x3A0000,0x60000, diff --git a/src/core/configPins.cpp b/src/core/configPins.cpp index 42064187d1..6bd21cb283 100644 --- a/src/core/configPins.cpp +++ b/src/core/configPins.cpp @@ -1,6 +1,5 @@ #include "configPins.h" #include "sd_functions.h" - String getMacAddress() { uint8_t mac[6]; esp_read_mac(mac, ESP_MAC_WIFI_STA); @@ -47,6 +46,30 @@ void BruceConfigPins::fromJson(JsonObject obj) { log_e("Fail"); } #endif + // if (!root["sys_i2c"].isNull()) { + // sys_i2c.fromJson(root["sys_i2c"].as()); + // } else { + // count++; + // log_e("Fail"); + // } + if (!root["i2c_bus"].isNull()) { + i2c_bus.fromJson(root["i2c_bus"].as()); + } else { + count++; + log_e("Fail"); + } + if (!root["uart_bus"].isNull()) { + uart_bus.fromJson(root["uart_bus"].as()); + } else { + count++; + log_e("Fail"); + } + if (!root["GPS_bus"].isNull()) { + gps_bus.fromJson(root["GPS_bus"].as()); + } else { + count++; + log_e("Fail"); + } validateConfig(); if (count > 0) saveFile(); } @@ -66,6 +89,14 @@ void BruceConfigPins::toJson(JsonObject obj) const { JsonObject _W5500 = root["W5500_Pins"].to(); W5500_bus.toJson(_W5500); #endif + // JsonObject _si2c = root["sys_i2c"].as(); + // sys_i2c.toJson(_si2c); + JsonObject _di2c = root["i2c_bus"].to(); + i2c_bus.toJson(_di2c); + JsonObject _uart = root["uart_bus"].to(); + uart_bus.toJson(_uart); + JsonObject _gps = root["GPS_bus"].to(); + gps_bus.toJson(_gps); } void BruceConfigPins::loadFile(JsonDocument &jsonDoc, bool checkFS) { @@ -162,6 +193,9 @@ void BruceConfigPins::validateConfig() { validateSpiPins(CC1101_bus); validateSpiPins(NRF24_bus); validateSpiPins(SDCARD_bus); + validateI2CPins(i2c_bus); + validateUARTPins(uart_bus); + validateUARTPins(gps_bus); } void BruceConfigPins::setCC1101Pins(SPIPins value) { @@ -187,6 +221,15 @@ void BruceConfigPins::setSpiPins(SPIPins value) { saveFile(); } +void BruceConfigPins::setI2CPins(I2CPins value) { + validateI2CPins(value); + saveFile(); +} + +void BruceConfigPins::setUARTPins(UARTPins value) { + validateUARTPins(value); + saveFile(); +} void BruceConfigPins::validateSpiPins(SPIPins value) { if (value.sck < 0 || value.sck > GPIO_PIN_COUNT) value.sck = GPIO_NUM_NC; if (value.miso < 0 || value.miso > GPIO_PIN_COUNT) value.miso = GPIO_NUM_NC; @@ -195,3 +238,13 @@ void BruceConfigPins::validateSpiPins(SPIPins value) { if (value.io0 < 0 || value.io0 > GPIO_PIN_COUNT) value.io0 = GPIO_NUM_NC; if (value.io2 < 0 || value.io2 > GPIO_PIN_COUNT) value.io2 = GPIO_NUM_NC; } + +void BruceConfigPins::validateI2CPins(I2CPins value) { + if (value.sda < 0 || value.sda > GPIO_PIN_COUNT) value.sda = GPIO_NUM_NC; + if (value.scl < 0 || value.scl > GPIO_PIN_COUNT) value.scl = GPIO_NUM_NC; +} + +void BruceConfigPins::validateUARTPins(UARTPins value) { + if (value.rx < 0 || value.rx > GPIO_PIN_COUNT) value.rx = GPIO_NUM_NC; + if (value.tx < 0 || value.tx > GPIO_PIN_COUNT) value.tx = GPIO_NUM_NC; +} diff --git a/src/core/configPins.h b/src/core/configPins.h index 0e3a07842a..ef863eb891 100644 --- a/src/core/configPins.h +++ b/src/core/configPins.h @@ -2,13 +2,51 @@ #include #include - +#include #ifndef CC1101_GDO2_PIN #define CC1101_GDO2_PIN -1 #endif class BruceConfigPins { public: + struct UARTPins { + gpio_num_t rx = GPIO_NUM_NC; + gpio_num_t tx = GPIO_NUM_NC; + + UARTPins() : rx(GPIO_NUM_NC), tx(GPIO_NUM_NC) {} + + UARTPins(gpio_num_t rx = GPIO_NUM_NC, gpio_num_t tx = GPIO_NUM_NC) : rx(rx), tx(tx) {} + + void fromJson(JsonObject obj) { + rx = (gpio_num_t)(obj["rx"] | (int)GPIO_NUM_NC); + tx = (gpio_num_t)(obj["tx"] | (int)GPIO_NUM_NC); + } + + void toJson(JsonObject obj) const { + obj["rx"] = rx; + obj["tx"] = tx; + } + }; + + struct I2CPins { + gpio_num_t sda = GPIO_NUM_NC; + gpio_num_t scl = GPIO_NUM_NC; + + I2CPins() : sda(GPIO_NUM_NC), scl(GPIO_NUM_NC) {} + + I2CPins(gpio_num_t sda = GPIO_NUM_NC, gpio_num_t scl = GPIO_NUM_NC) : sda(sda), scl(scl) {} + + void fromJson(JsonObject obj) { + sda = (gpio_num_t)(obj["sda"] | (int)GPIO_NUM_NC); + scl = (gpio_num_t)(obj["scl"] | (int)GPIO_NUM_NC); + } + + void toJson(JsonObject obj) const { + obj["sda"] = sda; + obj["scl"] = scl; + } + }; + struct SPIPins { gpio_num_t sck = GPIO_NUM_NC; gpio_num_t miso = GPIO_NUM_NC; @@ -94,6 +132,11 @@ class BruceConfigPins { SPIPins W5500_bus; #endif + // I2CPins sys_i2c = {(gpio_num_t)GROVE_SDA, (gpio_num_t)GROVE_SCL}; + I2CPins i2c_bus = {(gpio_num_t)GROVE_SDA, (gpio_num_t)GROVE_SCL}; + UARTPins uart_bus = {(gpio_num_t)SERIAL_RX, (gpio_num_t)SERIAL_TX}; + UARTPins gps_bus = {(gpio_num_t)GPS_SERIAL_RX, (gpio_num_t)GPS_SERIAL_TX}; + ///////////////////////////////////////////////////////////////////////////////////// // Constructor ///////////////////////////////////////////////////////////////////////////////////// @@ -116,5 +159,9 @@ class BruceConfigPins { void setSDCardPins(SPIPins value); void setSpiPins(SPIPins value); + void setI2CPins(I2CPins value); + void setUARTPins(UARTPins value); void validateSpiPins(SPIPins value); + void validateI2CPins(I2CPins value); + void validateUARTPins(UARTPins value); }; diff --git a/src/core/i2c_finder.cpp b/src/core/i2c_finder.cpp index 258ff00b4b..7ac207c0dd 100644 --- a/src/core/i2c_finder.cpp +++ b/src/core/i2c_finder.cpp @@ -12,7 +12,7 @@ void find_i2c_addresses() { padprintln(""); bool first_found = true; - Wire.begin(GROVE_SDA, GROVE_SCL); + Wire.begin(bruceConfigPins.i2c_bus.sda, bruceConfigPins.i2c_bus.scl); padprintln("Checking I2C addresses ...\n\n"); delay(300); @@ -45,7 +45,7 @@ uint8_t find_first_i2c_address() { } bool check_i2c_address(uint8_t i2c_address) { - Wire.begin(GROVE_SDA, GROVE_SCL); + Wire.begin(bruceConfigPins.i2c_bus.sda, bruceConfigPins.i2c_bus.scl); Wire.beginTransmission(i2c_address); int error = Wire.endTransmission(); return (error == 0); diff --git a/src/core/menu_items/ConfigMenu.cpp b/src/core/menu_items/ConfigMenu.cpp index 99561ca918..25c8ef6bdf 100644 --- a/src/core/menu_items/ConfigMenu.cpp +++ b/src/core/menu_items/ConfigMenu.cpp @@ -56,7 +56,7 @@ void ConfigMenu::optionsMenu() { options.push_back({"Turn-off", powerOff}); options.push_back({"Deep Sleep", goToDeepSleep}); - if (bruceConfig.devMode) options.push_back({"Dev Mode", [=]() { devMenu(); }}); + if (bruceConfig.devMode) options.push_back({"Device Pin setting", [=]() { devMenu(); }}); options.push_back({"About", showDeviceInfo}); addOptionToMainMenu(); @@ -70,6 +70,10 @@ void ConfigMenu::devMenu() { {"CC1101 Pins", [=]() { setSPIPinsMenu(bruceConfigPins.CC1101_bus); }}, {"NRF24 Pins", [=]() { setSPIPinsMenu(bruceConfigPins.NRF24_bus); } }, {"SDCard Pins", [=]() { setSPIPinsMenu(bruceConfigPins.SDCARD_bus); }}, + //{"SYSI2C Pins", [=]() { setI2CPinsMenu(bruceConfigPins.sys_i2c); } }, + {"I2C Pins", [=]() { setI2CPinsMenu(bruceConfigPins.i2c_bus); } }, + {"UART Pins", [=]() { setUARTPinsMenu(bruceConfigPins.uart_bus); } }, + {"GPS Pins", [=]() { setUARTPinsMenu(bruceConfigPins.gps_bus); } }, {"Back", [=]() { optionsMenu(); } }, }; diff --git a/src/core/menu_items/GpsMenu.cpp b/src/core/menu_items/GpsMenu.cpp index 637920e9bb..35ed004c75 100644 --- a/src/core/menu_items/GpsMenu.cpp +++ b/src/core/menu_items/GpsMenu.cpp @@ -20,8 +20,9 @@ void GpsMenu::optionsMenu() { void GpsMenu::configMenu() { options = { - {"Baudrate", setGpsBaudrateMenu }, - {"Back", [=]() { optionsMenu(); }}, + {"Baudrate", setGpsBaudrateMenu }, + {"GPS Pins", [=]() { setUARTPinsMenu(bruceConfigPins.gps_bus); }}, + {"Back", [=]() { optionsMenu(); } }, }; loopOptions(options, MENU_TYPE_SUBMENU, "GPS Config"); diff --git a/src/core/serial_commands/util_commands.cpp b/src/core/serial_commands/util_commands.cpp index 54b20af9bf..510b472d18 100644 --- a/src/core/serial_commands/util_commands.cpp +++ b/src/core/serial_commands/util_commands.cpp @@ -1,10 +1,10 @@ #include "util_commands.h" -#include "core/utils.h" // to return optionsJSON +#include "core/main_menu.h" +#include "core/sd_functions.h" +#include "core/utils.h" // to return optionsJSON +#include "core/wifi/webInterface.h" #include "core/wifi/wifi_common.h" //to return MAC addr #include "modules/badusb_ble/ducky_typer.h" -#include "core/wifi/webInterface.h" -#include "core/sd_functions.h" -#include "core/main_menu.h" #include #include @@ -56,7 +56,7 @@ uint32_t dateCallback(cmd *c) { uint32_t i2cCallback(cmd *c) { // scan for connected i2c modules // derived from https://learn.adafruit.com/scanning-i2c-addresses/arduino - Wire.begin(GROVE_SDA, GROVE_SCL); + Wire.begin(bruceConfigPins.i2c_bus.sda, bruceConfigPins.i2c_bus.scl); byte error, address; int nDevices; Serial.println("Scanning..."); @@ -140,34 +140,45 @@ uint32_t helpCallback(cmd *c) { Serial.println(" ir rx raw - Read an IR signal in RAW mode and print the dump on serial."); Serial.println(" ir tx
- Send a custom decoded IR signal."); Serial.println(" ir tx_from_file - Send an IR signal saved in storage."); - + Serial.println("\nRF Commands:"); - Serial.println(" subghz rx - Read an RF signal and print the dump on serial. (alias: rf rx)"); - Serial.println(" subghz rx raw - Read an RF signal in RAW mode and print the dump on serial. (alias: rf rx raw)"); - Serial.println(" subghz tx - Send a custom decoded RF signal. (alias: rf tx)"); + Serial.println( + " subghz rx - Read an RF signal and print the dump on serial. (alias: rf rx)" + ); + Serial.println( + " subghz rx raw - Read an RF signal in RAW mode and print the dump on serial. (alias: " + "rf rx raw)" + ); + Serial.println( + " subghz tx - Send a custom decoded RF signal. (alias: rf " + "tx)" + ); Serial.println(" subghz tx_from_file - Send an RF signal saved in storage."); - + Serial.println("\nAudio Commands:"); Serial.println(" music_player