T-Deck Pro support
Implementation status (standard UI)
- [x] E-Ink display GxEPD2_310_GDEQ031T10
- [x] Touch driver CST328
- [x] LoRa Radio SX1262/SX1268
- [x] TCA8418 keyboard
- [x] GPS M10Q
- [x] SD card
- [x] BQ25896 battery fast charger
- [ ] BQ27220 battery fuel gauge
- [ ] LTR-553ALS light sensor
- [ ] BHI260AP gyroscope (self-learning AI fitness tracker)
Note: reused keyboard code provided by @Szetya 🙏
🤝 Attestations
- [x] I have tested that my proposed changes behave as described.
- [ ] I have tested that my proposed changes do not cause any obvious regressions on the following devices:
- [ ] Heltec (Lora32) V3
- [x] LilyGo T-Deck
- [ ] LilyGo T-Beam
- [ ] RAK WisBlock 4631
- [ ] Seeed Studio T-1000E tracker card
- [ ] Other (please specify below)
CannedMessage module function (keys) are missing currently.
The BQ27220 does not provide useful information.
OperationConfigA Values:0x0
External Thermistor Selected: NO
BATT_GD Pin Polarity High: NO
BATT_GD Function Enabled: NO
Can Enter SLEEP State: NO
slpwakechg Function Enabled: NO
Write Temperature Function Enabled: NO
Battery Insertion Detection Enabled: NO
Battery Insertion Pin Pull - Up Enabled: NO
Pin Function Code (PFC) Mode: 0
Wake - Up Function Enabled: NO
Wake - Up Threshold 1: 0
Wake - Up Threshold 0: 0
OperationConfigB Values:0x0
Default Seal Option Enabled: NO
Non - Removable Option Set: NO
INT_BREM Function Enabled: NO
INT_BATL Function Enabled: NO
INT_STATE Function Enabled: NO
INT_OCV Function Enabled: NO
INT_OT Function Enabled: NO
INT_POL Function Enabled (High - Level Polarity): NO
INT_FOCV Function Enabled: NO
Standard query:
- AtRate:0 mA
- AtRateTimeToEmpty:0 minutes
- Temperature:-273.15 ℃
- BatteryVoltage:0 mV
- InstantaneousCurrent:0 mAh
- RemainingCapacity:0 mAh
- FullChargeCapacity:0 mAh
- DesignCapacity:0 mAh
- TimeToEmpty:0 minutes
- TimeToFull:0 minutes
- StandbyCurrent:0 mA
- StandbyTimeToEmpty:0 minutes
- MaxLoadCurrent:0 mA
- MaxLoadTimeToEmpty:0 minute
- RawCoulombCount:0 mAh
- AveragePower:0 mW
- InternalTemperature:-273.15 ℃
- CycleCount:0
- StateOfCharge:0 %
- StateOfHealth:0 %
- RequestChargingVoltage:0 mV
- RequestChargingCurrent:0 mA
- BTPDischargeSet:0 mAh
- BTPChargeSet:0 mAh
Operation Status:
- getIsConfigUpdateMode:NO
- getIsBtpThresholdExceeded:NO
- getIsCapacityAccumulationThrottled:NO
- getIsInitializationComplete:NO
- getIsDischargeCycleCompliant:NO
- getIsBatteryVoltageBelowEdv2:NO
- getSecurityAccessLevel:0
- getIsCalibrationModeEnabled:NO
Battery Status:
===============================================
TCA8418 treatment is a bit better but still needs some work. There is a modifierFlag variable for the modifier keys, so the TCA8418TapMap can have 7 columns. Shift: modifierFlag bit 1 alt: modifierFlag bit 2 Sym: modifierFlag bit 3 src_input.zip The formatting needs a little tweaking. . :)
I can confirm that this is somewhat working today, as-is. Keyboard input is very slow and the shift keys don't work (but you can double-tap a letter to make it caps). Backspace and enter work. You can send and receive messages through the radio.
It's not polished yet, but it does actually function as a standalone device with keyboard, screen, radio, and buzzer notifications.
This is awesome. My little TDP is alive and usable for the first time now! Thank you both for getting it to this point!
I can confirm that this is somewhat working today, as-is. Keyboard input is very slow and the shift keys don't work (but you can double-tap a letter to make it caps). Backspace and enter work. You can send and receive messages through the radio.
It's not polished yet, but it does actually function as a standalone device with keyboard, screen, radio, and buzzer notifications.
This is awesome. My little TDP is alive and usable for the first time now! Thank you both for getting it to this point!
Try the contents of the zip file. The code is a bit messy but it works better. Shift, alt, Sym too.
These firmware updates are for the T-Deck Pro "4G" version or the "voice" version? Or is it irrelevant? Thank you.
@Szetya Yep, that's a nice improvement.
@adrianTNT I'm using it on the 4G.
@adrianTNT It is irrelevant at the moment because neither option is supported. It will probably have to be split later as it uses common PINs.
Has anyone disassembled it yet? 😉 LTR553ALS location found? I ordered from aliexpress. Also plan on installing a BME280 or BME688 once I take the time.
@Nasimovy You may try if the refactored class is still working with your keyboard device 😅
@Nasimovy You may try if the refactored class is still working with your keyboard device 😅
WAO! I'll look at this tomorrow on t-deck pro. The value of modifierFalg can be up to 7 at the moment (shift + alt + sym) so the tapMap array can be up to 7+1 columns. There are plenty of possibilities to handle special events or use special characters. And the two shifts can be handled separately and then 15+1 combinations are possible for each key (which is a lot) 😂 (The t-lora pager is coming soon. Version 868MHz is already available on the official site (ordered today))
WAO! I'll look at this tomorrow on t-deck pro. The value of modifierFalg can be up to 7 at the moment (shift + alt + sym) so the tapMap array can be up to 7+1 columns.
I tried to use the same keys as on the T-Deck with quite similar behavior. The only difference is that instead of ALT+C - key now can use ALT+key directly.
TCA8418 is capable of requesting 3 buttons at once (under certain matrix rules) which is not currently used and I don't think it is needed. Currently shift increases the modifierFalg value by 1, alt by 2 and sym by 4. Before the _TCA8418_MULTI_TAP_THRESHOLD time expires, the modifier keys can be pressed in sequence to use different combinations e.g. shift & alt & key. Which gives the index of the third key of tapMap. It would be a good idea to have some information about the state of the modifierFalg on the display but the top line of the display is full.
TCA8418 is capable of requesting 3 buttons at once (under certain matrix rules) which is not currently used and I don't think it is needed. Currently shift increases the modifierFalg value by 1, alt by 2 and sym by 4. Before the _TCA8418_MULTI_TAP_THRESHOLD time expires, the modifier keys can be pressed in sequence to use different combinations e.g. shift & alt & key. Which gives the index of the third key of tapMap. It would be a good idea to have some information about the state of the modifierFalg on the display but the top line of the display is full.
I've modified all this already, i.e. implemented the multi-key press and removed the long press which we don't use on T-Deck. I guess nobody wants to press more than one modifier key in sequence which would also simplify the logic and the programming. What is currently not working is that the shift key can be held while typing a series of capital alphabetic characters. Looks like an issue with the modifier state. From what you are suggesting I assume you've never worked with a T-Deck, right?
TCA8418 is capable of requesting 3 buttons at once (under certain matrix rules) which is not currently used and I don't think it is needed. Currently shift increases the modifierFalg value by 1, alt by 2 and sym by 4. Before the _TCA8418_MULTI_TAP_THRESHOLD time expires, the modifier keys can be pressed in sequence to use different combinations e.g. shift & alt & key. Which gives the index of the third key of tapMap. It would be a good idea to have some information about the state of the modifierFalg on the display but the top line of the display is full.
I've modified all this already, i.e. implemented the multi-key press and removed the long press which we don't use on T-Deck. I guess nobody wants to press more than one modifier key in sequence which would also simplify the logic and the programming. What is currently not working is that the shift key can be held while typing a series of capital alphabetic characters. Looks like an issue with the modifier state. From what you are suggesting I assume you've never worked with a T-Deck, right?
For me, it was not uncomfortable to press several buttons in a row during my tests. The beauty of it all is that you can approach the same thing in different ways. 😉 I have no problem with your solution, that's not why I wrote it. I haven't tried your version yet (I'll take the time this afternoon). I have a first generation t-deck but I don't use it.
TCA8418 is capable of requesting 3 buttons at once (under certain matrix rules) which is not currently used and I don't think it is needed. Currently shift increases the modifierFalg value by 1, alt by 2 and sym by 4. Before the _TCA8418_MULTI_TAP_THRESHOLD time expires, the modifier keys can be pressed in sequence to use different combinations e.g. shift & alt & key. Which gives the index of the third key of tapMap. It would be a good idea to have some information about the state of the modifierFalg on the display but the top line of the display is full.
I've modified all this already, i.e. implemented the multi-key press and removed the long press which we don't use on T-Deck. I guess nobody wants to press more than one modifier key in sequence which would also simplify the logic and the programming. What is currently not working is that the shift key can be held while typing a series of capital alphabetic characters. Looks like an issue with the modifier state. From what you are suggesting I assume you've never worked with a T-Deck, right?
For me, it was not uncomfortable to press several buttons in a row during my tests. The beauty of it all is that you can approach the same thing in different ways. 😉 I have no problem with your solution, that's not why I wrote it. I haven't tried your version yet (I'll take the time this afternoon). I have a first generation t-deck but I don't use it.
If you take a look at the meshtastic map of Hungary, you will understand why you don't need a qwerty device. It's currently a hobby for some crazy people. 😂 No good infrastructure and no good coverage. Also 433MHz and 868MHz devices are very mixed. Chances are high that messages will not reach their destination.
@kstrauser @Szetya Do you also have issues fully charging the T-Deck Pro? Sometimes it charges, sometimes not e.g. when shutdown. After 10h charging still at 80%. Weird. I've opened an issue here.
@kstrauser @Szetya Do you also have issues fully charging the T-Deck Pro? Sometimes it charges, sometimes not e.g. when shutdown. After 10h charging still at 80%. Weird. I've opened an issue here.
It doesn't charge for me above 80-85% either. There was a photo here that I printed extra information on the display just to see what was happening (picture here: https://github.com/meshtastic/firmware/issues/6854#issuecomment-2907956446 the photo is in the state of discharging) When the charge reached about 4.2V the charge was switched off, you could see it on the display 0mA & Not Charging When I unplugged the charging cable it dropped back to the known 85% and showed about 4V.
Hello! I've installed this version but after a while the keyboard has stopped working 🤔 Now or it ignores key press or types random stuff autonomously
I've tried to erase and reflash but the issue is still present
@mverch67 Add the #define I2C_NO_RESCAN macro to the variant.h file. Thank you!
@Szetya Have tried Adding the #define I2C_NO_RESCAN macro to the variant.h file, And unfortunately ghost writer is still at work typing on me keyboard and randomly restarting on the table next to me. And as added oddness, i have never had it respond to me actually typing on the keyboard ever. (Clean build, only the macro above added)
@Szetya Have tried Adding the #define I2C_NO_RESCAN macro to the variant.h file, And unfortunately ghost writer is still at work typing on me keyboard and randomly restarting on the table next to me. And as added oddness, i have never had it respond to me actually typing on the keyboard ever. (Clean build, only the macro above added)
Unfortunately, I experienced it yesterday. 🙁 And I had the I2C_NO_RESCAN macro defined from the beginning. I'm at a loss, maybe I should use a complete directive to disable the TDECK_KB lookup for T_DECK_PRO and use it in the I2C scanner. The BQ27220 does not provide any useful information, all values are OFF or 00. My first solution was something similar in my trials. It seemed stable then. I am sure it is the BQ27220 that is causing it.
@Nasimovy You may try if the refactored class is still working with your keyboard device 😅
it works fine with my keyboard, you made some nice improvements
@Szetya Have tried Adding the #define I2C_NO_RESCAN macro to the variant.h file, And unfortunately ghost writer is still at work typing on me keyboard and randomly restarting on the table next to me. And as added oddness, i have never had it respond to me actually typing on the keyboard ever. (Clean build, only the macro above added)
@ReconPirate @mverch67 https://github.com/meshtastic/firmware/blob/8f9e569825b673a21c644d3b398a8afea1ac222e/src/detect/ScanI2C.cpp#L32-L36 Maybe the order can solve the problem if the TCA8418KB comes first?!
Hi there!
I installed this and it mostly works great. One question: How do you navigate between nodes and channels when sending a message?
So if you hit alt + t it selects Broadcast, and a second alt+t will select the Primary channel, but I can't figure out how to navigate to other nodes or other channels. Once the Primary channel is selected in the alt + t menu, I've tried pressing nearly every button and also swiping on the screen but nothing seems to make it change to the Secondary channel I have programmed.
Other than that, this is working great. Thanks so much for this awesome effort!! :+1:
-John
Great work! I successfully ran this patch on my T-Deck Pro (Voice, US band) and communicated with another node.
I know this is just an initial patch, but some observations so far:
- Modifier keys are not held across multiple key presses.
- Screen refresh sometimes misses the latest input, showing the previous item or character until the next input.
- The
Alt + Cbindings inherited from T-Deck don't feel great and a new command mapping should probably be created. Arrow keys in particular are important now. - Screensaver / screen lock UX could be reconsidered in the context of e-ink.
- UI in general should take better advantage of the additional vertical height.
- Channel selector UX when sending messages is very finicky, and I accidentally transmitted on channel 0 several times when attempting to send a test message on a private channel.
I'll try and see where I can contribute once initial board support is stabilized.
Latest changes fix all the issues I described. Thank you all! Can confirm most of the relatively minor bugs reported by Hylian. But my device is up and running great for the most part! Huzzah!! 🥳
My unit seems to not always be charging properly however. It's been plugged in all night and it is at 40%. Before I rebooted it, it was showing 0%. I'm wondering if it stopped being able to talk to the power management chip after being on for a while?
After I rebooted it, it's been fine. Showing ... checks again ... 48% now.
Hi all,
Thanks for your work on this, @Szetya. I was also having a multitude of keyboard problems (ignored inputs, ghost inputs) but the change you suggested above seems to have solved the problem (requoted below):
https://github.com/meshtastic/firmware/blob/8f9e569825b673a21c644d3b398a8afea1ac222e/src/detect/ScanI2C.cpp#L32-L36
Apologies if there is a more useful place to share these, but here are some high-resolution pictures of the circuitboard. Note to others re disassembly: There are two layers to the rear half of the case: an outer rear shell that attaches to the front shell via plastic clips and an inner rear shell that is attached to the front shell using 6 small screws. These screws screw into threaded inserts that have been set into plastic posts on the front shell that also fit into notches on the edges of the PCB, holding it in place. There are 6 main retention tabs for the outer shell, one at each corner as well as one on each side between the keyboard and the buttons/sim slot. There are a couple smaller tabs for alignment that don't need to be unhooked. The side tabs are especially fragile; you may have more luck than me (I broke one despite being pretty careful) if you start with the 4 corner tabs using an especially thin spudger. Removing the SIM card tray can provide a good point to start.
When you open the unit, be aware that the plastic button cap for the reset/boot buttons isn't attached to anything and will just pop right out. There are two small pieces of clear plastic that are stuck between the plastic button cap and the tactile switches on the PCB which I guess was Lilygo's way of bridging the distance and/or providing a better tactile feel to the buttons. Pay attention to where these fall out if you want to keep them, or else remember you'll need to stick something in those two spaces again if you want the side buttons to work well again after reassembly.
Missing from the pictures is a piece of black fabric tape that I removed to show where the keyboard and screen ribbon cables connect to the PCB. The battery is also wrapped in a similar black fabric tape as you can clearly see from the outside of an unmodified unit.
Other notes I forgot to put in the previous message:
The inner rear case has a cutout that's just slightly smaller than the battery, perhaps to make room for whatever the bullseye printed on the outer case was meant to represent (wireless charger? NFC reader? Location to aim hammer?). The battery in my unit is a 305070 LiPo from Tewaycell with a marked rating of 1400mAh and a mfg date from April 2025, which, hey, not bad. There is a real 10k thermistor on the protection board attached to the battery (as opposed to just a 10k resistor, which I've certainly found before) so that's not bad either.
As you can see without even opening the case, the WiFi, LoRa, and (presumably only on the 4G units?) GSM antennas are thin flex-pcb stickers that are attached to the inner rear case. These actually connect to the rest of their circuits via metal tabs that make contact with spring-loaded terminals on the PCB, which I was a little surprised by - notes taken from Blackberry et al. These spring-loaded terminals on the PCB are located near U.FL connectors that have tiny coax cables connected to them that pass their signal to another U.FL connector near the relevant IC. The onboard "chip"- or "tile"-style GPS antenna is attached via a standard U.FL connector as well. This should allow easy antenna customization for any of the 4 wireless communication protocols.
As you can see from the picture of the keyboard side of the PCB, there's still a bare footprint where Lilygo intended to put an ambient light sensor (LTR-553ALS-01 from Liteon). Liteon discontinued this sensor, which is Lilygo's explanation for not populating it on the board. Given that Lilygo's schematic shows 2 unpopulated resistor footprints, 2 resistors, and 3 capacitors total between the microphone and the light sensor, and that's exactly what we see on the back despite the missing sensor, everything's already in place if you get your hands on an LTR-553ALS-01. TMD27721 from OSRAM also looks to be a good replacement - same pinout, same dimensions, same operating voltage. I can't find its I2C slave address on quick glance though, so if you go that route, make sure there's no collision between the other ICs that share the same I2C bus.
There's a tactile switch near the A7682E (GSM/LTE modem); based on the schematic and on Simcom's datasheet, pressing this pulls the A7682E "BOOT_CFG" pin low, and doing this while powering up the modem and then toggling the modem's reset pin, which is connected to GPIO9 of the ESP32, places the modem in "USB Download" mode, which it appears allows you to flash the modem's firmware from a computer via USB. The modem's USB interface is available through the test points (and it appears the test points only) next to the modem on the PCB.