From 57cd2445ec27cf4c7e94ad2230d59f54bea1e70b Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 15 Jan 2020 09:56:23 +0100 Subject: [PATCH 01/70] Fix wrong default for 128 LS timers --- radio/src/gui/128x64/model_logical_switches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/128x64/model_logical_switches.cpp b/radio/src/gui/128x64/model_logical_switches.cpp index 90fc08481..0ce6bb44b 100644 --- a/radio/src/gui/128x64/model_logical_switches.cpp +++ b/radio/src/gui/128x64/model_logical_switches.cpp @@ -83,7 +83,7 @@ void menuModelLogicalSwitchOne(event_t event) uint8_t new_cstate = lswFamily(cs->func); if (cstate != new_cstate) { if (new_cstate == LS_FAMILY_TIMER) { - cs->v1 = cs->v2 = 0; + cs->v1 = cs->v2 = -119; } else if (new_cstate == LS_FAMILY_EDGE) { cs->v1 = 0; cs->v2 = -129; cs->v3 = 0; From db7d241306c2bd7ff489fa03d4dcf1e31d550bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Charpentier?= Date: Wed, 15 Jan 2020 10:45:36 +0100 Subject: [PATCH 02/70] Fr Translation (#7297) * initial version * Updated French Translation. --- companion/src/translations/companion_fr.ts | 586 +++++++++++---------- 1 file changed, 298 insertions(+), 288 deletions(-) diff --git a/companion/src/translations/companion_fr.ts b/companion/src/translations/companion_fr.ts index 8f69bf1bb..b4ff19c18 100644 --- a/companion/src/translations/companion_fr.ts +++ b/companion/src/translations/companion_fr.ts @@ -728,58 +728,58 @@ Manche Droit: Profondeur, Direction Boards - + Left Horizontal Gauche Horizontal - + Left Vertical Gauche Vertical - + Right Vertical Droit Vertical - + Right Horizontal Droit Horizontal - + Aux. 1 - + Aux. 2 - - + + Unknown Inconnu - + Rud Dir - + Ele Prf - + Thr Gaz - + Ail @@ -1581,7 +1581,7 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import Trainer - Écolage + Écolage Manches @@ -1605,193 +1605,198 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import + Trainer Channels + Écolage Channels + + + Instant Trim Trims instantanés - + Play Sound Jouer Son - + Haptic Vibreur - + Reset Remise à zéro - + Set Timer %1 Définir chrono %1 - + Vario - + Play Track Jouer fichier - + Play Both Jouer les deux - + Play Value Lire valeur - + Play Script Exécuter script - + SD Logs Logs SD - + Volume - + Backlight Rétroéclairage - + Screenshot Capture d'écran - + Background Music Musique de fond - + Background Music Pause Pause musique de fond - + Adjust %1 Ajuster %1 - + SetFailsafe Int. Module Définir failsafe module interne - + SetFailsafe Ext. Module Définir failsafe module externe - + RangeCheck Int. Module Test portée module interne - + RangeCheck Ext. Module Test portée module externe - + Bind Int. Module Bind module interne - + Bind Ext. Module Bind module externe - + Timer1 Chrono 1 - + Timer2 Chrono 2 - + Timer3 Chrono 3 - + Flight Vol - + Telemetry Télémétrie - + Rotary Encoder Sélecteur Rotatif - + REa - + REb - + s - - - + + + <font color=red><b>Inconsistent parameter</b></font> <font color=red><b>Paramètre inconsistant</b></font> - + Value Valeur - + played once, not during startup !1x Lu une fois, mais pas à la mise en route - + repeat(%1s) Répéter chaque %1s - + DISABLED DESACTIVE - + CFN FPN @@ -2114,13 +2119,13 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import OpenTX n'accepte que %1 points au maximum entre toutes les courbes - - + + OpenTX on this board doesn't accept this function OpenTX ne supporte pas cette fonction sur cette carte - + OpenTX doesn't accept this radio protocol OpenTX ne supporte pas ce protocole radio @@ -2200,12 +2205,12 @@ Pour <b>retirer un filtre de l'historique</b>, sélectionnez-le Basculer le filtre on/off. - + <html><head><style>kbd {background-color: palette(alternate-base); font-size: large; white-space: nowrap;}</style></head><body><p>The filter supports two syntax types: basic matching with common wildcards as well as full Perl-style (<code>pcre</code>) Regular Expressions.</p><p>By default a filter will only show lines which match (<b>inclusive</b>). To make an <b>exclusive</b> filter which removes matching lines, prefix the filter expression with a <kbd>!</kbd> (exclamation mark).</p><p>To use <b>Regular Expressions</b> (RegEx), prefix the filter text with a <kbd>/</kbd> (slash) or <kbd>^</kbd> (up caret). <ul><li>Put the <kbd>/</kbd> or <kbd>^</kbd> after the exclusive <kbd>!</kbd> indicator if you're using one.</li><li>By default the match is case-sensitive. To make it insensitive, add the typical <kbd>/i</kbd> (slash i) operator at the end of your RegEx.</li><li>If you use a caret (^) to denote a RegEx, it will become part of the Reg. Ex. (that is, matches from start of line).</li><li>If the RegEx is invalid, the filter edit field should show a red border and you will not be able to enable the filter.</li><li>A useful resource for testing REs (with a full reference) can be found at <a href="http://www.regexr.com/">http://www.regexr.com/</a></li></ul></p><p>To use <b>basic matching</b> just type any text.<ul><li>Wildcards: <kbd>*</kbd> (asterisk) matches zero or more of any character(s), and <kbd>?</kbd> (question mark) matches any single character.</li><li>The match is always case-insensitive.</li><li>The match always starts from the beginning of a log line. To ignore characters at the start, use a leading <kbd>*</kbd> wildcard.</li><li>A trailing <kbd>*</kbd> is always implied (that is, matches anything to the end of the log line). To avoid this, use a RegEx.</li><li>You can match literal wildcard characters by prefixing them with a <kbd>\</kbd> (backslash) character (eg. "foo\*bar" matches "foo*bar").</li></ul></p><p>After <b>editing text</b>, press ENTER or TAB key (or click anywhere outside the box) to update the filter.</p><p>To <b>remove an entry</b> from the filter selector list, first choose it, and while in the line editor press <kbd>Shift-Delete</kbd> (or <kbd>Shift-Backspace</kbd>) key combination. The default filters cannot be removed. Up to 50 filters are stored.</p></body></html> <html><head><style>kbd {background-color: palette(alternate-base); font-size: large; white-space: nowrap;}</style></head><body><p>Le filtre supporte deux types de syntaxes: la recherche simple utilisant les métacaractères ou la recherche avancée utilisant les expressions régulières (<code>RegEx</code>) de type Perl.</p><p>Par défaut, un filtre ne montre que les lignes qui correspondent (<b>inclusif</b>). Pour faire un filtre <b>exclusif</b> qui supprime les lignes de correspondance, préfixez l'expression du filtre avec un <kbd>!</kbd> (point d'exclamation).</p><p>Pour utiliser les <b>Expressions Régulières</b> (RegEx), préfixez le texte du filtre avec un <kbd>/</kbd> (slash) ou <kbd>^</kbd> (accent circonflexe).<ul><li>Il faut mettre le <kbd>!</kbd> <u>avant</u> le <kbd>/</kbd> ou <kbd>^</kbd> dans le cas d'un filtre exclusif.</li><li>Par défaut, la correspondance est sensible à la casse (ex: a &ne; A). Pour la rendre insensible (ex: a = A), ajoutez l'opérateur typique <kbd>/i</kbd> (slash i) à la fin de votre RegEx.</li><li>Si vous utilisez un <kbd>^</kbd> pour désigner une RegEx, il deviendra une partie de la RegEx (<kbd>^</kbd> est le caractère de début de chaîne).</li><li>Si la RegEx n'est pas valide, le champ d'édition du filtre affichera une bordure rouge et vous ne pourrez pas activer le filtre.</li><li>Une ressource utile pour tester les RegExs (avec une référence complète) peut être trouvée sur le site <a href="http://www.regexr.com/">http://www.regexr.com/</a> (tutoriel en français: <a href="http://perl.mines-albi.fr/DocFr/perlretut.html">Expressions rationnelles/régulières en Perl</a>)</li></ul></p><p>Pour utiliser la <b>recherche simple</b>, tapez simplement le texte recherché.<ul><li>Métacaractères: le quantificateur <kbd>*</kbd> (astérisque) correspond à zéro ou plus de n'importe quel caractère, et le quantificateur <kbd>?</kbd> (point d'interrogation) correspond à un caractère unique.</li><li>La correspondance est toujours sensible à la casse.</li><li>La correspondance commence toujours au début du Log. Pour ignorer les caractères au début, utilisez le métacaractère <kbd>*</kbd>.</li><li>Un métacaractère <kbd>*</kbd> est implicitement ajouté à la fin (ainsi, toutes les correspondances valides soient bien affichées jusqu'à la fin du Log). Si vous voulez éviter ce métacaractère implicite, il faut utiliser une RegEx.</li><li>Pour rechercher un caractère qui est lui-même un métacaractère, il faut préfixer avec un <kbd>\</kbd> (backslash) (ex: "<i>toto\*titi</i>" correspond à "<i>toto*titi</i>").</li></ul></p><p>Quand l'<b>édition</b> est terminée, appuyez sur la touche ENTRER ou TAB (ou cliquez n'importe où à l'extérieur du champ du filtre) afin de mettre à jour le filtre.</p><p>Pour <b>retirer un filtre de l'historique</b>, sélectionnez-le d'abord, puis faite le raccourci clavier <kbd>Shift-Suppr</kbd> (ou <kbd>Shift-Retour Arrière</kbd>). Les filtres par défaut ne peuvent pas être effacés. Jusqu'à 50 filtres peuvent être mémorisés.</p></body></html> - + Debug Console Filter Help Aide sur les filtres pour la console de débogage @@ -2857,267 +2862,272 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Firmware - + Channel values displayed in us Positions de voies affichées en µs - + No OverrideCH functions available Désactive la fonction spéciale "Remplacer VOIExx" - + Possibility to enable FAI MODE (no telemetry) at field Possibilité d'activer le mode FAI (télémétrie désactivée) sur le terrain - + FAI MODE (no telemetry) always enabled Mode FAI (télémétrie toujours désactivée) - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 Masque le protocole D8. Légalement obligatoire sur les radios Européennes importées après le 1er janvier 2015 - - + + Disable HELI menu and cyclic mix support Supprimer le menu HELICO et les mixages cycliques - - + + Disable Global variables Supprimer le support des variables globales - - + + Enable Lua custom scripts screen Activer l'écran des scripts Lua personnalisés - + Support for PPM internal module hack Support du remplacement du module interne par un module PPM - + Use alternative SQT5 font Utiliser la police alternative SQT5 - + Disable RAS (SWR) Désactiver le RAS (SWR). Utile uniquement pour les X9D+ avec un RAS/SWR non fonctionnel - + Pots use in menus navigation Support de la navigation dans les menus avec les POTS - + FrSky Taranis X9D+ - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D - + Haptic module installed Module vibreur installé - + FrSky Taranis X9E - + Confirmation before radio shutdown Confirmation avant l'arrêt de la radio - + Horus gimbals installed (Hall sensors) Manches Horus à effet HALL installés - + FrSky Taranis X9-Lite - + FrSky Taranis X9-Lite S - + FrSky Taranis X7 / X7S - + + FrSky Taranis X7 / X7S Access + + + + FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite - + FrSky Horus X10 / X10S - - + + Support for ACCESS internal module replacement Prise en charge du module de remplacement interne ACCESS - + FrSky Horus X10 Express / X10S Express - + FrSky Horus X12S - + Use ONLY with first DEV pcb version Exclusivement pour les Horus DEV - + Enable non certified R9M firmwares Activer les firmwares R9M non certifiés - - + + Support for MULTI internal module Prise en charge du module MULTI interne - + Support for bluetooth module Prise en charge du module Bluetooth - + Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support Activer le menu hélico et les mixages CCPM - + Global variables Variables globales - + Enable non certified firmwares Activer les firmwares non certifiés - + In model setup menus automatically set source by moving the control Sélectionner les sources des mixeurs en bougeant le contrôle désiré - + In model setup menus automatically set switch by moving the control Sélectionner les interrupteurs en bougeant le contrôle désiré - + No graphical check boxes and sliders Pas de cases à cocher et de curseurs graphiques - + Battery graph Graphique de la batterie - + Don't use bold font for highlighting active items Ne pas mettre les lignes actives en gras - + Turnigy 9XR with m128 chip Turnigy 9XR avec une puce m128 - + Turnigy 9XR - + 9X with stock board 9X avec carte mère d'origine - + Enable resetting values by pressing up and down at the same time Permet la remise à zéro des valeurs en pressant haut-bas en même temps, valeur min avec gauche/bas, valeur max avec haut/droite, inversion avec gauche/droite - + 9X with stock board and m128 chip Carte 9x avec un chip m128 - + 9X with AR9X board 9X avec carte AR9X - + Jumper T12 / T12 Pro - + Jumper T16 / T16+ / T16 Pro - + 9X with Sky9x board 9X avec carte Sky9x - + 9X with Gruvin9x board 9X avec carte Gruvin9x - + DIY MEGA2560 radio Radio DIY à base de MEGA2560 @@ -4047,7 +4057,7 @@ Communs à tous les modèles d'une même EEPROM. GeneralSettings - + Radio Settings Paramètres de la radio @@ -6057,14 +6067,14 @@ Les colonnes contenant l'altitude "GAlt" et la vitesse "GSpd MainWindow - - + + Edit Édition - - + + File Fichier @@ -6114,17 +6124,17 @@ Les colonnes contenant l'altitude "GAlt" et la vitesse "GSpd Notes de version - + Compare models Comparer les modèles - + Show fuses dialog Afficher les paramètres des fusibles - + A monochrome black icon theme Thème avec icônes monochromes noires @@ -6147,214 +6157,214 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b - + Synchronize SD Synchroniser la carte SD - + New Nouveau - + Open... Ouvrir... - + A monochrome white icon theme Thème avec icônes monochromes blanches - + A monochrome blue icon theme Thème avec icônes monochromes bleues - + Small Petites - + Use small toolbar icons Petites icônes de barre d'outils - + Use normal size toolbar icons Icônes de barre d'outils normales - + Normal Normales - + Use big toolbar icons Grosses icônes de barre d'outils - + Big Grandes - + Use huge toolbar icons Immenses icônes de barre d'outils - + Huge Immenses - + List programmers... Lister les programmateurs... - + Fuses... Fusibles... - + Read Firmware from Radio Lire le firmware de la radio - + Read firmware from Radio Lire le firmware de la radio - + Write Firmware to Radio Transférer le firmware à la radio - + Write firmware to Radio Transférer le firmware à la radio - + Add Radio Profile Ajouter un profil de radio - + Manuals and other Documents Manuels et documents - + Open the OpenTX document page in a web browser Ouvre la page de documentation d'OpenTX dans un navigateur - + Write Models and Settings To Radio Transférer les paramètres et modèles vers la radio - + Write Models and Settings to Radio Transférer les paramètres et modèles vers la radio - + Read Models and Settings from Radio Lire les paramètres et modèles depuis la radio - + OpenTX Companion %1 - Radio: %2 - Profile: %3 OpenTX Companion %1 - Radio: %2 - Profil: %3 - + List of recently used files Liste des fichiers récemment utilisés - + Radio Profiles Profil radio - + Create or Select Radio Profiles Créer ou Sélectionner un profil radio - + Configure Communications... Configurer les communications... - + Configure software for communicating with the Radio Configurer le programme gérant les communications avec la radio - + Write Backup to Radio Transférer une sauvegarde à la radio - + Write Backup from file to Radio Transférer une sauvegarde à la radio - + Backup Radio to File Sauvegarder la radio - + Save a complete backup file of all settings and model data in the Radio Créer une copie de sauvegarde de tous les paramètres et modèles de la radio - + Contributors... Contributeurs... - + A tribute to those who have contributed to OpenTX and Companion Remerciements à tout ceux qui ont contribué à OpenTX et Companion - + SD card synchronization Synchronisation de la carte SD - + Recent Files Fichiers récents - + Set Icon Theme Choisir le thème d'icônes - + Set Icon Size Choisir la taille des icônes - + Write Ecrire @@ -6374,12 +6384,12 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Si vous trouvez ce programme utile, merci de le supporter par une <a href='%1'>donation</a> - + Ready Prêt - + Show the application's About box Afficher la fenêtre "A propos" de l'application @@ -6391,7 +6401,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b - + Open Models and Settings file Ouvrir un fichier de paramètres et modèles @@ -6402,7 +6412,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Fichier sauvegardé - + Read Models and Settings From Radio Lire les paramètres et modèles depuis la radio @@ -6437,7 +6447,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Language non valide - + Some text will not be translated until the next time you start Companion. Please note that some translations may not be complete. Certains textes ne seront pas traduits avant le prochain redémarrage de Companion. Veuillez noter que certaines traductions peuvent ne pas être complètes. @@ -6493,78 +6503,78 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b - + Create a new Models and Settings file Créer un nouveau fichier de paramètres et modèles - - + + Save Models and Settings file Enregistrer le fichier de paramètres et modèles - + Save Enregistrer - + Save As... Enregistrer sous... - + Close Fermer - + Close Models and Settings file Fermer le fichier de paramètres et modèles - + Exit the application Quitter l'application - + Exit Quitter - + Create a new Radio Settings Profile Créer un nouveau profil de paramètres et modèles - + Copy Current Radio Profile Copier le profil radio actuel - + Duplicate current Radio Settings Profile Dupliquer les paramètres radio du profil actuel - + Delete the current Radio Settings Profile Supprimer les paramètres radio du profil actuel - + Use default system language. Utiliser le langage système par défaut. - + Use %1 language (some translations may not be complete). Utiliser la langue %1 (certaines traductions peuvent être incomplètes). - + Classical Classique @@ -6693,287 +6703,287 @@ Do you wish to continue? Pas de Radio ou carte SD de détectée ! - + Release notes... Notes de version... - + Show release notes Afficher les notes de version - + Delete Current Radio Profile... Supprimer le profil radio actuel... - + Export Application Settings.. Exporter Préférences Application... - + Save all the current %1 and Simulator settings (including radio profiles) to a file. Enregistrez tous les paramètres actuels %1 et du simulateur (y compris les profils radio) dans un fichier. - + Import Application Settings.. Importer les paramètres de l'application... - + Load %1 and Simulator settings from a prevously exported settings file. Charger les paramètres %1 et les paramètres de Simulation depuis un fichier précédemment exporté. - + Tabbed Windows Fenêtres à onglets - + Use tabs to arrange open windows. Utilisez les onglets pour organiser les fenêtres ouvertes. - + Tile Windows Titre de la fenêtre - + Arrange open windows across all the available space. Disposez les fenêtres ouvertes sur tout l'espace disponible. - + Cascade Windows Fenêtres en cascade - + Arrange all open windows in a stack. Organisez toutes les fenêtres ouvertes dans une pile. - + Close All Windows Fermer toutes les fenêtres - + Closes all open files (prompts to save if necessary. Fermer tous les fichiers ouverts (proposer de sauvegarder si nécessaire). - + Window Fenêtre - + Ctrl+Shift+S - + Ctrl+Alt+L - + Ctrl+Alt+D - + Ctrl+Alt+R - + The classic companion9x icon theme Thème d'icônes classique de Companion - + Yerico - + Yellow round honey sweet icon theme Thème d'icônes rondes jaunes - + Monochrome - + MonoWhite Monochrome Blanc - + Alt+%1 - + - Copy - Copier - + Companion :: Open files warning Companion::Ouvrir les fichiers d'avertissement - + Please save or close modified file(s) before deleting the active profile. Veuillez sauvegarder ou fermer le(s) fichier(s) modifié(s) avant de supprimer le profil actif. - + Not possible to remove profile Impossible de supprimer le profil - + The default profile can not be removed. Le profil par défaut ne peut pas être supprimé. - + Confirm Delete Profile Confirmer la suppression du profil - + Are you sure you wish to delete the "%1" radio profile? There is no way to undo this action! Etes-vous sûr de vouloir supprimer le profil radio %1? Cette action est irréversible! - + Please save or close all modified files before importing settings Veuillez sauvegarder ou fermer tous les fichiers modifiés avant d'importer les paramètres - + <html><p>%1 and Simulator settings can be imported (restored) from a previosly saved export (backup) file. This will replace current settings with any settings found in the file.</p><p>An automatic backup of the current settings will be attempted. But if the current settings are useful then it is recommended that you make a manual backup first.</p><p>For best results when importing settings, <b>close any other %1 windows you may have open, and make sure the standalone Simulator application is not running.</p><p>Do you wish to continue?</p></html> <html><p>%1 et les paramètres du simulateur peuvent être importés (restaurés) à partir d’un fichier d’exportation (sauvegarde) préalablement sauvegardé. Ceci remplacera les paramètres actuels par tous les paramètres trouvés dans le fichier.</p><p>Une sauvegarde automatique des paramètres actuels sera tentée. Mais si les paramètres actuels sont utiles, il est recommandé de commencer par une sauvegarde manuelle.</p><p>Pour obtenir de meilleurs résultats lors de l'importation des paramètres,<b> fermez les autres fenêtres %1 que vous avez éventuellement ouvertes et assurez-vous que l'application autonome Simulator n'est pas en cours d'exécution. </p><p>Souhaitez-vous continuer? </p></html> - + Confirm Settings Import Confirmer les paramètres d'importation - + Select %1: Sélectionnez %1: - + backup sauvegarde - + Press the 'Ignore' button to continue anyway. Appuyez sur le bouton 'Ignorer' pour continuer quand même. - + The settings could not be imported. Les paramètres n'ont pas pu être importés. - + <html><p>New settings have been imported from:<br> %1.</p><p>%2 will now re-initialize.</p><p>Note that you may need to close and restart %2 before some settings like language and icon theme take effect.</p> <html><p>Les nouveaux paramètres ont été importés depuis:<br> %1. </p><p>%2 sera maintenant réinitialisé.</p><p>Notez que vous devrez peut-être fermer et redémarrer %2 avant que certains paramètres tels que la langue et le thème d’icône prennent effet.</p> - + <p>The previous settings were backed up to:<br> %1</p> <p>Les paramètres précédents ont été sauvegardés sous:<br> %1 </p> - + MonoBlue Monochrome Bleu - + System language Langue du système - + About... A propos... - + View Log File... Ouvrir un Log... - + Open and view log file Ouvrir et visualiser un log - + Settings... Préférences... - + Edit Settings Éditer les préférences - + Download... Télécharger... - + Download firmware and voice files Télécharger firmware et fichiers son - + Check for Updates... Vérifier les mises à jour... - + Check OpenTX and Companion updates Vérifier les mises à jour d'OpenTX et Companion - + Compare Models... Comparer 2 modèles... - + Edit Radio Splash Image... Éditer l'écran d'accueil de la radio... - + Edit the splash image of your Radio Éditer l'écran d'accueil de la radio - + List available programmers Lister les programmateurs supportés @@ -6990,8 +7000,8 @@ Do you wish to continue? Aucune mise à jour disponible. - - + + Help Aide @@ -7011,27 +7021,27 @@ Do you wish to continue? A propos de Companion - + Set Menu Language Choisir la langue des menus - + Settings Paramètres - + Read/Write Transfert - + %2 - + New Radio Nouvelle radio @@ -7328,11 +7338,6 @@ Do you wish to continue? Companion :: Conversion Result for %1 Companion :: Résultat de conversion de %1 - - - Unable to find Horus radio SD card! - Impossible de trouver la carte SD de la Horus ! - Models and Settings written @@ -7399,6 +7404,11 @@ Do you wish to continue? <p><b>Currently selected radio type (%1) is not compatible with file %3 (from %2), models and settings need to be converted.</b></p> <p><b>Le type de radio actuellement sélectionné (%1) n'est pas compatible avec le fichier %3 (à partir de %2), les modèles et les paramètres doivent être convertis.</b></p> + + + Unable to find radio SD card! + Impossible de trouver la carte SD de la radio! + Open backup Models and Settings file @@ -8961,12 +8971,12 @@ Mixage actif par défaut si non-renseigné. ModuleData - + Positive - + Negative Négative @@ -9047,47 +9057,47 @@ Mixage actif par défaut si non-renseigné. ModulePanel - + Value Valeur - + Hold Maintien - + No Pulse Pas d'impulsion - + Ask Demander - + Internal Interne - + Internal + External Interne + Externe - + External Externe - + Autodetect Format Format Détection auto - + Bind on channel Bind avec VOIE @@ -9589,7 +9599,7 @@ Mixage actif par défaut si non-renseigné. DÉFAUT - + Custom - proto %1) Personnaliser - proto %1) @@ -9620,22 +9630,22 @@ Mixage actif par défaut si non-renseigné. OpenTxEepromInterface - + Unknown error Erreur inconnue - + ... plus %1 errors ... plus %1 erreurs - + Cannot write radio settings Impossible d'écrire les paramètres de la radio - + Cannot write model %1 Impossible d'écrire le modèle %1 @@ -9908,8 +9918,8 @@ Mixage actif par défaut si non-renseigné. - Unable to find Horus radio SD card! - Impossible de trouver la carte SD de la Horus ! + Unable to find radio SD card! + Impossible de trouver la carte SD de la radio! @@ -11025,22 +11035,22 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo SetupPanel - + Timer %1 Chrono %1 - + THR GAZ - + Profile Settings Paramètres du profil - + SD structure path not specified or invalid Chemin de la structure SD non spécifié ou invalide @@ -11764,62 +11774,62 @@ La valeur par défaut est configurée dans le profil radio sélectionné.Simulateur Radio (%1) - + Could not determine startup data source. Impossible de déterminer les données source. - + Could not load data, possibly wrong format. Impossible de charger les données, mauvais format. - + Data Load Error Erreur de lecture des données - + Invalid startup data provided. Plese specify a proper file/path. Données de démarrage fournies non valides. Veuillez spécifier un fichier/chemin approprié. - + Simulator Startup Error Erreur de démarrage du simulateur - + Error saving data: could open file for writing: '%1' Erreur de sauvegarde des données: impossible d'écrire le fichier '%1' - + Error saving data: could not get data from simulator interface. Erreur de sauvegarde des données: impossible de récupérer les données depuis l'interface de simulation. - + An unexpected error occurred while attempting to save radio data to file '%1'. Une erreur inattendue s'est produite lors de l'enregistrement des données radio dans le fichier '%1'. - + Data Save Error Erreur de sauvegarde des données - + Cannot open joystick, joystick disabled Impossible d'accéder au Joystick, Joystick désactivé - + Radio firmware error: %1 Erreur firmware radio: %1 - + - Flight Mode %1 (#%2) - Phase de Vol %1 (#%2) From 152a702faaba6bbdb8b5cddb45ec00fe612cc7c5 Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 15 Jan 2020 17:40:13 +0100 Subject: [PATCH 03/70] Post 2.3.5 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcbe62e95..820530334 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ project(OpenTX) set(VERSION_MAJOR "2") set(VERSION_MINOR "3") -set(VERSION_REVISION "5") +set(VERSION_REVISION "6") set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) From d152be5e18f5120e73eb80665b322325bc6302b1 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 15 Jan 2020 17:48:20 +0100 Subject: [PATCH 04/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 3ed94c926..b696b8e3d 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1685,3 +1685,4 @@ Gary Garland Stefano Boggia Jean-Jacques Pointel Ferenc Kunkli +Sven Müller From 4d5b5e1c0b1e61bea06f7a0b5611a9918e697b36 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 15 Jan 2020 21:06:44 +0100 Subject: [PATCH 05/70] Fixes #7299 --- radio/src/targets/common/arm/stm32/pwr_driver.cpp | 6 ++++-- radio/src/targets/taranis/hal.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/radio/src/targets/common/arm/stm32/pwr_driver.cpp b/radio/src/targets/common/arm/stm32/pwr_driver.cpp index 751279da8..f488d19fa 100644 --- a/radio/src/targets/common/arm/stm32/pwr_driver.cpp +++ b/radio/src/targets/common/arm/stm32/pwr_driver.cpp @@ -54,9 +54,11 @@ void pwrInit() #if defined(PCBREV_HARDCODED) hardwareOptions.pcbrev = PCBREV_HARDCODED; #elif defined(PCBREV_GPIO_PIN) - GPIO_ResetBits(PCBREV_GPIO, PCBREV_GPIO_PIN); + #if defined(PCBREV_GPIO_PULL_DOWN) + GPIO_ResetBits(PCBREV_GPIO, PCBREV_GPIO_PIN); + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + #endif GPIO_InitStructure.GPIO_Pin = PCBREV_GPIO_PIN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(PCBREV_GPIO, &GPIO_InitStructure); hardwareOptions.pcbrev = PCBREV_VALUE(); #endif diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 2a7ca0ad9..31cf6a4a9 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1375,6 +1375,7 @@ #define PCBREV_RCC_AHB1Periph RCC_AHB1Periph_GPIOA #define PCBREV_GPIO GPIOA #define PCBREV_GPIO_PIN GPIO_Pin_14 // PA.14 + #define PCBREV_GPIO_PULL_DOWN #define PCBREV_VALUE() GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN) #else #define PCBREV_RCC_AHB1Periph 0 From cc298988de3340ffdbfe387b01337c636d171109 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 15 Jan 2020 21:39:20 +0100 Subject: [PATCH 06/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index b696b8e3d..b974f0a73 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1686,3 +1686,4 @@ Stefano Boggia Jean-Jacques Pointel Ferenc Kunkli Sven Müller +Taavi Tuisk From 38f13c30e0258b3694568eccdebf1490d9ea5919 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 16 Jan 2020 13:12:27 +0100 Subject: [PATCH 07/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index b974f0a73..e5abc8a23 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1687,3 +1687,4 @@ Jean-Jacques Pointel Ferenc Kunkli Sven Müller Taavi Tuisk +Thomas Floyd From 1737a8433b1a849adc946c8889fbb8c91a975b4c Mon Sep 17 00:00:00 2001 From: Ben Lye Date: Thu, 16 Jan 2020 14:39:02 +0000 Subject: [PATCH 08/70] Fix simulator buttons for T16 (#7300) Lines the clickable overlay up with the button images more accurately. --- .../src/simulation/simulateduiwidgetJumperT16.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/companion/src/simulation/simulateduiwidgetJumperT16.cpp b/companion/src/simulation/simulateduiwidgetJumperT16.cpp index 317fdb24c..66fc7f36e 100644 --- a/companion/src/simulation/simulateduiwidgetJumperT16.cpp +++ b/companion/src/simulation/simulateduiwidgetJumperT16.cpp @@ -34,27 +34,27 @@ SimulatedUIWidgetJumperT16::SimulatedUIWidgetJumperT16(SimulatorInterface *simul // add actions in order of appearance on the help menu act = new RadioUiAction(3, QList() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL); - addRadioWidget(ui->leftbuttons->addArea(QRect(10, 70, 80, 35), "JumperT16/left_mdl.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(50, 70, 80, 35), "JumperT16/left_mdl.png", act)); act = new RadioUiAction(6, QList() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS); - addRadioWidget(ui->leftbuttons->addArea(QRect(10, 10, 80, 35), "JumperT16/left_sys.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(25, 10, 95, 35), "JumperT16/left_sys.png", act)); act = new RadioUiAction(5, QList() << Qt::Key_Right, SIMU_STR_HLP_KEY_RGT, SIMU_STR_HLP_ACT_TELE); - addRadioWidget(ui->leftbuttons->addArea(QRect(10, 190, 80, 35), "JumperT16/left_tele.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(50, 190, 80, 35), "JumperT16/left_tele.png", act)); act = new RadioUiAction(4, QList() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEY_DN % "
" % SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_RTN); - addRadioWidget(ui->rightbuttons->addArea(QRect(35, 10, 80, 35), "JumperT16/right_rtn.png", act)); + addRadioWidget(ui->rightbuttons->addArea(QRect(50, 10, 95, 35), "JumperT16/right_rtn.png", act)); act = new RadioUiAction(1, QList() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN); - addRadioWidget(ui->leftbuttons->addArea(QRect(10, 131, 80, 35), "JumperT16/left_page.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(50, 131, 80, 35), "JumperT16/left_page.png", act)); m_scrollUpAction = new RadioUiAction(-1, QList() << Qt::Key_Minus, SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_ROT_LFT); m_scrollDnAction = new RadioUiAction(-1, QList() << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_ROT_RGT); connectScrollActions(); m_mouseMidClickAction = new RadioUiAction(2, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN); - addRadioWidget(ui->rightbuttons->addArea(QRect(45, 70, 100, 160), "JumperT16/right_ent.png", m_mouseMidClickAction)); + addRadioWidget(ui->rightbuttons->addArea(QRect(55, 90, 56, 120), "JumperT16/right_ent.png", m_mouseMidClickAction)); addRadioWidget(ui->leftbuttons->addArea(QRect(10, 252, 30, 30), "JumperT16/left_scrnsht.png", m_screenshotAction)); From 3be2af0fb5a9eef16a279c28ef81cc4eddff05a8 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 16 Jan 2020 21:04:39 +0100 Subject: [PATCH 09/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index e5abc8a23..0130f8052 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1688,3 +1688,4 @@ Ferenc Kunkli Sven Müller Taavi Tuisk Thomas Floyd +Matthew LePard From 6bbe04bda42578a7a1acbbd34a2798672e3a2cda Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sat, 18 Jan 2020 23:21:26 +0100 Subject: [PATCH 10/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 0130f8052..3e61c35dc 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1689,3 +1689,4 @@ Sven Müller Taavi Tuisk Thomas Floyd Matthew LePard +Peter Schneider From fdba50f27ef15dc5c8c59157e33b21b00af5a8a4 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sun, 19 Jan 2020 12:59:14 +0100 Subject: [PATCH 11/70] Fix FM edit while scrolling on T12 (#7306) --- radio/src/gui/128x64/model_flightmodes.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/radio/src/gui/128x64/model_flightmodes.cpp b/radio/src/gui/128x64/model_flightmodes.cpp index c803d9dfc..b619121b6 100644 --- a/radio/src/gui/128x64/model_flightmodes.cpp +++ b/radio/src/gui/128x64/model_flightmodes.cpp @@ -113,7 +113,11 @@ void menuModelFlightModeOne(event_t event) lcdDrawTextAlignedLeft(y, STR_TRIMS); for (uint8_t t = 0; t < NUM_STICKS; t++) { drawTrimMode(MIXES_2ND_COLUMN + (t*2*FW), y, s_currIdx, t, menuHorizontalPosition == t ? attr : 0); +#if defined(NAVIGATION_9X) + if (s_editMode > 0 && attr && menuHorizontalPosition == t) { +#else if (s_editMode >= 0 && attr && menuHorizontalPosition == t) { +#endif trim_t & v = fm->trim[t]; v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, k==0 ? 0 : 2*MAX_FLIGHT_MODES-1, EE_MODEL, isTrimModeAvailable); } From 511f8fd7bb5b6605090d7c39e1593693d94b0738 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sun, 19 Jan 2020 12:59:45 +0100 Subject: [PATCH 12/70] Keep frequent mixer runs for USB sim (#7305) --- radio/src/pulses/pulses.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index 289485bf2..42f04fb26 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -380,7 +380,7 @@ bool setupPulsesInternalModule(uint8_t protocol) #endif default: - scheduleNextMixerCalculation(INTERNAL_MODULE, 50/*ms*/); + scheduleNextMixerCalculation(INTERNAL_MODULE, 10 /*ms*/); // used for USB sim for example return false; } } From cd10ba438e7d79765951c995663b333cefccfb66 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 20 Jan 2020 13:47:26 +0100 Subject: [PATCH 13/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 3e61c35dc..6f1feb477 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1690,3 +1690,4 @@ Taavi Tuisk Thomas Floyd Matthew LePard Peter Schneider +Michel Garbarino From d44ec9b218124260bf12a5ea11531ce201148651 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 21 Jan 2020 09:41:08 +0100 Subject: [PATCH 14/70] Display baudrate choice only when needed on colorlcd (#7311) --- radio/src/gui/480x272/radio_hardware.cpp | 8 +++++++- radio/src/targets/horus/hal.h | 6 +++++- radio/src/telemetry/crossfire.h | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/radio/src/gui/480x272/radio_hardware.cpp b/radio/src/gui/480x272/radio_hardware.cpp index fbf4db3fd..bf6c333f6 100644 --- a/radio/src/gui/480x272/radio_hardware.cpp +++ b/radio/src/gui/480x272/radio_hardware.cpp @@ -113,6 +113,12 @@ void onHardwareAntennaSwitchConfirm(const char * result) #define EXTERNAL_ANTENNA_ROW #endif +#if defined(CROSSFIRE) && SPORT_MAX_BAUDRATE < 400000 + #define MAX_BAUDRATE_ROW 0 +#else + #define MAX_BAUDRATE_ROW HIDDEN_ROW +#endif + bool menuRadioHardware(event_t event) { MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, { @@ -134,7 +140,7 @@ bool menuRadioHardware(event_t event) READONLY_ROW, /* RTC */ 0, /* RTC check */ - 0, /* max baudrate */ + MAX_BAUDRATE_ROW, /* max baudrate */ BLUETOOTH_ROWS diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 7b6934068..1e5eb137e 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -303,7 +303,11 @@ #define PWR_SWITCH_GPIO_PIN GPIO_Pin_0 // PJ.00 // S.Port update connector -#define SPORT_MAX_BAUDRATE 250000 // < 400000 +#if defined(RADIO_T16) + #define SPORT_MAX_BAUDRATE 400000 +#else + #define SPORT_MAX_BAUDRATE 250000 // < 400000 +#endif #if defined(PCBX10) && !defined(RADIO_T16) #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOH #define SPORT_UPDATE_PWR_GPIO GPIOH diff --git a/radio/src/telemetry/crossfire.h b/radio/src/telemetry/crossfire.h index 5f40b6f93..3daed0d57 100644 --- a/radio/src/telemetry/crossfire.h +++ b/radio/src/telemetry/crossfire.h @@ -81,7 +81,6 @@ enum CrossfireSensorIndexes { void processCrossfireTelemetryData(uint8_t data); void crossfireSetDefault(int index, uint8_t id, uint8_t subId); -#if SPORT_MAX_BAUDRATE < 400000 const uint32_t CROSSFIRE_BAUDRATES[] = { 400000, 115200, @@ -90,6 +89,7 @@ const uint8_t CROSSFIRE_PERIODS[] = { 4, 16, }; +#if SPORT_MAX_BAUDRATE < 400000 #define CROSSFIRE_BAUDRATE CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate] #define CROSSFIRE_PERIOD CROSSFIRE_PERIODS[g_eeGeneral.telemetryBaudrate] #else From 36d098d22d5c019e2a9f3c11922f332e96284570 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 21 Jan 2020 11:13:58 +0100 Subject: [PATCH 15/70] Fix multi firmware not working first time if internal module is on (#7302) --- radio/src/io/multi_firmware_update.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/io/multi_firmware_update.cpp b/radio/src/io/multi_firmware_update.cpp index 6b9cc1651..f7d8d238e 100644 --- a/radio/src/io/multi_firmware_update.cpp +++ b/radio/src/io/multi_firmware_update.cpp @@ -520,7 +520,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) pausePulses(); -#if defined(INTERNAL_MODULE_MULTI) +#if defined(HARDWARE_INTERNAL_MODULE) uint8_t intPwr = IS_INTERNAL_MODULE_ON(); INTERNAL_MODULE_OFF(); #endif @@ -534,7 +534,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) /* wait 2s off */ watchdogSuspend(500 /*5s*/); - RTOS_WAIT_MS(2000); + RTOS_WAIT_MS(3000); const char * result = driver->flashFirmware(&file, getBasename(filename)); f_close(&file); @@ -563,7 +563,7 @@ bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) // reset telemetry protocol telemetryInit(255); -#if defined(INTERNAL_MODULE_MULTI) +#if defined(HARDWARE_INTERNAL_MODULE) if (intPwr) { INTERNAL_MODULE_ON(); setupPulsesInternalModule(); From 8390cbc705ea6ab58d98a9312d78d0ea3a840022 Mon Sep 17 00:00:00 2001 From: Carsten W Date: Wed, 22 Jan 2020 11:59:24 +0100 Subject: [PATCH 16/70] Crossfire LUA add missing support for PREC3 values (#7322) --- .../horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua | 24 ++++++++----------- .../SCRIPTS/TOOLS/CROSSFIRE/device.lua | 22 ++++++++--------- .../SCRIPTS/TOOLS/CROSSFIRE/device.lua | 22 ++++++++--------- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua index 50a8c7dde..3f99b5dbb 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -72,7 +72,7 @@ local function incrField(step) end else local min, max = 0, 0 - if field.type <= 5 then + if ((field.type <= 5) or (field.type == 8)) then min = field.min max = field.max step = field.step * step @@ -239,25 +239,21 @@ local function fieldFloatLoad(field, data, offset) field.default = fieldGetValue(data, offset+12, 4) fieldUnsignedToSigned(field, 4) field.prec = data[offset+16] - if field.prec > 2 then - field.prec = 2 + if field.prec > 3 then + field.prec = 3 end field.step = fieldGetValue(data, offset+17, 4) field.unit, offset = fieldGetString(data, offset+21) end +local function formatFloat(num, decimals) + local mult = 10^(decimals or 0) + local val = num / mult + return string.format("%." .. decimals .. "f", val) +end + local function fieldFloatDisplay(field, y, attr) - local attrnum - if field.prec == 1 then - attrnum = LEFT + attr + PREC1 - elseif field.prec == 2 then - attrnum = LEFT + attr + PREC2 - else - attrnum = LEFT + attr - end - -- lcd.drawNumber(140, y, field.value, attrnum) -- NOTE: original code getLastPos not available in Horus - -- lcd.drawText(lcd.getLastPos(), y, field.unit, attr) -- NOTE: original code getLastPos not available in Horus - lcd.drawText(140, y, field.value .. field.unit, attr) -- NOTE: Concenated fields instead of get lastPos + lcd.drawText(140, y, formatFloat(field.value, field.prec) .. field.unit, attr) end local function fieldFloatSave(field) diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua index 8ccdbf285..b6115d088 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -72,7 +72,7 @@ local function incrField(step) end else local min, max = 0, 0 - if field.type <= 5 then + if ((field.type <= 5) or (field.type == 8)) then min = field.min max = field.max step = field.step * step @@ -238,23 +238,21 @@ local function fieldFloatLoad(field, data, offset) field.default = fieldGetValue(data, offset+12, 4) fieldUnsignedToSigned(field, 4) field.prec = data[offset+16] - if field.prec > 2 then - field.prec = 2 + if field.prec > 3 then + field.prec = 3 end field.step = fieldGetValue(data, offset+17, 4) field.unit, offset = fieldGetString(data, offset+21) end +local function formatFloat(num, decimals) + local mult = 10^(decimals or 0) + local val = num / mult + return string.format("%." .. decimals .. "f", val) +end + local function fieldFloatDisplay(field, y, attr) - local attrnum - if field.prec == 1 then - attrnum = LEFT + attr + PREC1 - elseif field.prec == 2 then - attrnum = LEFT + attr + PREC2 - else - attrnum = LEFT + attr - end - lcd.drawNumber(89, y, field.value, attrnum) + lcd.drawText(89, y, formatFloat(field.value, field.prec), LEFT + attr) lcd.drawText(lcd.getLastPos(), y, field.unit, attr) end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua index 58416af36..833ec6d83 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -72,7 +72,7 @@ local function incrField(step) end else local min, max = 0, 0 - if field.type <= 5 then + if ((field.type <= 5) or (field.type == 8)) then min = field.min max = field.max step = field.step * step @@ -238,23 +238,21 @@ local function fieldFloatLoad(field, data, offset) field.default = fieldGetValue(data, offset+12, 4) fieldUnsignedToSigned(field, 4) field.prec = data[offset+16] - if field.prec > 2 then - field.prec = 2 + if field.prec > 3 then + field.prec = 3 end field.step = fieldGetValue(data, offset+17, 4) field.unit, offset = fieldGetString(data, offset+21) end +local function formatFloat(num, decimals) + local mult = 10^(decimals or 0) + local val = num / mult + return string.format("%." .. decimals .. "f", val) +end + local function fieldFloatDisplay(field, y, attr) - local attrnum - if field.prec == 1 then - attrnum = LEFT + attr + PREC1 - elseif field.prec == 2 then - attrnum = LEFT + attr + PREC2 - else - attrnum = LEFT + attr - end - lcd.drawNumber(140, y, field.value, attrnum) + lcd.drawText(140, y, formatFloat(field.value, field.prec), LEFT + attr) lcd.drawText(lcd.getLastPos(), y, field.unit, attr) end From 93e8d83a9f1719111c55626feae09009eef7c818 Mon Sep 17 00:00:00 2001 From: Carsten W Date: Sat, 25 Jan 2020 11:33:56 +0100 Subject: [PATCH 17/70] fix nonworking retun to deviceoverview on T16 (#7334) --- radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua index 3f99b5dbb..d592677db 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -419,7 +419,7 @@ end -- Main local function runDevicePage(event) - if event == EVT_EXIT_BREAK then -- exit script + if event == EVT_VIRTUAL_EXIT then -- exit script if edit == true then edit = false local field = getField(lineIndex) @@ -451,9 +451,9 @@ local function runDevicePage(event) end end elseif edit then - if event == EVT_VIRTUAL_INC then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then incrField(1) - elseif event == EVT_VIRTUAL_DEC then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then incrField(-1) end else From fa95bb7e247376e80c3b86c4cea156e18370087a Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sun, 26 Jan 2020 10:26:18 +0100 Subject: [PATCH 18/70] Update CREDITS.txt --- CREDITS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CREDITS.txt b/CREDITS.txt index 6f1feb477..a36b07e91 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1691,3 +1691,5 @@ Thomas Floyd Matthew LePard Peter Schneider Michel Garbarino +Achim Stolze +Fernando Rimoldi From 96a631284ce1abe954abbcc138f01e0470d7093f Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sun, 26 Jan 2020 16:53:13 +0100 Subject: [PATCH 19/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index a36b07e91..95b67bc67 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1693,3 +1693,4 @@ Peter Schneider Michel Garbarino Achim Stolze Fernando Rimoldi +Bernard Delpy From 080f650ff2facca8206417a34c23f50b5709f691 Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 27 Jan 2020 07:07:35 +0100 Subject: [PATCH 20/70] Add missing file in DB theme --- radio/sdcard/horus/THEMES/Darkblue/shutdown.bmp | Bin 0 -> 48538 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 radio/sdcard/horus/THEMES/Darkblue/shutdown.bmp diff --git a/radio/sdcard/horus/THEMES/Darkblue/shutdown.bmp b/radio/sdcard/horus/THEMES/Darkblue/shutdown.bmp new file mode 100755 index 0000000000000000000000000000000000000000..be7034db74473f701eb7bc031046d0f21c905ae3 GIT binary patch literal 48538 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 Date: Mon, 27 Jan 2020 07:18:32 +0100 Subject: [PATCH 21/70] Add missing interval, fix #7336 --- radio/src/gui/480x272/view_statistics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/480x272/view_statistics.cpp b/radio/src/gui/480x272/view_statistics.cpp index 179bf546c..c13dff60e 100644 --- a/radio/src/gui/480x272/view_statistics.cpp +++ b/radio/src/gui/480x272/view_statistics.cpp @@ -127,7 +127,7 @@ bool menuStatsDebug(event_t event) lcdDrawText(MENU_STATS_COLUMN1, y+1, "[Duration]", HEADER_COLOR|SMLSIZE); lcdDrawNumber(lcdNextPos+5, y, 10*maxLuaDuration, LEFT, 0, NULL, "ms"); lcdDrawText(lcdNextPos+20, y+1, "[Interval]", HEADER_COLOR|SMLSIZE); - lcdDrawNumber(lcdNextPos+5, y, 10*maxLuaDuration, LEFT, 0, NULL, "ms"); + lcdDrawNumber(lcdNextPos+5, y, 10*maxLuaInterval, LEFT, 0, NULL, "ms"); y += FH; // lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+line*FH, "Lua memory"); From 23f16d039ec4e2efcb532f83bf69a422d2d406e7 Mon Sep 17 00:00:00 2001 From: Carsten W Date: Mon, 27 Jan 2020 15:10:46 +0100 Subject: [PATCH 22/70] Lua virtual replace (#7337) --- .../sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua | 5 ---- .../horus/SCRIPTS/WIZARD/glider/wizard.lua | 16 ++++++------ .../horus/SCRIPTS/WIZARD/plane/wizard.lua | 16 ++++++------ .../horus/SxR Calibrate/SxR_Calibrate.lua | 22 ++++++++-------- .../taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua | 5 ---- .../taranis-x7/SCRIPTS/WIZARD/delta.lua | 24 ++++++++--------- .../taranis-x7/SCRIPTS/WIZARD/multi.lua | 24 ++++++++--------- .../taranis-x7/SCRIPTS/WIZARD/plane.lua | 20 +++++++------- .../taranis-x7/SCRIPTS/WIZARD/wizard.lua | 8 +++--- radio/sdcard/taranis-x7/SCRIPTS/snake.lua | 2 +- .../SxR Calibrate/SxR_Calibrate.lua | 24 ++++++++--------- .../taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua | 5 ---- .../taranis-x9/SCRIPTS/WIZARD/delta.lua | 20 +++++++------- .../taranis-x9/SCRIPTS/WIZARD/multi.lua | 24 ++++++++--------- .../taranis-x9/SCRIPTS/WIZARD/plane.lua | 20 +++++++------- .../taranis-x9/SCRIPTS/WIZARD/wizard.lua | 8 +++--- radio/sdcard/taranis-x9/SCRIPTS/snake.lua | 2 +- .../SxR Calibrate/SxR_Calibrate.lua | 26 +++++++++---------- 18 files changed, 128 insertions(+), 143 deletions(-) diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua index 73d2b88e2..bbe819087 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua @@ -273,11 +273,6 @@ local function run(event) if event == nil then error("Cannot run as a model script!") return 2 - elseif event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST or event == EVT_SHIFT_BREAK then - --selectPage(1) - elseif event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST or event == EVT_SHIFT_LONG then - --killEvents(event); - --selectPage(-1) end local result = pages[page](event) diff --git a/radio/sdcard/horus/SCRIPTS/WIZARD/glider/wizard.lua b/radio/sdcard/horus/SCRIPTS/WIZARD/glider/wizard.lua index 1985589bc..a07089513 100644 --- a/radio/sdcard/horus/SCRIPTS/WIZARD/glider/wizard.lua +++ b/radio/sdcard/horus/SCRIPTS/WIZARD/glider/wizard.lua @@ -91,9 +91,9 @@ end -- Main local function runFieldsPage(event) - if event == EVT_EXIT_BREAK then -- exit script + if event == EVT_VIRTUAL_EXIT then -- exit script return 2 - elseif event == EVT_ENTER_BREAK or event == EVT_ROT_BREAK then -- toggle editing/selecting current field + elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field if fields[current][5] ~= nil then edit = not edit if edit == false then @@ -101,15 +101,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else - if event == EVT_MINUS_FIRST or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_PLUS_FIRST or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -465,9 +465,9 @@ local function run(event) if event == nil then error("Cannot be run as a model script!") return 2 - elseif (event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST) and page < #pages-1 then + elseif event == EVT_VIRTUAL_NEXT_PAGE and page < #pages-1 then selectPage(1) - elseif (event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST) and page > 1 then + elseif event == EVT_VIRTUAL_PREV_PAGE and page > 1 then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/horus/SCRIPTS/WIZARD/plane/wizard.lua b/radio/sdcard/horus/SCRIPTS/WIZARD/plane/wizard.lua index 37a78d4e3..3c44e5ad5 100755 --- a/radio/sdcard/horus/SCRIPTS/WIZARD/plane/wizard.lua +++ b/radio/sdcard/horus/SCRIPTS/WIZARD/plane/wizard.lua @@ -91,9 +91,9 @@ end -- Main local function runFieldsPage(event) - if event == EVT_EXIT_BREAK then -- exit script + if event == EVT_VIRTUAL_EXIT then -- exit script return 2 - elseif event == EVT_ENTER_BREAK or event == EVT_ROT_BREAK then -- toggle editing/selecting current field + elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field if fields[current][5] ~= nil then edit = not edit if edit == false then @@ -101,15 +101,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else - if event == EVT_MINUS_FIRST or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_PLUS_FIRST or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -465,9 +465,9 @@ local function run(event) if event == nil then error("Cannot be run as a model script!") return 2 - elseif (event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST) and page < #pages-1 then + elseif event == EVT_VIRTUAL_NEXT_PAGE and page < #pages-1 then selectPage(1) - elseif (event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST) and page > 1 then + elseif event == EVT_VIRTUAL_PREV_PAGE and page > 1 then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/horus/SxR Calibrate/SxR_Calibrate.lua b/radio/sdcard/horus/SxR Calibrate/SxR_Calibrate.lua index 4568b50eb..fca13271f 100755 --- a/radio/sdcard/horus/SxR Calibrate/SxR_Calibrate.lua +++ b/radio/sdcard/horus/SxR Calibrate/SxR_Calibrate.lua @@ -237,9 +237,9 @@ end -- Main local function runFieldsPage(event) - if event == EVT_EXIT_BREAK then -- exit script + if event == EVT_VIRTUAL_EXIT then -- exit script return 2 - elseif event == EVT_ENTER_BREAK or event == EVT_ROT_BREAK then -- toggle editing/selecting current field + elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field if fields[current][4] ~= nil then edit = not edit if edit == false then @@ -247,15 +247,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else - if event == EVT_MINUS_FIRST or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_PLUS_FIRST or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -313,11 +313,11 @@ local function runCalibrationPage(event) lcd.drawBitmap(Bitmap.open("img/done.bmp"),200, 100) lcd.drawText(160, 220, "Press [RTN] when ready", attr) end - if calibrationStep > 6 and (event == EVT_ENTER_BREAK or event == EVT_EXIT_BREAK) then + if calibrationStep > 6 and (event == EVT_VIRTUAL_ENTER or event == EVT_VIRTUAL_EXIT) then return 2 - elseif event == EVT_ENTER_BREAK then + elseif event == EVT_VIRTUAL_ENTER then calibrationState = 1 - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then if calibrationStep > 0 then calibrationStep = 0 end @@ -341,9 +341,9 @@ local function run(event) if event == nil then error("Cannot be run as a model script!") return 2 - elseif event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST then + elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua index 73d2b88e2..bbe819087 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua @@ -273,11 +273,6 @@ local function run(event) if event == nil then error("Cannot run as a model script!") return 2 - elseif event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST or event == EVT_SHIFT_BREAK then - --selectPage(1) - elseif event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST or event == EVT_SHIFT_LONG then - --killEvents(event); - --selectPage(-1) end local result = pages[page](event) diff --git a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/delta.lua b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/delta.lua index b30185e2f..bcd9238f4 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/delta.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/delta.lua @@ -52,10 +52,10 @@ end local function fieldIncDec(event, value, max, force) if edit or force==true then - if event == EVT_ROT_LEFT or event == EVT_UP_BREAK then + if event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then value = (value + max) dirty = true - elseif event == EVT_ROT_RIGHT or event == EVT_DOWN_BREAK then + elseif event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then value = (value + max + 2) dirty = true end @@ -66,12 +66,12 @@ end local function valueIncDec(event, value, min, max) if edit then - if event == EVT_ROT_RIGHT or event == EVT_RIGHT_BREAK then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_ROT_LEFT or event == EVT_LEFT_BREAK then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -82,22 +82,22 @@ local function valueIncDec(event, value, min, max) end local function navigate(event, fieldMax, prevPage, nextPage) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then edit = not edit dirty = true elseif edit then - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then edit = false dirty = true elseif not dirty then dirty = blinkChanged() end else - if event == EVT_PAGE_BREAK or event==EVT_RIGHT_BREAK then + if event == EVT_VIRTUAL_NEXT then page = nextPage field = 0 dirty = true - elseif event == EVT_PAGE_LONG or event==EVT_LEFT_BREAK then + elseif event == EVT_VIRTUAL_PREV then page = prevPage field = 0 killEvents(event); @@ -120,7 +120,7 @@ local function getFieldFlags(position) end local function channelIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event==EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -276,7 +276,7 @@ local function servoMenu(event) limits.revert = fieldIncDec(event, limits.revert, 1) end model.setOutput(servoPage, limits) - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then servoPage = nil dirty = true end @@ -348,9 +348,9 @@ local function confirmationMenu(event) navigate(event, fieldsMax, RUDDER_PAGE, page) - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 - elseif event == EVT_ENTER_LONG then + elseif event == EVT_VIRTUAL_ENTER_LONG then killEvents(event) applySettings() return 2 diff --git a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua index ebc7c536f..f4677ed4e 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua @@ -58,10 +58,10 @@ end local function fieldIncDec(event, value, max, force) if edit or force==true then - if event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_INC then value = (value + max) dirty = true - elseif event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_DEC then value = (value + max + 2) dirty = true end @@ -72,12 +72,12 @@ end local function valueIncDec(event, value, min, max) if edit then - if event == EVT_ROT_RIGHT or event == EVT_RIGHT_FIRST then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_ROT_LEFT or event == EVT_LEFT_FIRST then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -88,11 +88,11 @@ local function valueIncDec(event, value, min, max) end local function navigate(event, fieldMax, prevPage, nextPage) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then edit = not edit dirty = true elseif edit then - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then edit = false dirty = true elseif not dirty then @@ -126,7 +126,7 @@ local function getFieldFlags(position) end local function channelIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event==EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -137,12 +137,12 @@ end local function switchValueIncDec(event, value, min, max) if edit then - if event == EVT_ROT_RIGHT or event == EVT_RIGHT_FIRST then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_ROT_LEFT or event == EVT_LEFT_FIRST then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -153,7 +153,7 @@ local function switchValueIncDec(event, value, min, max) end local function switchIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event== EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -399,9 +399,9 @@ local function confirmationMenu(event) navigate(event, fieldsMax, BEEPER_PAGE, page) - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 - elseif event == EVT_ENTER_LONG then + elseif event == EVT_VIRTUAL_ENTER_LONG then killEvents(event) applySettings() return 2 diff --git a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/plane.lua b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/plane.lua index 6558b8f12..26282cdf7 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/plane.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/plane.lua @@ -62,10 +62,10 @@ end local function fieldIncDec(event, value, max, force) if edit or force==true then - if event == EVT_ROT_LEFT or event == EVT_UP_BREAK then + if event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then value = (value + max) dirty = true - elseif event == EVT_ROT_RIGHT or event == EVT_DOWN_BREAK then + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then value = (value + max + 2) dirty = true end @@ -76,12 +76,12 @@ end local function valueIncDec(event, value, min, max) if edit then - if event == EVT_ROT_RIGHT or event == EVT_RIGHT_BREAK then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_ROT_LEFT or event == EVT_LEFT_BREAK then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -92,11 +92,11 @@ local function valueIncDec(event, value, min, max) end local function navigate(event, fieldMax, prevPage, nextPage) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then edit = not edit dirty = true elseif edit then - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then edit = false dirty = true elseif not dirty then @@ -130,7 +130,7 @@ local function getFieldFlags(position) end local function channelIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event==EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -420,7 +420,7 @@ local function servoMenu(event) limits.revert = fieldIncDec(event, limits.revert, 1) end model.setOutput(servoPage, limits) - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then servoPage = nil dirty = true end @@ -544,9 +544,9 @@ local function confirmationMenu(event) navigate(event, fieldsMax, TAIL_PAGE, page) - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 - elseif event == EVT_ENTER_LONG then + elseif event == EVT_VIRTUAL_ENTER_LONG then killEvents(event) applySettings() return 2 diff --git a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/wizard.lua b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/wizard.lua index 2568f22b9..06f365c9c 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/wizard.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/wizard.lua @@ -23,9 +23,9 @@ local MODELTYPE_QUAD = 2 -- Common functions local function fieldIncDec(event, value, max) - if event == EVT_ROT_LEFT or event == EVT_UP_BREAK then + if event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then value = (value + max) - elseif event == EVT_ROT_RIGHT or event == EVT_DOWN_BREAK then + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then value = (value + max + 2) end value = (value % (max+1)) @@ -53,7 +53,7 @@ end local function modelTypeMenu(event) drawModelChoiceMenu() - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then if modelType == MODELTYPE_PLANE then return "plane.lua" elseif modelType == MODELTYPE_DELTA then @@ -73,7 +73,7 @@ local function run(event) error("Cannot be run as a model script!") end - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/snake.lua b/radio/sdcard/taranis-x7/SCRIPTS/snake.lua index 012a9f1e1..d3a1914bb 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/snake.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/snake.lua @@ -127,7 +127,7 @@ local function run(event) raise("Cannot be run as a model script!") end - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 end diff --git a/radio/sdcard/taranis-x7/SxR Calibrate/SxR_Calibrate.lua b/radio/sdcard/taranis-x7/SxR Calibrate/SxR_Calibrate.lua index 5b2e141a8..b9e406691 100644 --- a/radio/sdcard/taranis-x7/SxR Calibrate/SxR_Calibrate.lua +++ b/radio/sdcard/taranis-x7/SxR Calibrate/SxR_Calibrate.lua @@ -62,10 +62,10 @@ local function runWarningPage(event) lcd.drawText(0, 30, "power, and a level surface.", SMLSIZE) lcd.drawText(0, 40, "Press [Enter] when ready", SMLSIZE) lcd.drawText(0, 50, "Press [Exit] to cancel", SMLSIZE) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then selectPage(1) return 0 - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then return 2 end return 0 @@ -186,9 +186,9 @@ end -- Main local function runFieldsPage(event) - if event == EVT_EXIT_BREAK then -- exit script + if event == EVT_VIRTUAL_EXIT then -- exit script return 2 - elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field + elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field if fields[current][4] ~= nil then edit = not edit if edit == false then @@ -196,15 +196,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT or event == EVT_DOWN_BREAK then + if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REP then addField(1) - elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT or event == EVT_UP_BREAK then + elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REP then addField(-1) end else - if event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_UP_BREAK then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REP then selectField(1) - elseif event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_DOWN_BREAK then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REP then selectField(-1) end end @@ -260,9 +260,9 @@ local function runCalibrationPage(event) -- lcd.drawText(10, 19, "Done",0) lcd.drawText(0, 56, "Press [Exit] when ready", attr) end - if calibrationStep > 6 and (event == EVT_ENTER_BREAK or event == EVT_EXIT_BREAK) then + if calibrationStep > 6 and (event == EVT_VIRTUAL_ENTER or event == EVT_VIRTUAL_EXIT) then return 2 - elseif event == EVT_ENTER_BREAK and positionConfirmed then + elseif event == EVT_VIRTUAL_ENTER and positionConfirmed then calibrationState = 1 positionConfirmed = 0 end @@ -284,9 +284,9 @@ local function run(event) if event == nil then error("Cannot be run as a model script!") return 2 - elseif event == EVT_PAGE_BREAK or event==EVT_RIGHT_BREAK then + elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_PAGE_LONG or event==EVT_LEFT_BREAK then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua index 73d2b88e2..bbe819087 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua @@ -273,11 +273,6 @@ local function run(event) if event == nil then error("Cannot run as a model script!") return 2 - elseif event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST or event == EVT_SHIFT_BREAK then - --selectPage(1) - elseif event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST or event == EVT_SHIFT_LONG then - --killEvents(event); - --selectPage(-1) end local result = pages[page](event) diff --git a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/delta.lua b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/delta.lua index 06af19541..cf559c6b2 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/delta.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/delta.lua @@ -52,10 +52,10 @@ end local function fieldIncDec(event, value, max, force) if edit or force==true then - if event == EVT_PLUS_BREAK or event == EVT_ROT_LEFT then + if event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then value = (value + max) dirty = true - elseif event == EVT_MINUS_BREAK or event == EVT_ROT_RIGHT then + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then value = (value + max + 2) dirty = true end @@ -66,12 +66,12 @@ end local function valueIncDec(event, value, min, max) if edit then - if event == EVT_PLUS_FIRST or event == EVT_PLUS_REPT or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_MINUS_FIRST or event == EVT_MINUS_REPT or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -82,11 +82,11 @@ local function valueIncDec(event, value, min, max) end local function navigate(event, fieldMax, prevPage, nextPage) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then edit = not edit dirty = true elseif edit then - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then edit = false dirty = true elseif not dirty then @@ -120,7 +120,7 @@ local function getFieldFlags(position) end local function channelIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event == EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -284,7 +284,7 @@ local function servoMenu(event) limits.revert = fieldIncDec(event, limits.revert, 1) end model.setOutput(servoPage, limits) - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then servoPage = nil dirty = true end @@ -357,9 +357,9 @@ local function confirmationMenu(event) navigate(event, fieldsMax, RUDDER_PAGE, page) - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 - elseif event == EVT_ENTER_LONG then + elseif event == EVT_VIRTUAL_ENTER_LONG then killEvents(event) applySettings() return 2 diff --git a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/multi.lua b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/multi.lua index 773abafad..3296626ad 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/multi.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/multi.lua @@ -57,10 +57,10 @@ end local function fieldIncDec(event, value, max, force) if edit or force==true then - if event == EVT_PLUS_BREAK or event == EVT_ROT_LEFT then + if event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then value = (value + max) dirty = true - elseif event == EVT_MINUS_BREAK or event == EVT_ROT_RIGHT then + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then value = (value + max + 2) dirty = true end @@ -71,12 +71,12 @@ end local function valueIncDec(event, value, min, max) if edit then - if event == EVT_PLUS_FIRST or event == EVT_PLUS_REPT or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_MINUS_FIRST or event == EVT_MINUS_REPT or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -87,11 +87,11 @@ local function valueIncDec(event, value, min, max) end local function navigate(event, fieldMax, prevPage, nextPage) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then edit = not edit dirty = true elseif edit then - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then edit = false dirty = true elseif not dirty then @@ -125,7 +125,7 @@ local function getFieldFlags(position) end local function channelIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event == EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -136,12 +136,12 @@ end local function switchValueIncDec(event, value, min, max) if edit then - if event == EVT_PLUS_FIRST or event == EVT_PLUS_REPT or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_MINUS_FIRST or event == EVT_MINUS_REPT or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -152,7 +152,7 @@ local function switchValueIncDec(event, value, min, max) end local function switchIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event == EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -415,9 +415,9 @@ local function confirmationMenu(event) navigate(event, fieldsMax, BEEPER_PAGE, page) - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 - elseif event == EVT_ENTER_LONG then + elseif event == EVT_VIRTUAL_ENTER_LONG then killEvents(event) applySettings() return 2 diff --git a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/plane.lua b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/plane.lua index 5a75fbcc1..7d20bd97e 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/plane.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/plane.lua @@ -62,10 +62,10 @@ end local function fieldIncDec(event, value, max, force) if edit or force==true then - if event == EVT_PLUS_BREAK or event == EVT_ROT_LEFT then + if event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then value = (value + max) dirty = true - elseif event == EVT_MINUS_BREAK or event == EVT_ROT_RIGHT then + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then value = (value + max + 2) dirty = true end @@ -76,12 +76,12 @@ end local function valueIncDec(event, value, min, max) if edit then - if event == EVT_PLUS_FIRST or event == EVT_PLUS_REPT or event == EVT_ROT_RIGHT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then if value < max then value = (value + 1) dirty = true end - elseif event == EVT_MINUS_FIRST or event == EVT_MINUS_REPT or event == EVT_ROT_LEFT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then if value > min then value = (value - 1) dirty = true @@ -92,11 +92,11 @@ local function valueIncDec(event, value, min, max) end local function navigate(event, fieldMax, prevPage, nextPage) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then edit = not edit dirty = true elseif edit then - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then edit = false dirty = true elseif not dirty then @@ -130,7 +130,7 @@ local function getFieldFlags(position) end local function channelIncDec(event, value) - if not edit and event==EVT_MENU_BREAK then + if not edit and event == EVT_VIRTUAL_MENU then servoPage = value dirty = true else @@ -425,7 +425,7 @@ local function servoMenu(event) limits.revert = fieldIncDec(event, limits.revert, 1) end model.setOutput(servoPage, limits) - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then servoPage = nil dirty = true end @@ -550,9 +550,9 @@ local function confirmationMenu(event) navigate(event, fieldsMax, TAIL_PAGE, page) - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 - elseif event == EVT_ENTER_LONG then + elseif event == EVT_VIRTUAL_ENTER_LONG then killEvents(event) applySettings() return 2 diff --git a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/wizard.lua b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/wizard.lua index 463522765..7d330daae 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/wizard.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/WIZARD/wizard.lua @@ -25,10 +25,10 @@ local MODELTYPE_QUAD = 2 -- Common functions local function fieldIncDec(event, value, max) - if event == EVT_PLUS_BREAK or event == EVT_ROT_LEFT or event == EVT_PLUS_REPT then + if event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then value = (value + max) dirty = true - elseif event == EVT_MINUS_BREAK or event == EVT_ROT_RIGHT or event == EVT_MINUS_REPT then + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then value = (value + max + 2) dirty = true end @@ -56,7 +56,7 @@ local function modelTypeMenu(event) drawModelChoiceMenu() dirty = false end - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then if modelType == MODELTYPE_PLANE then return "plane.lua" elseif modelType == MODELTYPE_DELTA then @@ -77,7 +77,7 @@ local function run(event) error("Cannot be run as a model script!") end - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 end return modelTypeMenu(event) diff --git a/radio/sdcard/taranis-x9/SCRIPTS/snake.lua b/radio/sdcard/taranis-x9/SCRIPTS/snake.lua index 012a9f1e1..d3a1914bb 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/snake.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/snake.lua @@ -127,7 +127,7 @@ local function run(event) raise("Cannot be run as a model script!") end - if event == EVT_EXIT_BREAK then + if event == EVT_VIRTUAL_EXIT then return 2 end diff --git a/radio/sdcard/taranis-x9/SxR Calibrate/SxR_Calibrate.lua b/radio/sdcard/taranis-x9/SxR Calibrate/SxR_Calibrate.lua index 5a03b1db0..a9c636f30 100644 --- a/radio/sdcard/taranis-x9/SxR Calibrate/SxR_Calibrate.lua +++ b/radio/sdcard/taranis-x9/SxR Calibrate/SxR_Calibrate.lua @@ -60,10 +60,10 @@ local function runWarningPage(event) lcd.drawText(0, 30, "power supply and a flat level surface (desk,...)", SMLSIZE) lcd.drawText(0, 40, "Press [Enter] when ready", SMLSIZE) lcd.drawText(0, 50, "Press [Exit] when cancel", SMLSIZE) - if event == EVT_ENTER_BREAK then + if event == EVT_VIRTUAL_ENTER then selectPage(1) return 0 - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then return 2 end return 0 @@ -184,9 +184,9 @@ end -- Main local function runFieldsPage(event) - if event == EVT_EXIT_BREAK then -- exit script + if event == EVT_VIRTUAL_EXIT then -- exit script return 2 - elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field + elseif event == EVT_VIRTUAL_ENTER then -- toggle editing/selecting current field if fields[current][4] ~= nil then edit = not edit if edit == false then @@ -194,15 +194,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then + if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REP then addField(1) - elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then + elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REP then addField(-1) end else - if event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REP then selectField(1) - elseif event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REP then selectField(-1) end end @@ -235,11 +235,11 @@ local function runCalibrationPage(event) lcd.drawPixmap(10, 19, "bmp/done.bmp") lcd.drawText(0, 56, "Press [Exit] when ready", attr) end - if calibrationStep > 6 and (event == EVT_ENTER_BREAK or event == EVT_EXIT_BREAK) then + if calibrationStep > 6 and (event == EVT_VIRTUAL_ENTER or event == EVT_VIRTUAL_EXIT) then return 2 - elseif event == EVT_ENTER_BREAK then + elseif event == EVT_VIRTUAL_ENTER then calibrationState = 1 - elseif event == EVT_EXIT_BREAK then + elseif event == EVT_VIRTUAL_EXIT then if calibrationStep > 0 then calibrationStep = 0 end @@ -261,9 +261,9 @@ local function run(event) if event == nil then error("Cannot be run as a model script!") return 2 - elseif event == EVT_PAGE_BREAK then + elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_PAGE_LONG then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end From c817844a8668671525bae779d403bde8d54119e9 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 29 Jan 2020 22:17:36 +0100 Subject: [PATCH 23/70] Update CREDITS.txt --- CREDITS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CREDITS.txt b/CREDITS.txt index 95b67bc67..f90be0081 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1694,3 +1694,5 @@ Michel Garbarino Achim Stolze Fernando Rimoldi Bernard Delpy +Daniel Dubovsky +Jonathan Starch From cde54f04f4f94a2ff0783440887fbb88ac02c6ae Mon Sep 17 00:00:00 2001 From: Offer Shmuely Date: Thu, 30 Jan 2020 12:34:08 +0200 Subject: [PATCH 24/70] shmuely/horus batt widget faster (#7338) BattCheck optimization --- radio/sdcard/horus/WIDGETS/BattCheck/main.lua | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/radio/sdcard/horus/WIDGETS/BattCheck/main.lua b/radio/sdcard/horus/WIDGETS/BattCheck/main.lua index ddd83039d..abe3460d5 100755 --- a/radio/sdcard/horus/WIDGETS/BattCheck/main.lua +++ b/radio/sdcard/horus/WIDGETS/BattCheck/main.lua @@ -16,11 +16,16 @@ ---- # # ---- ######################################################################### +-- Horus Widget to display the levels of lipo battery with per cell indication +-- 3djc & Offer Shmuely +-- Date: 2020 +-- ver: 0.4 + local _options = { - { "Sensor", SOURCE, 0 }, + { "Sensor", SOURCE, 0 }, -- default to 'Cels' { "Color", COLOR, WHITE }, { "Shadow", BOOL, 0 }, - { "LowestCell", BOOL, 1 } + { "LowestCell", BOOL, 1 } -- 0=main voltage display shows all-cell-voltage, 1=main voltage display shows lowest-cell } -- This function is run once at the creation of the widget @@ -29,12 +34,12 @@ local function create(zone, options) zone = zone, options = options, counter = 0, - shadowed = 0, + no_telem_blink = 0, isDataAvailable = 0, cellDataLive = {0,0,0,0,0,0}, - cellDataHistoryLowest = {0,0,0,0,0,0}, + cellDataHistoryLowest = {5,5,5,5,5,5}, cellDataHistoryCellLowest = 5, cellMax = 0, cellMin = 0, @@ -112,51 +117,47 @@ local function calculateBatteryData(wgt) return end - -- this is necessary for simu where cell-count can change if #wgt.cellDataHistoryLowest ~= #newCellData then wgt.cellDataHistoryLowest = {} for k, v in pairs(newCellData) do - wgt.cellDataHistoryLowest[k] = v - end - end - -- stores the lowest cell values in historical table - for k, v in pairs(newCellData) do - if v < wgt.cellDataHistoryLowest[k] then - wgt.cellDataHistoryLowest[k] = v + wgt.cellDataHistoryLowest[k] = 5 -- invalid reading, set high value so the min() will update it soon end end - --- calc highest of all cels local cellMax = 0 + local cellMin = 5 + local cellSum = 0 for k, v in pairs(newCellData) do + -- stores the lowest cell values in historical table + if v > 1 and v < wgt.cellDataHistoryLowest[k] then -- min 1v to consider a valid reading + wgt.cellDataHistoryLowest[k] = v + + --- calc history lowest of all cells + if v < wgt.cellDataHistoryCellLowest then + wgt.cellDataHistoryCellLowest = v + end + + end + + -- calc highest of all cells if v > cellMax then cellMax = v end - end - wgt.cellMax = cellMax - --- calc lowest of all cels - local cellMin = 5 - for k, v in pairs(newCellData) do - if v < cellMin and v > 1 then -- >1 to ignore invalid values + --- calc lowest of all cells + if v < cellMin and v > 1 then -- min 1v to consider a valid reading cellMin = v end - end - wgt.cellMin = cellMin - - --- calc history lowest of all cells - if cellMin < wgt.cellDataHistoryCellLowest and cellMin > 1 then -- >1 to ignore invalid values - wgt.cellDataHistoryCellLowest = cellMin - end - - wgt.cellCount = #newCellData - - --- sum of all cells - local cellSum = 0 - for k, v in pairs(newCellData) do + --- sum of all cells cellSum = cellSum + v + + end + + wgt.cellMin = cellMin + wgt.cellMax = cellMax + wgt.cellCount = #newCellData wgt.cellSum = cellSum --- average of all cells @@ -328,7 +329,7 @@ local function refreshZoneLarge(wgt) lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y, wgt.cellPercent .. "%", RIGHT + DBLSIZE + CUSTOM_COLOR + wgt.shadowed) lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + 30, string.format("%2.1fV", wgt.mainValue), RIGHT + DBLSIZE + CUSTOM_COLOR + wgt.shadowed) - lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + 70, string.format("%2.1fV %2.1fS", wgt.secondaryValue, wgt.cellCount), RIGHT + SMLSIZE + CUSTOM_COLOR + wgt.shadowed) + lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + 70, string.format("%2.1fV %dS", wgt.secondaryValue, wgt.cellCount), RIGHT + SMLSIZE + CUSTOM_COLOR + wgt.shadowed) -- fill batt lcd.setColor(CUSTOM_COLOR, getPercentColor(wgt.cellPercent)) lcd.drawFilledRectangle(wgt.zone.x + myBatt.x, wgt.zone.y + myBatt.y + myBatt.h + myBatt.cath_h - math.floor(wgt.cellPercent / 100 * myBatt.h), myBatt.w, math.floor(wgt.cellPercent / 100 * myBatt.h), CUSTOM_COLOR) @@ -372,7 +373,7 @@ local function refreshZoneXLarge(wgt) lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + myBatt.y, wgt.cellPercent .. "%", RIGHT + DBLSIZE + CUSTOM_COLOR + wgt.shadowed + wgt.no_telem_blink) lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + myBatt.y + 30, string.format("%2.1fV", wgt.mainValue), RIGHT + DBLSIZE + CUSTOM_COLOR + wgt.shadowed + wgt.no_telem_blink) - lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + myBatt.y + 105, string.format("%2.1fV %2.1fS", wgt.secondaryValue, wgt.cellCount), RIGHT + SMLSIZE + CUSTOM_COLOR + wgt.shadowed + wgt.no_telem_blink) + lcd.drawText(wgt.zone.x + wgt.zone.w, wgt.zone.y + myBatt.y + 105, string.format("%2.1fV %dS", wgt.secondaryValue, wgt.cellCount), RIGHT + SMLSIZE + CUSTOM_COLOR + wgt.shadowed + wgt.no_telem_blink) -- draw cells local pos = { { x = 111, y = 38 }, { x = 164, y = 38 }, { x = 217, y = 38 }, { x = 111, y = 57 }, { x = 164, y = 57 }, { x = 217, y = 57 } } From 6a52627f47c05b1d835122b2df9fc047154fcbb5 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 30 Jan 2020 11:37:26 +0100 Subject: [PATCH 25/70] Increase output buffer (#7323) --- radio/src/lua/api_general.cpp | 8 ++++++++ radio/src/telemetry/telemetry.h | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 2a5db1422..0bdf7ba47 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -456,6 +456,10 @@ static int luaSportTelemetryPush(lua_State * L) lua_pushboolean(L, outputTelemetryBuffer.isAvailable()); return 1; } + else if (lua_gettop(L) > sizeof(SportTelemetryPacket) ) { + lua_pushboolean(L, false); + return 1; + } uint16_t dataId = luaL_checkunsigned(L, 3); @@ -653,6 +657,10 @@ static int luaCrossfireTelemetryPush(lua_State * L) if (lua_gettop(L) == 0) { lua_pushboolean(L, outputTelemetryBuffer.isAvailable()); } + else if (lua_gettop(L) > TELEMETRY_OUTPUT_BUFFER_SIZE ) { + lua_pushboolean(L, false); + return 1; + } else if (outputTelemetryBuffer.isAvailable()) { uint8_t command = luaL_checkunsigned(L, 1); luaL_checktype(L, 2, LUA_TTABLE); diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 9a6872e5a..c4a5e325a 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -171,6 +171,7 @@ void logTelemetryWriteByte(uint8_t data); #define LOG_TELEMETRY_WRITE_START() #define LOG_TELEMETRY_WRITE_BYTE(data) #endif +#define TELEMETRY_OUTPUT_BUFFER_SIZE 64 class OutputTelemetryBuffer { public: @@ -212,7 +213,8 @@ class OutputTelemetryBuffer { void pushByte(uint8_t byte) { - data[size++] = byte; + if (size < TELEMETRY_OUTPUT_BUFFER_SIZE) + data[size++] = byte; } void pushByteWithBytestuffing(uint8_t byte) @@ -244,7 +246,7 @@ class OutputTelemetryBuffer { public: union { SportTelemetryPacket sport; - uint8_t data[16]; + uint8_t data[TELEMETRY_OUTPUT_BUFFER_SIZE]; }; uint8_t size; uint8_t timeout; From 8ef996f992b07c65e26de22bcef8bab0131d1b71 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 30 Jan 2020 11:40:01 +0100 Subject: [PATCH 26/70] Remove uneeded D8 option on some radio (#7295) Remove uneeded D8 option on some radios --- .../src/firmwares/opentx/opentxinterface.cpp | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 741db16b6..294c69a82 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -1170,14 +1170,22 @@ void addOpenTxCommonOptions(OpenTxFirmware * firmware) firmware->addOption("nooverridech", Firmware::tr("No OverrideCH functions available")); } -void addOpenTxRfOptions(OpenTxFirmware * firmware, bool flex = true) +enum RfOptions { + NONE = 0, + EU, + FLEX +}; + +void addOpenTxRfOptions(OpenTxFirmware * firmware, uint8_t options) { static const Firmware::Option opt_eu("eu", Firmware::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015")); static const Firmware::Option opt_fl("flexr9m", Firmware::tr("Enable non certified firmwares")); - if (flex) + if (options == EU + FLEX) firmware->addOptionsGroup({opt_eu, opt_fl}); - else + else if (options == EU) firmware->addOption(opt_eu); + else if (options == FLEX) + firmware->addOption(opt_fl); } void addOpenTxFontOptions(OpenTxFirmware * firmware) @@ -1191,7 +1199,6 @@ void addOpenTxFrskyOptions(OpenTxFirmware * firmware) firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support")); firmware->addOption("nogvars", Firmware::tr("Disable Global variables")); firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen")); - addOpenTxRfOptions(firmware); } void addOpenTxTaranisOptions(OpenTxFirmware * firmware) @@ -1220,7 +1227,7 @@ void addOpenTxArm9xOptions(OpenTxFirmware * firmware, bool dblkeys = true) if (dblkeys) firmware->addOption("dblkeys", Firmware::tr("Enable resetting values by pressing up and down at the same time")); addOpenTxFontOptions(firmware); - addOpenTxRfOptions(firmware, true); + addOpenTxRfOptions(firmware, FLEX); } void registerOpenTxFirmwares() @@ -1233,11 +1240,13 @@ void registerOpenTxFirmwares() addOpenTxTaranisOptions(firmware); addPPMInternalModuleHack(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky Taranis X9D+ 2019 board */ firmware = new OpenTxFirmware("opentx-x9d+2019", Firmware::tr("FrSky Taranis X9D+ 2019"), BOARD_TARANIS_X9DP_2019); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* FrSky Taranis X9D board */ firmware = new OpenTxFirmware("opentx-x9d", Firmware::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D); @@ -1245,6 +1254,7 @@ void registerOpenTxFirmwares() addOpenTxTaranisOptions(firmware); addPPMInternalModuleHack(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky Taranis X9E board */ firmware = new OpenTxFirmware("opentx-x9e", Firmware::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E); @@ -1253,48 +1263,57 @@ void registerOpenTxFirmwares() addOpenTxTaranisOptions(firmware); addPPMInternalModuleHack(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X9-Lite board */ firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X9-LiteS board */ firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X7 board */ firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X7 Access board */ firmware = new OpenTxFirmware("opentx-x7access", Firmware::tr("FrSky Taranis X7 / X7S Access"), BOARD_TARANIS_X7_ACCESS); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X-Lite S/PRO board */ firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X-Lite board */ firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE); // firmware->addOption("stdr9m", Firmware::tr("Use JR-sized R9M module")); addOpenTxTaranisOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X10 board */ firmware = new OpenTxFirmware("opentx-x10", Firmware::tr("FrSky Horus X10 / X10S"), BOARD_X10); addOpenTxFrskyOptions(firmware); firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement")); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* FrSky X10 Express board */ firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 Express / X10S Express"), BOARD_X10_EXPRESS); addOpenTxFrskyOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* FrSky X12 (Horus) board */ firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_HORUS_X12S); @@ -1302,6 +1321,7 @@ void registerOpenTxFirmwares() firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement")); firmware->addOption("pcbdev", Firmware::tr("Use ONLY with first DEV pcb version")); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, EU + FLEX); /* Jumper T12 board */ firmware = new OpenTxFirmware("opentx-t12", QCoreApplication::translate("Firmware", "Jumper T12 / T12 Pro"), BOARD_JUMPER_T12); @@ -1313,6 +1333,7 @@ void registerOpenTxFirmwares() firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module")); addOpenTxFontOptions(firmware); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* Jumper T16 board */ firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16); @@ -1320,6 +1341,7 @@ void registerOpenTxFirmwares() firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module")); firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module")); registerOpenTxFirmware(firmware); + addOpenTxRfOptions(firmware, FLEX); /* 9XR-Pro */ firmware = new OpenTxFirmware("opentx-9xrpro", Firmware::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); From 13488b5c21479fed12a9e5bc490432043017aa9b Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 30 Jan 2020 11:44:33 +0100 Subject: [PATCH 27/70] Move TOOLS menu as first radio screen (#7312) Move TOOLS menu as first radio screen --- radio/src/gui/128x64/menus.h | 8 ++++---- radio/src/gui/128x64/view_main.cpp | 2 +- radio/src/gui/212x64/menu_radio.cpp | 4 ++-- radio/src/gui/212x64/menus.h | 4 ++-- radio/src/gui/212x64/view_main.cpp | 2 +- radio/src/gui/480x272/menu_radio.cpp | 4 ++-- radio/src/gui/480x272/menus.cpp | 2 +- radio/src/gui/480x272/menus.h | 8 ++++---- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index ccde94cc9..d861a626f 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -50,11 +50,11 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF enum MenuRadioIndexes { - MENU_RADIO_SETUP, - CASE_SDCARD(MENU_RADIO_SD_MANAGER) #if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) MENU_RADIO_TOOLS, #endif + CASE_SDCARD(MENU_RADIO_SD_MANAGER) + MENU_RADIO_SETUP, MENU_RADIO_SPECIAL_FUNCTIONS, MENU_RADIO_TRAINER, MENU_RADIO_HARDWARE, @@ -76,11 +76,11 @@ void menuRadioPowerMeter(event_t event); void menuRadioCalibration(event_t event); static const MenuHandlerFunc menuTabGeneral[MENU_RADIO_PAGES_COUNT] = { - menuRadioSetup, - CASE_SDCARD(menuRadioSdManager) #if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) menuRadioTools, #endif + CASE_SDCARD(menuRadioSdManager) + menuRadioSetup, menuRadioSpecialFunctions, menuRadioTrainer, menuRadioHardware, diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 308ba4290..737a4dc44 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -369,7 +369,7 @@ void menuMainView(event_t event) break; case EVT_KEY_GENERAL_MENU: - pushMenu(menuRadioSetup); + pushMenu(menuRadioTools); killEvents(event); break; #endif diff --git a/radio/src/gui/212x64/menu_radio.cpp b/radio/src/gui/212x64/menu_radio.cpp index 082424e07..6e7647a72 100644 --- a/radio/src/gui/212x64/menu_radio.cpp +++ b/radio/src/gui/212x64/menu_radio.cpp @@ -21,11 +21,11 @@ #include "opentx.h" const MenuHandlerFunc menuTabGeneral[MENU_RADIO_PAGES_COUNT] = { - menuRadioSetup, - menuRadioSdManager, #if defined(LUA) || defined(PXX2) menuRadioTools, #endif + menuRadioSdManager, + menuRadioSetup, menuRadioSpecialFunctions, menuRadioTrainer, menuRadioHardware, diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index 24da83e0f..c5025c728 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -52,11 +52,11 @@ void menuTraceBuffer(event_t event); #endif enum MenuRadioIndexes { - MENU_RADIO_SETUP, - MENU_RADIO_SD_MANAGER, #if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) MENU_RADIO_TOOLS, #endif + MENU_RADIO_SD_MANAGER, + MENU_RADIO_SETUP, MENU_RADIO_SPECIAL_FUNCTIONS, MENU_RADIO_TRAINER, MENU_RADIO_HARDWARE, diff --git a/radio/src/gui/212x64/view_main.cpp b/radio/src/gui/212x64/view_main.cpp index 56e4c22ae..720e3ccbf 100644 --- a/radio/src/gui/212x64/view_main.cpp +++ b/radio/src/gui/212x64/view_main.cpp @@ -455,7 +455,7 @@ void menuMainView(event_t event) break; case EVT_KEY_LONG(KEY_MENU): - pushMenu(menuRadioSetup); + pushMenu(menuRadioTools); killEvents(event); break; #endif diff --git a/radio/src/gui/480x272/menu_radio.cpp b/radio/src/gui/480x272/menu_radio.cpp index 42327fc6f..dd5368bc2 100644 --- a/radio/src/gui/480x272/menu_radio.cpp +++ b/radio/src/gui/480x272/menu_radio.cpp @@ -21,11 +21,11 @@ #include "opentx.h" const MenuHandlerFunc menuTabGeneral[MENU_RADIO_PAGES_COUNT] = { - menuRadioSetup, - menuRadioSdManager, #if defined(LUA) || defined(PXX2) menuRadioTools, #endif + menuRadioSdManager, + menuRadioSetup, menuRadioSpecialFunctions, menuRadioTrainer, menuRadioHardware, diff --git a/radio/src/gui/480x272/menus.cpp b/radio/src/gui/480x272/menus.cpp index 44af61725..c166eb86b 100644 --- a/radio/src/gui/480x272/menus.cpp +++ b/radio/src/gui/480x272/menus.cpp @@ -55,7 +55,7 @@ void pushMenu(MenuHandlerFunc newMenu) killEvents(KEY_ENTER); if (menuLevel == 0) { - if (newMenu == menuRadioSetup) + if (newMenu == menuRadioTools) menuVerticalPositions[0] = 1; if (newMenu == menuModelSetup) menuVerticalPositions[0] = 0; diff --git a/radio/src/gui/480x272/menus.h b/radio/src/gui/480x272/menus.h index a3d9574ca..37e33a58f 100644 --- a/radio/src/gui/480x272/menus.h +++ b/radio/src/gui/480x272/menus.h @@ -190,11 +190,11 @@ bool menuRadioDiagAnalogs(event_t event); extern const MenuHandlerFunc menuTabModel[MENU_MODEL_PAGES_COUNT]; enum EnumTabRadio { - MENU_RADIO_SETUP, - MENU_RADIO_SD_MANAGER, #if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) MENU_RADIO_TOOLS, #endif + MENU_RADIO_SD_MANAGER, + MENU_RADIO_SETUP, MENU_RADIO_SPECIAL_FUNCTIONS, MENU_RADIO_TRAINER, MENU_RADIO_HARDWARE, @@ -204,11 +204,11 @@ enum EnumTabRadio { const uint8_t RADIO_ICONS[MENU_RADIO_PAGES_COUNT + 1] = { ICON_RADIO, - ICON_RADIO_SETUP, - ICON_RADIO_SD_MANAGER, #if defined(LUA) || defined(PXX2) ICON_RADIO_TOOLS, #endif + ICON_RADIO_SD_MANAGER, + ICON_RADIO_SETUP, ICON_RADIO_GLOBAL_FUNCTIONS, ICON_RADIO_TRAINER, ICON_RADIO_HARDWARE, From 6fec6eef21338730128e35586050ba1409a193d4 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 30 Jan 2020 13:22:08 +0100 Subject: [PATCH 28/70] Cosmetics --- companion/src/firmwares/opentx/opentxinterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 294c69a82..09aded8e2 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -1172,8 +1172,8 @@ void addOpenTxCommonOptions(OpenTxFirmware * firmware) enum RfOptions { NONE = 0, - EU, - FLEX + EU = 1 << 0, + FLEX = 1 << 1 }; void addOpenTxRfOptions(OpenTxFirmware * firmware, uint8_t options) From 0f9114c52428d36c294aa94b3dd17588b02090b4 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 30 Jan 2020 14:25:09 +0100 Subject: [PATCH 29/70] Initial TX16S (#7344) * TX16S initial push - Radio booting, navigation keys ok * TX16S libsimu * Please Travis * Do not start radio on charger power * USB charger led handling * Revert "USB charger led handling" until we have proper details * Pseudo sport power pin * Please Travis * tx16s serial debug * Add tx16s calibration picture * Review anadir for tx16s, needs to be checked on more radios * Dump raw multi telem on AUX port * More work on TX16S * Fixes * Compilation fix * Compilation fix * Fix Aux Serial power * Various improvement * USB charger led handling * Cosmetics * Cosmetics * USB charger led handling * Add charge indicator on GUI --- companion/src/CMakeLists.txt | 2 + companion/src/apppreferencesdialog.cpp | 2 +- companion/src/companion.qrc | 11 + companion/src/firmwares/boards.cpp | 18 +- companion/src/firmwares/boards.h | 30 ++- companion/src/firmwares/generalsettings.cpp | 20 +- .../src/firmwares/opentx/opentxeeprom.cpp | 70 +++---- .../src/firmwares/opentx/opentxinterface.cpp | 34 +-- companion/src/firmwares/radiodata.cpp | 2 +- companion/src/firmwares/rawsource.cpp | 14 +- companion/src/firmwares/rawswitch.cpp | 8 +- companion/src/generaledit/generalsetup.cpp | 4 +- companion/src/generaledit/hardware.cpp | 4 +- .../src/images/simulator/TX16S/bottom.png | Bin 0 -> 250 bytes companion/src/images/simulator/TX16S/left.png | Bin 0 -> 48315 bytes .../src/images/simulator/TX16S/left_page.png | Bin 0 -> 48258 bytes .../src/images/simulator/TX16S/left_page2.png | Bin 0 -> 48292 bytes .../src/images/simulator/TX16S/left_rtn.png | Bin 0 -> 48242 bytes .../src/images/simulator/TX16S/left_sys.png | Bin 0 -> 48264 bytes .../src/images/simulator/TX16S/left_tele.png | Bin 0 -> 48266 bytes .../src/images/simulator/TX16S/right.png | Bin 0 -> 40325 bytes .../src/images/simulator/TX16S/right_ent.png | Bin 0 -> 40117 bytes .../src/images/simulator/TX16S/right_mdl.png | Bin 0 -> 40247 bytes companion/src/images/simulator/TX16S/top.png | Bin 0 -> 439 bytes companion/src/mainwindow.cpp | 10 +- companion/src/mdichild.cpp | 4 +- companion/src/modeledit/setup.cpp | 16 +- companion/src/modelslist.cpp | 4 +- companion/src/radiointerface.cpp | 2 +- companion/src/simulation/CMakeLists.txt | 2 + companion/src/simulation/simulateduiwidget.h | 13 ++ .../src/simulation/simulateduiwidgetTX16S.cpp | 72 +++++++ .../src/simulation/simulateduiwidgetTX16S.ui | 197 ++++++++++++++++++ .../src/simulation/simulatorstartupdialog.cpp | 2 +- companion/src/simulation/simulatorwidget.cpp | 5 +- companion/src/storage/categorized.cpp | 2 +- companion/src/storage/rlefile.cpp | 18 +- radio/sdcard/horus/THEMES/Darkblue/tx16s.bmp | Bin 0 -> 164938 bytes radio/sdcard/horus/THEMES/Default/tx16s.bmp | Bin 0 -> 124056 bytes .../bitmaps/480x272/mask_txbat_charging.png | Bin 0 -> 4967 bytes radio/src/dataconstants.h | 4 +- radio/src/gui/480x272/bitmaps.cpp | 4 + radio/src/gui/480x272/bitmaps.h | 1 + radio/src/gui/480x272/radio_hardware.cpp | 3 + radio/src/gui/480x272/themes/darkblue.cpp | 2 + radio/src/gui/480x272/themes/default.cpp | 2 + radio/src/gui/480x272/topbar.cpp | 7 +- radio/src/lua/api_general.cpp | 2 +- radio/src/opentx.h | 2 +- radio/src/sdcard.h | 2 + .../targets/common/arm/stm32/adc_driver.cpp | 2 + .../common/arm/stm32/aux_serial_driver.cpp | 9 + .../arm/stm32/bootloader/CMakeLists.txt | 9 + .../common/arm/stm32/bootloader/boot.cpp | 17 +- .../arm/stm32/rotary_encoder_driver.cpp | 2 +- radio/src/targets/horus/CMakeLists.txt | 23 ++ radio/src/targets/horus/board.cpp | 17 ++ radio/src/targets/horus/board.h | 32 ++- radio/src/targets/horus/hal.h | 75 ++++++- radio/src/targets/horus/keys_driver.cpp | 2 +- .../src/targets/horus/usb_charger_driver.cpp | 38 ++++ radio/src/targets/taranis/board.h | 2 + radio/src/targets/taranis/hal.h | 2 + radio/src/telemetry/multi.cpp | 7 + radio/src/translations/untranslated.h | 4 +- 65 files changed, 702 insertions(+), 134 deletions(-) create mode 100755 companion/src/images/simulator/TX16S/bottom.png create mode 100755 companion/src/images/simulator/TX16S/left.png create mode 100755 companion/src/images/simulator/TX16S/left_page.png create mode 100755 companion/src/images/simulator/TX16S/left_page2.png create mode 100755 companion/src/images/simulator/TX16S/left_rtn.png create mode 100755 companion/src/images/simulator/TX16S/left_sys.png create mode 100755 companion/src/images/simulator/TX16S/left_tele.png create mode 100755 companion/src/images/simulator/TX16S/right.png create mode 100755 companion/src/images/simulator/TX16S/right_ent.png create mode 100755 companion/src/images/simulator/TX16S/right_mdl.png create mode 100755 companion/src/images/simulator/TX16S/top.png create mode 100644 companion/src/simulation/simulateduiwidgetTX16S.cpp create mode 100644 companion/src/simulation/simulateduiwidgetTX16S.ui create mode 100755 radio/sdcard/horus/THEMES/Darkblue/tx16s.bmp create mode 100644 radio/sdcard/horus/THEMES/Default/tx16s.bmp create mode 100755 radio/src/bitmaps/480x272/mask_txbat_charging.png create mode 100644 radio/src/targets/horus/usb_charger_driver.cpp diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 0603c40cf..14f24ccba 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -351,6 +351,8 @@ elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS) set(FLAVOUR x10express) elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T16) set(FLAVOUR t16) +elseif(PCB STREQUAL X10 AND PCBREV STREQUAL TX16S) + set(FLAVOUR tx16s) else() string(TOLOWER ${PCB} FLAVOUR) endif() diff --git a/companion/src/apppreferencesdialog.cpp b/companion/src/apppreferencesdialog.cpp index c17d5c88d..63c260176 100644 --- a/companion/src/apppreferencesdialog.cpp +++ b/companion/src/apppreferencesdialog.cpp @@ -541,7 +541,7 @@ void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware) // TODO: Remove once splash replacement supported on Horus // NOTE: 480x272 image causes issues on screens <800px high, needs a solution like scrolling once reinstated - if (IS_HORUS(baseFw->getBoard())) { + if (IS_FAMILY_HORUS_OR_T16(baseFw->getBoard())) { ui->widget_splashImage->hide(); ui->SplashFileName->setText(""); } diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index f91782c50..ce172fbb7 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -190,6 +190,17 @@ images/simulator/JumperT16/left_tele.png images/simulator/JumperT16/right_ent.png images/simulator/JumperT16/right_rtn.png + images/simulator/TX16S/left.png + images/simulator/TX16S/right.png + images/simulator/TX16S/top.png + images/simulator/TX16S/bottom.png + images/simulator/TX16S/left_page.png + images/simulator/TX16S/left_page2.png + images/simulator/TX16S/left_rtn.png + images/simulator/TX16S/left_sys.png + images/simulator/TX16S/left_tele.png + images/simulator/TX16S/right_ent.png + images/simulator/TX16S/right_mdl.png images/wizard/ailerons.png images/wizard/airbrakes.png images/wizard/elevons.png diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index acfc70004..cfadf5936 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -92,6 +92,8 @@ uint32_t Boards::getFourCC(Type board) return 0x3D78746F; case BOARD_JUMPER_T16: return 0x3F78746F; + case BOARD_RADIOMASTER_TX16S: + return 0x3878746F; case BOARD_UNKNOWN: break; } @@ -132,6 +134,7 @@ int Boards::getEEpromSize(Board::Type board) case BOARD_X10: case BOARD_X10_EXPRESS: case BOARD_JUMPER_T16: + case BOARD_RADIOMASTER_TX16S: return 0; } @@ -169,6 +172,7 @@ int Boards::getFlashSize(Type board) case BOARD_X10: case BOARD_X10_EXPRESS: case BOARD_JUMPER_T16: + case BOARD_RADIOMASTER_TX16S: return FSIZE_HORUS; case BOARD_UNKNOWN: return FSIZE_MAX; @@ -284,7 +288,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 2; else if (IS_TARANIS_X9E(board)) return 4; - else if (IS_HORUS_X10(board) || IS_JUMPER_T16(board)) + else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) return 5; else if (IS_HORUS_X12S(board)) return 3; @@ -300,13 +304,13 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case Sliders: if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) return 4; - else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) + else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) return 2; else return 0; case MouseAnalogs: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 2; else return 0; @@ -343,7 +347,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 9; else if (IS_TARANIS(board)) return 8; - else if (IS_HORUS(board)) + else if (IS_FAMILY_HORUS_OR_T16(board)) return 10; else return 7; @@ -363,7 +367,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 9; case NumTrims: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 6; else return 4; @@ -467,7 +471,7 @@ QString Boards::getAnalogInputName(Board::Type board, int index) if (index < DIM(pots)) return pots[index]; } - else if (IS_HORUS_X10(board) || IS_JUMPER_T16(board)) { + else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) { const QString pots[] = { "S1", "6P", @@ -536,6 +540,8 @@ QString Boards::getBoardName(Board::Type board) return "Horus X10/X10S Express"; case BOARD_JUMPER_T16: return "Jumper T16"; + case BOARD_RADIOMASTER_TX16S: + return "Radiomaster TX16S"; default: return tr("Unknown"); } diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 74e690ebf..e4149a298 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -54,9 +54,10 @@ namespace Board { BOARD_TARANIS_X9LITES, BOARD_JUMPER_T12, BOARD_JUMPER_T16, + BOARD_RADIOMASTER_TX16S, }; - constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_T16 ; + constexpr int BOARD_TYPE_MAX = BOARD_RADIOMASTER_TX16S ; enum PotType { @@ -230,6 +231,16 @@ inline bool IS_JUMPER_T16(Board::Type board) return board == Board::BOARD_JUMPER_T16; } +inline bool IS_RADIOMASTER_TX16S(Board::Type board) +{ + return board == Board::BOARD_RADIOMASTER_TX16S; +} + +inline bool IS_FAMILY_T16(Board::Type board) +{ + return board == Board::BOARD_JUMPER_T16 || board == Board::BOARD_RADIOMASTER_TX16S; +} + inline bool IS_TARANIS_XLITE(Board::Type board) { return board == Board::BOARD_TARANIS_XLITE || board == Board::BOARD_TARANIS_XLITES; @@ -300,19 +311,24 @@ inline bool IS_HORUS_X12S(Board::Type board) return board == Board::BOARD_HORUS_X12S; } -inline bool IS_HORUS(Board::Type board) +inline bool IS_FAMILY_HORUS(Board::Type board) { - return IS_HORUS_X12S(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board); + return IS_HORUS_X12S(board) || IS_HORUS_X10(board); +} + +inline bool IS_FAMILY_HORUS_OR_T16(Board::Type board) +{ + return IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board); } inline bool IS_HORUS_OR_TARANIS(Board::Type board) { - return IS_HORUS(board) || IS_TARANIS(board); + return IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS(board); } inline bool IS_STM32(Board::Type board) { - return IS_TARANIS(board) || IS_HORUS(board); + return IS_TARANIS(board) || IS_FAMILY_HORUS_OR_T16(board); } inline bool IS_ARM(Board::Type board) @@ -322,7 +338,7 @@ inline bool IS_ARM(Board::Type board) inline bool HAS_LARGE_LCD(Board::Type board) { - return IS_HORUS(board) || IS_TARANIS_X9(board); + return IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board); } inline bool HAS_EXTERNAL_ANTENNA(Board::Type board) @@ -333,7 +349,7 @@ inline bool HAS_EXTERNAL_ANTENNA(Board::Type board) inline bool IS_ACCESS_RADIO(Board::Type board, QString &id) { return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == Board::BOARD_TARANIS_X9DP_2019 || board == Board::BOARD_X10_EXPRESS || IS_TARANIS_X7_ACCESS(board) || - (IS_HORUS(board) && id.contains("internalaccess"))); + (IS_FAMILY_HORUS_OR_T16(board) && id.contains("internalaccess"))); } #endif // _BOARDS_H_ diff --git a/companion/src/firmwares/generalsettings.cpp b/companion/src/firmwares/generalsettings.cpp index 6cb9fdb9f..1676e913c 100644 --- a/companion/src/firmwares/generalsettings.cpp +++ b/companion/src/firmwares/generalsettings.cpp @@ -88,7 +88,7 @@ GeneralSettings::GeneralSettings() vBatMin = -5; //8,5V vBatMax = -5; //11,5V } - else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) { + else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) { // Lipo 2S vBatWarn = 66; vBatMin = -23; // 6.7V @@ -106,7 +106,7 @@ GeneralSettings::GeneralSettings() backlightMode = 3; // keys and sticks // backlightBright = 0; // 0 = 100% - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { backlightOffBright = 20; } @@ -116,7 +116,7 @@ GeneralSettings::GeneralSettings() if (IS_JUMPER_T16(board)) strcpy(bluetoothName, "t16"); - else if (IS_HORUS(board)) { + else if (IS_FAMILY_HORUS_OR_T16(board)) { strcpy(bluetoothName, "horus"); } else if (IS_TARANIS_X9E(board) || IS_TARANIS_SMALL(board)) { @@ -236,7 +236,7 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board) } // TODO: move to Boards, like with switches - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { potConfig[0] = Board::POT_WITH_DETENT; potConfig[1] = Board::POT_MULTIPOS_SWITCH; potConfig[2] = Board::POT_WITH_DETENT; @@ -269,7 +269,7 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board) sliderConfig[2] = Board::SLIDER_WITH_DETENT; sliderConfig[3] = Board::SLIDER_WITH_DETENT; } - else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) { + else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) { sliderConfig[0] = Board::SLIDER_WITH_DETENT; sliderConfig[1] = Board::SLIDER_WITH_DETENT; } @@ -313,27 +313,27 @@ void GeneralSettings::convert(RadioDataConversionState & cstate) // SE and SG are skipped on X7 board if (IS_TARANIS_X7(cstate.toType)) { - if (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType)) { + if (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType)) { strncpy(switchName[4], switchName[5], sizeof(switchName[4])); strncpy(switchName[5], switchName[7], sizeof(switchName[5])); } } else if (IS_TARANIS_X7(cstate.fromType)) { - if (IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) { + if (IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) { strncpy(switchName[5], switchName[4], sizeof(switchName[5])); strncpy(switchName[7], switchName[5], sizeof(switchName[7])); } } if (IS_JUMPER_T12(cstate.toType)) { - if (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType)) { + if (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType)) { strncpy(switchName[4], switchName[5], sizeof(switchName[0])); strncpy(switchName[5], switchName[7], sizeof(switchName[0])); } } else if (IS_JUMPER_T12(cstate.fromType)) { - if (IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) { + if (IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) { strncpy(switchName[5], switchName[4], sizeof(switchName[0])); strncpy(switchName[7], switchName[5], sizeof(switchName[0])); } @@ -349,7 +349,7 @@ void GeneralSettings::convert(RadioDataConversionState & cstate) strncpy(sliderName[3], sliderName[1], sizeof(sliderName[3])); } - if (IS_HORUS(cstate.toType)) { + if (IS_FAMILY_HORUS_OR_T16(cstate.toType)) { // 6P switch is only on Horus (by default) if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) == 2) { strncpy(potName[2], potName[1], sizeof(potName[2])); diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 18dfc7379..3609713a5 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -36,7 +36,7 @@ inline int MAX_SWITCHES(Board::Type board, int version) if (version <= 218) { if (IS_TARANIS_X7(board)) return 6; - if (IS_TARANIS_X9D(board) || IS_HORUS(board)) + if (IS_TARANIS_X9D(board) || IS_FAMILY_HORUS_OR_T16(board)) return 8; if (IS_TARANIS_XLITE(board)) return 4; @@ -63,7 +63,7 @@ inline int MAX_SWITCHES_POSITION(Board::Type board, int version) inline int POTS_CONFIG_SIZE(Board::Type board, int version) { - if (version >= 219 && IS_HORUS(board)) + if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) return 16; return 8; @@ -71,44 +71,44 @@ inline int POTS_CONFIG_SIZE(Board::Type board, int version) inline int MAX_POTS(Board::Type board, int version) { - if (version <= 218 && IS_HORUS(board)) + if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) return 3; return Boards::getCapability(board, Board::Pots); } inline int MAX_POTS_STORAGE(Board::Type board, int version) { - if (version <= 218 && IS_HORUS(board)) + if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) return 3; - if (version >= 219 && IS_HORUS(board)) + if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) return 5; return Boards::getCapability(board, Board::Pots); } inline int MAX_POTS_SOURCES(Board::Type board, int version) { - if (version <= 218 && IS_HORUS(board)) + if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) return 5; return Boards::getCapability(board, Board::Pots); } inline int MAX_SLIDERS_STORAGE(Board::Type board, int version) { - if (version >= 219 && IS_HORUS(board)) + if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) return 4; return Boards::getCapability(board, Board::Sliders); } inline int MAX_SLIDERS_SOURCES(Board::Type board, int version) { - if (version <= 218 && IS_HORUS(board)) + if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) return 2; return Boards::getCapability(board, Board::Sliders); } inline int SLIDERS_CONFIG_SIZE(Board::Type board, int version) { - if (version >= 219 && IS_HORUS(board)) + if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) return 8; return 4; @@ -119,7 +119,7 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version) if (IS_TARANIS_X9E(board)) return 64; - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 32; if (version >= 219 && IS_TARANIS_X9D(board)) @@ -139,11 +139,11 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version) #define MAX_CUSTOM_FUNCTIONS(board, version) 64 #define MAX_CURVES(board, version) ((version >= 219 || HAS_LARGE_LCD(board)) ? 32 : 16) #define MAX_GVARS(board, version) 9 -#define MAX_SCRIPTS(board) (IS_HORUS(board) ? 9 : 7) -#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_HORUS(board) || IS_TARANIS_X9(board)) ? 60 : 40)) +#define MAX_SCRIPTS(board) (IS_FAMILY_HORUS_OR_T16(board) ? 9 : 7) +#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board)) ? 60 : 40)) #define NUM_PPM_INPUTS(board, version) 16 #define ROTENC_COUNT(board, version) ((IS_STM32(board) && version >= 218) ? 0 : 1) -#define MAX_AUX_TRIMS(board) (IS_HORUS(board) ? 2 : 0) +#define MAX_AUX_TRIMS(board) (IS_FAMILY_HORUS_OR_T16(board) ? 2 : 0) inline int switchIndex(int i, Board::Type board, unsigned int version) { @@ -810,7 +810,7 @@ class MixField: public TransformedField { internalField.Append(new UnsignedField<8>(this, mix.delayDown)); internalField.Append(new UnsignedField<8>(this, mix.speedUp)); internalField.Append(new UnsignedField<8>(this, mix.speedDown)); - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new ZCharField<6>(this, mix.name)); else if (HAS_LARGE_LCD(board) && version <= 218) internalField.Append(new ZCharField<8>(this, mix.name)); @@ -946,7 +946,7 @@ class InputField: public TransformedField { internalField.Append(new UnsignedField<9>(this, expo.flightModes)); internalField.Append(new SignedField<8>(this, _weight, "Weight")); internalField.Append(new SpareBitsField<1>(this)); - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new ZCharField<6>(this, expo.name)); else if (HAS_LARGE_LCD(board) && version <= 218) internalField.Append(new ZCharField<8>(this, expo.name)); @@ -1809,7 +1809,7 @@ class Frsky218Field: public StructField { rssiConversionTable[0] = RSSIConversionTable(0); rssiConversionTable[1] = RSSIConversionTable(1); - if (!IS_HORUS(board)) { + if (!IS_FAMILY_HORUS_OR_T16(board)) { Append(new UnsignedField<8>(this, frsky.voltsSource, "Volts Source")); Append(new UnsignedField<8>(this, frsky.altitudeSource, "Altitude Source")); @@ -2251,7 +2251,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig qDebug() << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant); - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new ZCharField<15>(this, modelData.name, "Model name")); else if (HAS_LARGE_LCD(board)) internalField.Append(new ZCharField<12>(this, modelData.name, "Model name")); @@ -2262,7 +2262,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig internalField.Append(new UnsignedField<8>(this, modelData.moduleData[1].modelId)); if (HAS_LARGE_LCD(board)) { - if (version >= 219 && IS_HORUS(board)) + if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new CharField<14>(this, modelData.bitmap, true, "Model bitmap")); else internalField.Append(new CharField<10>(this, modelData.bitmap, true, "Model bitmap")); @@ -2330,7 +2330,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig internalField.Append(new UnsignedField<8>(this, modelData.thrTraceSrc, "Throttle Source")); - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version)); else if (IS_TARANIS_X9E(board)) internalField.Append(new SwitchesWarningField<64>(this, modelData.switchWarningStates, board, version)); @@ -2345,7 +2345,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig internalField.Append(new UnsignedField<32>(this, modelData.switchWarningEnable)); else if (version >= 219 && IS_TARANIS_X9D(board)) internalField.Append(new UnsignedField<16>(this, modelData.switchWarningEnable)); - else if (!IS_HORUS(board)) + else if (!IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new UnsignedField<8>(this, modelData.switchWarningEnable)); for (int i=0; i(this, modelData.toplcdTimer)); } - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { for (int i = 0; i < 5; i++) { internalField.Append(new CharField<610>(this, modelData.customScreenData[i], false, "Custom screen blob")); } @@ -2508,7 +2508,7 @@ void OpenTxModelData::beforeExport() { // qDebug() << QString("before export model") << modelData.name; - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { uint32_t newSwitchWarningStates = 0; for (int i = 0; i < MAX_SWITCHES(board, version); i++) { uint8_t value = (modelData.switchWarningStates >> (2*i)) & 0x03; @@ -2524,7 +2524,7 @@ void OpenTxModelData::afterImport() { qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name; - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { uint32_t newSwitchWarningStates = 0; for (int i = 0; i < MAX_SWITCHES(board, version); i++) { uint8_t value = (modelData.switchWarningStates >> (3*i)) & 0x07; @@ -2572,7 +2572,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new UnsignedField<16>(this, chkSum)); - if (!IS_HORUS(board)) { + if (!IS_FAMILY_HORUS_OR_T16(board)) { internalField.Append(new UnsignedField<8>(this, generalData.currModelIndex)); internalField.Append(new UnsignedField<8>(this, generalData.contrast)); } @@ -2617,7 +2617,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new UnsignedField<8>(this, generalData.inactivityTimer)); internalField.Append(new UnsignedField<3>(this, generalData.telemetryBaudrate)); - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) internalField.Append(new SpareBitsField<3>(this)); else if (IS_TARANIS(board)) internalField.Append(new SignedField<3>(this, generalData.splashDuration)); @@ -2632,11 +2632,11 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new SignedField<8>(this, generalData.PPM_Multiplier)); internalField.Append(new SignedField<8>(this, generalData.hapticLength)); - if (version < 218 || (!IS_TARANIS(board) && !IS_HORUS(board))) { + if (version < 218 || (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board))) { internalField.Append(new UnsignedField<8>(this, generalData.reNavigation)); } - if (!IS_TARANIS(board) && !IS_HORUS(board)) { + if (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) { internalField.Append(new UnsignedField<8>(this, generalData.stickReverse)); } @@ -2715,7 +2715,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type if (IS_STM32(board)) { if (version >= 218) { internalField.Append(new UnsignedField<4>(this, generalData.auxSerialMode)); - if (IS_HORUS(board) && version >= 219) { + if (IS_FAMILY_HORUS_OR_T16(board) && version >= 219) { internalField.Append(new SpareBitsField<4>(this)); } else { @@ -2735,7 +2735,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type } } - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { for (int i=0; i(this, generalData.switchConfig[i])); @@ -2747,7 +2747,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type for (int i=0; i= 3)) + if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board) && (i >= 3)) offset += 2; if (i < MAX_POTS_STORAGE(board, version)) @@ -2756,7 +2756,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new SpareBitsField<2>(this)); } - if (IS_HORUS(board) && version >= 219) { + if (IS_FAMILY_HORUS_OR_T16(board) && version >= 219) { for (int i=0; i(this, generalData.sliderConfig[i])); @@ -2765,7 +2765,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type } } - if (!IS_HORUS(board)) { + if (!IS_FAMILY_HORUS_OR_T16(board)) { internalField.Append(new UnsignedField<8>(this, generalData.backlightColor)); } } @@ -2793,7 +2793,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type } } - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { for (int i=0; i(this, generalData.switchName[i], "Switch name")); } @@ -2832,7 +2832,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type } } - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { internalField.Append(new SpareBitsField<1>(this)); internalField.Append(new UnsignedField<7>(this, generalData.backlightOffBright)); internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); @@ -2842,7 +2842,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); } - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { internalField.Append(new CharField<8>(this, generalData.themeName, true, "Theme name")); for (int i=0; i<5; i++) { internalField.Append(new CharField<8>(this, (char *)generalData.themeOptionValue[i], true, "Theme blob")); diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 09aded8e2..d22964cb0 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -70,6 +70,8 @@ const char * OpenTxEepromInterface::getName() return "OpenTX for Jumper T12"; case BOARD_JUMPER_T16: return "OpenTX for Jumper T16"; + case BOARD_RADIOMASTER_TX16S: + return "OpenTX for Radiomaster TX16S"; case BOARD_TARANIS_X9D: return "OpenTX for FrSky Taranis X9D"; case BOARD_TARANIS_X9DP: @@ -175,7 +177,7 @@ bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data) { uint32_t fourcc = *((uint32_t*)&data.data()[0]); if (Boards::getFourCC(board) != fourcc) { - if (IS_HORUS(board) && fourcc == 0x3178396F) { + if (IS_FAMILY_HORUS_OR_T16(board) && fourcc == 0x3178396F) { qDebug() << QString().sprintf("%s: Deprecated fourcc used %x vs %x", getName(), fourcc, Boards::getFourCC(board)); } else { @@ -441,7 +443,7 @@ int OpenTxFirmware::getCapability(::Capability capability) { switch (capability) { case Models: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; else if (IS_ARM(board)) return 60; @@ -457,7 +459,7 @@ int OpenTxFirmware::getCapability(::Capability capability) else return id.contains("imperial") ? 1 : 0; case ModelImage: - return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 || IS_HORUS(board)); + return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 || IS_FAMILY_HORUS_OR_T16(board)); case HasBeeper: return (!IS_ARM(board)); case HasPxxCountry: @@ -495,7 +497,7 @@ int OpenTxFirmware::getCapability(::Capability capability) else return 0; case ModelName: - return (IS_HORUS(board) ? 15 : (HAS_LARGE_LCD(board) ? 12 : 10)); + return (IS_FAMILY_HORUS_OR_T16(board) ? 15 : (HAS_LARGE_LCD(board) ? 12 : 10)); case FlightModesName: return (IS_HORUS_OR_TARANIS(board) ? 10 : 6); case GvarsName: @@ -562,7 +564,7 @@ int OpenTxFirmware::getCapability(::Capability capability) case SoundPitch: return 1; case Haptic: - return (IS_2560(board) || IS_SKY9X(board) || IS_TARANIS_PLUS(board) || IS_TARANIS_SMALL(board) || IS_TARANIS_X9E(board) || IS_HORUS(board) || IS_JUMPER_T12(board) || id.contains("haptic")); + return (IS_2560(board) || IS_SKY9X(board) || IS_TARANIS_PLUS(board) || IS_TARANIS_SMALL(board) || IS_TARANIS_X9E(board) || IS_FAMILY_HORUS_OR_T16(board) || IS_JUMPER_T12(board) || id.contains("haptic")); case ModelTrainerEnable: if (IS_HORUS_OR_TARANIS(board) && board!=Board::BOARD_TARANIS_XLITE) return 1; @@ -610,7 +612,7 @@ int OpenTxFirmware::getCapability(::Capability capability) case TelemetryBars: return 1; case TelemetryCustomScreens: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; else return IS_ARM(board) ? 4 : 2; @@ -663,7 +665,7 @@ int OpenTxFirmware::getCapability(::Capability capability) case HasSDLogs: return ((IS_2560(board) || IS_ARM(board)) ? true : false); case LcdWidth: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 480; else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board)) return 128; @@ -672,12 +674,12 @@ int OpenTxFirmware::getCapability(::Capability capability) else return 128; case LcdHeight: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 272; else return 64; case LcdDepth: - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 16; else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board)) return 1; @@ -747,7 +749,7 @@ int OpenTxFirmware::getCapability(::Capability capability) case DangerousFunctions: return id.contains("danger") ? 1 : 0; case HasModelCategories: - return IS_HORUS(board); + return IS_FAMILY_HORUS_OR_T16(board); case HasSwitchableJack: return IS_TARANIS_XLITES(board); case PwrButtonPress: @@ -782,9 +784,9 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) return true; case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_LR12: - return !IS_ACCESS_RADIO(board, id) && board != BOARD_JUMPER_T16; + return !IS_ACCESS_RADIO(board, id) && !IS_FAMILY_T16(board); case PULSES_PXX_XJT_D8: - return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && board != BOARD_JUMPER_T16; + return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && !IS_FAMILY_T16(board); case PULSES_PPM: return id.contains("internalppm"); case PULSES_ACCESS_ISRM: @@ -814,7 +816,7 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_CROSSFIRE: return true; case PULSES_ACCESS_R9M: - return IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess")); + return IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_FAMILY_HORUS_OR_T16(board) && id.contains("internalaccess")); case PULSES_PXX_R9M_LITE: case PULSES_ACCESS_R9M_LITE: case PULSES_ACCESS_R9M_LITE_PRO: @@ -1343,6 +1345,12 @@ void registerOpenTxFirmwares() registerOpenTxFirmware(firmware); addOpenTxRfOptions(firmware, FLEX); + /* Radiomaster TX16S board */ + firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S"), BOARD_RADIOMASTER_TX16S); + addOpenTxFrskyOptions(firmware); + firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module")); + registerOpenTxFirmware(firmware); + /* 9XR-Pro */ firmware = new OpenTxFirmware("opentx-9xrpro", Firmware::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); addOpenTxArm9xOptions(firmware, false); diff --git a/companion/src/firmwares/radiodata.cpp b/companion/src/firmwares/radiodata.cpp index 0710910a0..8054e5b1a 100644 --- a/companion/src/firmwares/radiodata.cpp +++ b/companion/src/firmwares/radiodata.cpp @@ -116,7 +116,7 @@ void RadioData::convert(RadioDataConversionState & cstate) } } - if (IS_HORUS(cstate.toType)) { + if (IS_FAMILY_HORUS_OR_T16(cstate.toType)) { fixModelFilenames(); } diff --git a/companion/src/firmwares/rawsource.cpp b/companion/src/firmwares/rawsource.cpp index 47171c29f..401eb9781 100644 --- a/companion/src/firmwares/rawsource.cpp +++ b/companion/src/firmwares/rawsource.cpp @@ -580,13 +580,13 @@ RawSource RawSource::convert(RadioDataConversionState & cstate) } } - if (IS_TARANIS(cstate.toType) && IS_HORUS(cstate.fromType)) { + if (IS_TARANIS(cstate.toType) && IS_FAMILY_HORUS_OR_T16(cstate.fromType)) { if (index == 6) index = 5; // pot S2 to S2 else if (index == 5) index = -1; // 6P on Horus doesn't exist on Taranis } - else if (IS_HORUS(cstate.toType) && IS_TARANIS(cstate.fromType) && index == 5) + else if (IS_FAMILY_HORUS_OR_T16(cstate.toType) && IS_TARANIS(cstate.fromType) && index == 5) { index = 6; // pot S2 to S2 } @@ -602,7 +602,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate) } } - if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) { + if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) { // No SE and SG on X7 board if (index == 4 || index == 6) { index = 3; // SG and SE to SD @@ -615,7 +615,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate) index = 5; // SH to SH } } - else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) { + else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) { // No SE and SG on T12 board if (index == 4 || index == 6) { index = 3; // SG and SE to SD @@ -629,7 +629,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate) } } // Compensate for SE and SG on X9/Horus board if converting from X7 - else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) { + else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) { if (index == 4) { index = 5; // SF to SF } @@ -637,7 +637,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate) index = 7; // SH to SH } } - else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) { + else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) { if (index == 4) { index = 5; // SF to SF } @@ -645,7 +645,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate) index = 7; // SH to SH } } - else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) { + else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) { if (index == 4) { index = 5; // SF to SF } diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index 1d91f242a..a689ceea7 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -197,7 +197,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate) } // No SE and SG on X7 board - if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) { + if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) { if (srcIdx == 4 || srcIdx == 5) { delta = 3; // SE to SD & SF to SF if (srcIdx == 4) @@ -211,7 +211,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate) delta = 6; // SH to SH } } - else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) { + else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) { if (srcIdx == 4 || srcIdx == 5) { delta = 3; // SE to SD & SF to SF if (srcIdx == 4) @@ -226,7 +226,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate) } } // Compensate for SE and SG on X9/Horus board if converting from X7 - else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) { + else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) { if (srcIdx == 4) { delta = -3; // SF to SF } @@ -234,7 +234,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate) delta = -6; // SH to SH } } - else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) { + else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) { if (srcIdx == 4) { delta = -3; // SF to SF } diff --git a/companion/src/generaledit/generalsetup.cpp b/companion/src/generaledit/generalsetup.cpp index 38db4d31a..1f74e2734 100644 --- a/companion/src/generaledit/generalsetup.cpp +++ b/companion/src/generaledit/generalsetup.cpp @@ -191,7 +191,7 @@ ui(new Ui::GeneralSetup) ui->label_BLBright->hide(); } - if (!IS_HORUS(firmware->getBoard())) { + if (!IS_FAMILY_HORUS_OR_T16(firmware->getBoard())) { ui->OFFBright_SB->hide(); ui->OFFBright_SB->setDisabled(true); ui->label_OFFBright->hide(); @@ -241,7 +241,7 @@ ui(new Ui::GeneralSetup) ui->rssiPowerOffWarnChkB->hide(); } - if (IS_HORUS(firmware->getBoard())) { + if (IS_FAMILY_HORUS_OR_T16(firmware->getBoard())) { ui->splashScreenChkB->hide(); ui->splashScreenDuration->hide(); ui->splashScreenLabel->hide(); diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 737882d78..4f530aa78 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -172,7 +172,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings ui->txCurrentCalibrationLabel->hide(); } - if (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) || IS_HORUS(board)) { + if (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) || IS_FAMILY_HORUS_OR_T16(board)) { ui->bluetoothMode->addItem(tr("OFF"), 0); if (IS_TARANIS_X9E(board)) { ui->bluetoothMode->addItem(tr("Enabled"), 1); @@ -189,7 +189,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings ui->bluetoothWidget->hide(); } - if ((IS_HORUS(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board))) { + if ((IS_FAMILY_HORUS_OR_T16(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board))) { ui->antennaMode->addItem(tr("Internal"), -2); ui->antennaMode->addItem(tr("Ask"), -1); ui->antennaMode->addItem(tr("Per model"), 0); diff --git a/companion/src/images/simulator/TX16S/bottom.png b/companion/src/images/simulator/TX16S/bottom.png new file mode 100755 index 0000000000000000000000000000000000000000..8f0d29f7e4c93a2b813c766f31b5ce2b2cda5d22 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0y~yV0-{%b8)Z%$()+rqdmmtT}V`<;yxP*J(3 zi(^Q|oVRy2@*Xzeadq@spuqfU&;LbjTuV=IIY#`*Yr1c{A@TLz`3wyIR)zC3G?)t| zFlZdIVLcB{>DqNWabOM8?tDnm{r-UW|2^CXQ literal 0 HcmV?d00001 diff --git a/companion/src/images/simulator/TX16S/left.png b/companion/src/images/simulator/TX16S/left.png new file mode 100755 index 0000000000000000000000000000000000000000..ded33bf620b35487e831e385d89cb629313a76a5 GIT binary patch literal 48315 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 literal 0 HcmV?d00001 diff --git a/companion/src/images/simulator/TX16S/left_page2.png b/companion/src/images/simulator/TX16S/left_page2.png new file mode 100755 index 0000000000000000000000000000000000000000..c104c148bd8b16d10ae4c01e7456aa213b765b33 GIT binary patch literal 48292 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 literal 0 HcmV?d00001 diff --git a/companion/src/images/simulator/TX16S/left_rtn.png b/companion/src/images/simulator/TX16S/left_rtn.png new file mode 100755 index 0000000000000000000000000000000000000000..0080f271a83f5fae7adf709b2721c7553d8c4547 GIT binary patch literal 48242 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 literal 0 HcmV?d00001 diff --git a/companion/src/images/simulator/TX16S/left_sys.png b/companion/src/images/simulator/TX16S/left_sys.png new file mode 100755 index 0000000000000000000000000000000000000000..31eeb409fd780032e2ec4765031d2d6315583945 GIT binary patch literal 48264 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 apS*tlHG+{ZEEO#Idm;-{f|f}b`2G*DSpew( literal 0 HcmV?d00001 diff --git a/companion/src/images/simulator/TX16S/right.png b/companion/src/images/simulator/TX16S/right.png new file mode 100755 index 0000000000000000000000000000000000000000..f07ca05bf283c6286030052feeeb4bd5be2dbce5 GIT binary patch literal 40325 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 Y=?msl3*Q<6rtu{$HGS20%2vVu2l;Yq8~^|S literal 0 HcmV?d00001 diff --git a/companion/src/images/simulator/TX16S/top.png b/companion/src/images/simulator/TX16S/top.png new file mode 100755 index 0000000000000000000000000000000000000000..3bc1784ee2860dd9ffa705850dad1f93983f6aa6 GIT binary patch literal 439 zcmV;o0Z9IdP)B#)F`Hw}IF6?V%{>&{k39kQfE~Hmm5|HPEyeXQZQJ&AA|-?e;5vE) zN_X@X^yUh9nx-H{Jps)H0C2?RN3{(nmGbbJ13-LD>;e#8Zhw0MfLyrT1Fn1*0{{TF hH~|9y5WxEO-yc}D#MSsetEnabled(activeChild); writeEepromAct->setEnabled(activeChild); readEepromAct->setEnabled(true); - if (IS_HORUS(getCurrentBoard())) { + if (IS_FAMILY_HORUS_OR_T16(getCurrentBoard())) { writeBUToRadioAct->setEnabled(false); readBUToFileAct->setEnabled(false); } @@ -1086,7 +1086,7 @@ void MainWindow::updateMenus() writeBUToRadioAct->setEnabled(true); readBUToFileAct->setEnabled(true); } - editSplashAct->setDisabled(IS_HORUS(getCurrentBoard())); + editSplashAct->setDisabled(IS_FAMILY_HORUS_OR_T16(getCurrentBoard())); foreach (QAction * act, fileWindowActions) { if (!act) diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index c31697a9f..3c8c7c214 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -534,7 +534,7 @@ void MdiChild::initModelsList() connect(modelsListModel, &QAbstractItemModel::dataChanged, this, &MdiChild::onDataChanged); ui->modelsList->setModel(modelsListModel); - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { ui->modelsList->setIndentation(20); // ui->modelsList->resetIndentation(); // introduced in next Qt versions ... } @@ -1531,7 +1531,7 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt void MdiChild::writeEeprom() // write to Tx { Board::Type board = getCurrentBoard(); - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { QString radioPath = findMassstoragePath("RADIO", true); qDebug() << "Searching for SD card, found" << radioPath; if (radioPath.isEmpty()) { diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 77988a2e7..5e193faec 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -209,7 +209,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ui->trainerMode->setItemData(TRAINER_MODE_SLAVE_BLUETOOTH, 0, Qt::UserRole - 1); } - if (!IS_JUMPER_T16(firmware->getBoard())) { + if (!IS_FAMILY_T16(firmware->getBoard())) { ui->trainerMode->setItemData(TRAINER_MODE_MULTI, 0, Qt::UserRole - 1); } @@ -1001,7 +1001,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge QDir qd(path); if (qd.exists()) { QStringList filters; - if(IS_HORUS(board)) { + if(IS_FAMILY_HORUS_OR_T16(board)) { filters << "*.bmp" << "*.jpg" << "*.png"; foreach ( QString file, qd.entryList(filters, QDir::Files) ) { QFileInfo fi(file); @@ -1032,17 +1032,17 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge ui->image->setCurrentIndex(ui->image->count()-1); QString fileName = path; fileName.append(model.bitmap); - if (!IS_HORUS(board)) + if (!IS_FAMILY_HORUS_OR_T16(board)) fileName.append(".bmp"); QImage image(fileName); - if (image.isNull() && !IS_HORUS(board)) { + if (image.isNull() && !IS_FAMILY_HORUS_OR_T16(board)) { fileName = path; fileName.append(model.bitmap); fileName.append(".BMP"); image.load(fileName); } if (!image.isNull()) { - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { ui->imagePreview->setFixedSize(QSize(192, 114)); ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(192, 114))); } @@ -1281,17 +1281,17 @@ void SetupPanel::on_image_currentIndexChanged(int index) if (qd.exists()) { QString fileName=path; fileName.append(model->bitmap); - if (!IS_HORUS(board)) + if (!IS_FAMILY_HORUS_OR_T16(board)) fileName.append(".bmp"); QImage image(fileName); - if (image.isNull() && !IS_HORUS(board)) { + if (image.isNull() && !IS_FAMILY_HORUS_OR_T16(board)) { fileName=path; fileName.append(model->bitmap); fileName.append(".BMP"); image.load(fileName); } if (!image.isNull()) { - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { ui->imagePreview->setFixedSize(QSize(192, 114)); ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(192, 114))); } diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index 2fb5cc329..864c10028 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -145,7 +145,7 @@ TreeModel::TreeModel(RadioData * radioData, QObject * parent): if (!hasCategories) labels << tr("Index"); labels << tr("Name"); - if (!(IS_HORUS(board) || IS_SKY9X(board))) { + if (!(IS_FAMILY_HORUS_OR_T16(board) || IS_SKY9X(board))) { labels << tr("Size"); } labels << tr("RX #"); @@ -651,7 +651,7 @@ void TreeModel::refresh() EEPROMInterface * eepromInterface = getCurrentEEpromInterface(); Board::Type board = eepromInterface->getBoard(); TreeItem * defaultCategoryItem = NULL; - bool hasEepromSizeData = (IS_HORUS(board) ? false : true); + bool hasEepromSizeData = (IS_FAMILY_HORUS_OR_T16(board) ? false : true); if (hasEepromSizeData) { availableEEpromSize = Boards::getEEpromSize(board) - 64; // let's consider fat diff --git a/companion/src/radiointerface.cpp b/companion/src/radiointerface.cpp index 6c2c50052..c3214958a 100644 --- a/companion/src/radiointerface.cpp +++ b/companion/src/radiointerface.cpp @@ -314,7 +314,7 @@ bool readEeprom(const QString & filename, ProgressWidget * progress) return false; } - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { QString radioPath = findMassstoragePath("RADIO", true); qDebug() << "Searching for SD card, found" << radioPath; if (radioPath.isEmpty()) { diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index 7601f8f04..8acadd92a 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -14,6 +14,7 @@ set(simulation_SRCS simulateduiwidgetX12.cpp simulateduiwidgetJumperT12.cpp simulateduiwidgetJumperT16.cpp + simulateduiwidgetTX16S.cpp simulatorinterface.cpp simulatormainwindow.cpp simulatorstartupdialog.cpp @@ -38,6 +39,7 @@ set(simulation_UIS simulateduiwidgetX12.ui simulateduiwidgetJumperT12.ui simulateduiwidgetJumperT16.ui + simulateduiwidgetTX16S.ui simulatormainwindow.ui simulatorstartupdialog.ui simulatorwidget.ui diff --git a/companion/src/simulation/simulateduiwidget.h b/companion/src/simulation/simulateduiwidget.h index d688c641a..75dd3ebfd 100644 --- a/companion/src/simulation/simulateduiwidget.h +++ b/companion/src/simulation/simulateduiwidget.h @@ -113,6 +113,7 @@ namespace Ui { class SimulatedUIWidgetX12; class SimulatedUIWidgetJumperT12; class SimulatedUIWidgetJumperT16; + class SimulatedUIWidgetTX16S; } class SimulatedUIWidget9X: public SimulatedUIWidget @@ -251,5 +252,17 @@ class SimulatedUIWidgetJumperT16: public SimulatedUIWidget Ui::SimulatedUIWidgetJumperT16 * ui; }; +class SimulatedUIWidgetTX16S: public SimulatedUIWidget +{ + Q_OBJECT + + public: + explicit SimulatedUIWidgetTX16S(SimulatorInterface * simulator, QWidget * parent = nullptr); + virtual ~SimulatedUIWidgetTX16S(); + + private: + Ui::SimulatedUIWidgetTX16S * ui; +}; + #endif // SIMULATEDUIWIDGET_H diff --git a/companion/src/simulation/simulateduiwidgetTX16S.cpp b/companion/src/simulation/simulateduiwidgetTX16S.cpp new file mode 100644 index 000000000..db1d5fa8b --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetTX16S.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h + +#include "simulateduiwidget.h" +#include "ui_simulateduiwidgetTX16S.h" + +SimulatedUIWidgetTX16S::SimulatedUIWidgetTX16S(SimulatorInterface *simulator, QWidget * parent): + SimulatedUIWidget(simulator, parent), + ui(new Ui::SimulatedUIWidgetTX16S) +{ + RadioUiAction * act; + + ui->setupUi(this); + + // add actions in order of appearance on the help menu + + act = new RadioUiAction(3, QList() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL); + addRadioWidget(ui->rightbuttons->addArea(QRect(10, 0, 80, 35), "TX16S/right_mdl.png", act)); + + m_mouseMidClickAction = new RadioUiAction(2, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN); + addRadioWidget(ui->rightbuttons->addArea(QRect(45, 70, 100, 160), "TX16S/right_ent.png", m_mouseMidClickAction)); + + act = new RadioUiAction(6, QList() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS); + addRadioWidget(ui->leftbuttons->addArea(QRect(32, 1, 80, 35), "TX16S/left_sys.png", act)); + + act = new RadioUiAction(5, QList() << Qt::Key_Right, SIMU_STR_HLP_KEY_RGT, SIMU_STR_HLP_ACT_TELE); + addRadioWidget(ui->leftbuttons->addArea(QRect(55, 220, 80, 35), "TX16S/left_tele.png", act)); + + act = new RadioUiAction(1, QList() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN); + addRadioWidget(ui->leftbuttons->addArea(QRect(55, 115, 80, 35), "TX16S/left_page.png", act)); + + act = new RadioUiAction(0, QList() << Qt::Key_PageUp, SIMU_STR_HLP_KEY_PGUP, SIMU_STR_HLP_ACT_PGUP); + addRadioWidget(ui->leftbuttons->addArea(QRect(55, 160, 80, 35), "TX16S/left_page2.png", act)); + + act = new RadioUiAction(4, QList() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, + SIMU_STR_HLP_KEY_DN % "
" % SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_RTN); + addRadioWidget(ui->leftbuttons->addArea(QRect(55, 55, 80, 35), "TX16S/left_rtn.png", act)); + + m_scrollUpAction = new RadioUiAction(-1, QList() << Qt::Key_Minus, SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_ROT_LFT); + m_scrollDnAction = new RadioUiAction(-1, QList() << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_ROT_RGT); + connectScrollActions(); + + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 252, 30, 30), "TX16S/left_scrnsht.png", m_screenshotAction)); + + m_backlightColors << QColor(47, 123, 227); + + setLcd(ui->lcd); +} + +SimulatedUIWidgetTX16S::~SimulatedUIWidgetTX16S() +{ + delete ui; +} diff --git a/companion/src/simulation/simulateduiwidgetTX16S.ui b/companion/src/simulation/simulateduiwidgetTX16S.ui new file mode 100644 index 000000000..e5137d992 --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetTX16S.ui @@ -0,0 +1,197 @@ + + + SimulatedUIWidgetTX16S + + + + 0 + 0 + 825 + 292 + + + + + 0 + 0 + + + + + 825 + 292 + + + + + 825 + 292 + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 174 + 292 + + + + + 174 + 292 + + + + background:url(:/images/simulator/TX16S/right.png) + + + + + + + + 0 + 0 + + + + + 480 + 272 + + + + + 480 + 272 + + + + + 5 + + + + + + + + + 0 + 0 + + + + + 174 + 292 + + + + + 174 + 292 + + + + true + + + background:url(:/images/simulator/TX16S/left.png); + + + + + + + + 0 + 0 + + + + + 480 + 10 + + + + + 480 + 10 + + + + + 5 + + + + background:url(:/images/simulator/TX16S/top.png) + + + + + + + + 0 + 0 + + + + + 480 + 10 + + + + + 480 + 10 + + + + + 5 + false + + + + background:url(:/images/simulator/TX16S/bottom.png) + + + + + + + + LcdWidget + QWidget +

lcdwidget.h
+ 1 + + + ButtonsWidget + QWidget +
buttonswidget.h
+ 1 +
+ + + + diff --git a/companion/src/simulation/simulatorstartupdialog.cpp b/companion/src/simulation/simulatorstartupdialog.cpp index 57272bf99..32d343321 100644 --- a/companion/src/simulation/simulatorstartupdialog.cpp +++ b/companion/src/simulation/simulatorstartupdialog.cpp @@ -86,7 +86,7 @@ void SimulatorStartupDialog::changeEvent(QEvent *e) // FIXME : need a better way to check for this bool SimulatorStartupDialog::usesCategorizedStorage(const QString & name) { - return name.contains(QRegExp("(x12|x10|horus|t16)", Qt::CaseInsensitive)); + return name.contains(QRegExp("(x12|x10|horus|16)", Qt::CaseInsensitive)); } bool SimulatorStartupDialog::usesCategorizedStorage() diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index 2a472fc00..798c8664b 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -94,6 +94,9 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato case Board::BOARD_JUMPER_T16: radioUiWidget = new SimulatedUIWidgetJumperT16(simulator, this); break; + case Board::BOARD_RADIOMASTER_TX16S: + radioUiWidget = new SimulatedUIWidgetTX16S(simulator, this); + break; default: radioUiWidget = new SimulatedUIWidget9X(simulator, this); break; @@ -270,7 +273,7 @@ bool SimulatorWidget::setRadioData(RadioData * radioData) saveTempRadioData = (flags & SIMULATOR_FLAGS_STANDALONE); - if (IS_HORUS(m_board)) + if (IS_FAMILY_HORUS_OR_T16(m_board)) ret = useTempDataPath(true); if (ret) { diff --git a/companion/src/storage/categorized.cpp b/companion/src/storage/categorized.cpp index 9ca248cc4..d659ae81f 100644 --- a/companion/src/storage/categorized.cpp +++ b/companion/src/storage/categorized.cpp @@ -93,7 +93,7 @@ bool CategorizedStorageFormat::load(RadioData & radioData) return false; } strncpy(radioData.models[modelIndex].filename, qPrintable(fileName), sizeof(radioData.models[modelIndex].filename)); - if (IS_HORUS(board) && !strcmp(radioData.generalSettings.currModelFilename, qPrintable(fileName))) { + if (IS_FAMILY_HORUS_OR_T16(board) && !strcmp(radioData.generalSettings.currModelFilename, qPrintable(fileName))) { radioData.generalSettings.currModelIndex = modelIndex; qDebug() << "currModelIndex =" << modelIndex; } diff --git a/companion/src/storage/rlefile.cpp b/companion/src/storage/rlefile.cpp index b4d9da611..fe297339f 100644 --- a/companion/src/storage/rlefile.cpp +++ b/companion/src/storage/rlefile.cpp @@ -239,7 +239,7 @@ void RleFile::EeFsSetDat(unsigned int blk, unsigned int ofs, const uint8_t *buf, unsigned int RleFile::EeFsGetFree() { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; unsigned int ret = 0; @@ -261,7 +261,7 @@ unsigned int RleFile::EeFsGetFree() */ void RleFile::EeFsFree(unsigned int blk) { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return; unsigned int i = blk; @@ -281,7 +281,7 @@ void RleFile::EeFsFree(unsigned int blk) */ unsigned int RleFile::EeFsAlloc() { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; unsigned int ret = (IS_ARM(board) ? eeFsArm->freeList : eeFs->freeList); if (ret) { @@ -296,7 +296,7 @@ unsigned int RleFile::EeFsAlloc() unsigned int RleFile::size(unsigned int id) { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; else return IS_ARM(board) ? eeFsArm->files[id].size : eeFs->files[id].size; @@ -304,7 +304,7 @@ unsigned int RleFile::size(unsigned int id) unsigned int RleFile::openRd(unsigned int i_fileId) { - if (IS_HORUS(board)) { + if (IS_FAMILY_HORUS_OR_T16(board)) { return 1; } else if (IS_SKY9X(board)) { @@ -341,7 +341,7 @@ unsigned int RleFile::openRd(unsigned int i_fileId) unsigned int RleFile::read(uint8_t *buf, unsigned int i_len) { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; unsigned int len = IS_ARM(board) ? eeFsArm->files[m_fileId].size : eeFs->files[m_fileId].size; @@ -364,7 +364,7 @@ unsigned int RleFile::read(uint8_t *buf, unsigned int i_len) // G: Read runlength (RLE) compressed bytes into buf. unsigned int RleFile::readRlc12(uint8_t *buf, unsigned int i_len, bool rlc2) { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; memset(buf, 0, i_len); @@ -550,7 +550,7 @@ void RleFile::closeTrunc() unsigned int RleFile::writeRlc1(unsigned int i_fileId, unsigned int typ, const uint8_t *buf, unsigned int i_len) { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; create(i_fileId, typ); @@ -599,7 +599,7 @@ unsigned int RleFile::writeRlc1(unsigned int i_fileId, unsigned int typ, const u */ unsigned int RleFile::writeRlc2(unsigned int i_fileId, unsigned int typ, const uint8_t *buf, unsigned int i_len) { - if (IS_HORUS(board)) + if (IS_FAMILY_HORUS_OR_T16(board)) return 0; if (IS_SKY9X(board)) { diff --git a/radio/sdcard/horus/THEMES/Darkblue/tx16s.bmp b/radio/sdcard/horus/THEMES/Darkblue/tx16s.bmp new file mode 100755 index 0000000000000000000000000000000000000000..826fc35f000e449e374a24b2da04667d9f050c34 GIT binary patch literal 164938 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
t$PFt_L7PF{J~-m$q~Ys)?TjXt!XkKCXw{hobL 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 literal 0 HcmV?d00001 diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index c8e5b3ca0..836e60e88 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -191,6 +191,8 @@ enum TrainerMode { #if defined(PCBTARANIS) TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, +#endif +#if defined(PCBTARANIS) || defined(AUX_SERIAL) TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, #endif TRAINER_MODE_MASTER_BLUETOOTH, @@ -205,7 +207,7 @@ enum TrainerMode { }; #endif -#if defined(RADIO_T16) || defined(ALLOW_TRAINER_MULTI) +#if defined(RADIO_FAMILY_T16) || defined(ALLOW_TRAINER_MULTI) #define TRAINER_MODE_MAX() TRAINER_MODE_MULTI #elif defined(BLUETOOTH) #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE_BLUETOOTH diff --git a/radio/src/gui/480x272/bitmaps.cpp b/radio/src/gui/480x272/bitmaps.cpp index f7b87a4d3..08cc8f59a 100644 --- a/radio/src/gui/480x272/bitmaps.cpp +++ b/radio/src/gui/480x272/bitmaps.cpp @@ -64,6 +64,10 @@ const uint8_t LBM_TOPMENU_TXBATT[] = { #include "mask_txbat.lbm" }; +const uint8_t LBM_TOPMENU_TXBATT_CHARGING[] = { +#include "mask_txbat_charging.lbm" +}; + const uint8_t LBM_TOPMENU_ANTENNA[] = { #include "mask_antenna.lbm" }; diff --git a/radio/src/gui/480x272/bitmaps.h b/radio/src/gui/480x272/bitmaps.h index fcefcbd49..b51c04551 100644 --- a/radio/src/gui/480x272/bitmaps.h +++ b/radio/src/gui/480x272/bitmaps.h @@ -34,6 +34,7 @@ extern const uint8_t LBM_TOPMENU_VOLUME_3[]; extern const uint8_t LBM_TOPMENU_VOLUME_4[]; extern const uint8_t LBM_TOPMENU_VOLUME_SCALE[]; extern const uint8_t LBM_TOPMENU_TXBATT[]; +extern const uint8_t LBM_TOPMENU_TXBATT_CHARGING[]; extern const uint8_t LBM_HTRIM_FRAME[]; extern const uint8_t LBM_VTRIM_FRAME[]; extern const uint8_t LBM_TRIM_SHADOW[]; diff --git a/radio/src/gui/480x272/radio_hardware.cpp b/radio/src/gui/480x272/radio_hardware.cpp index bf6c333f6..96f29cfbb 100644 --- a/radio/src/gui/480x272/radio_hardware.cpp +++ b/radio/src/gui/480x272/radio_hardware.cpp @@ -347,6 +347,9 @@ bool menuRadioHardware(event_t event) #if defined(AUX_SERIAL) case ITEM_RADIO_HARDWARE_AUX_SERIAL_MODE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_AUX_SERIAL_MODE); +#if defined(RADIO_TX16S) + lcdDrawText(lcdNextPos, y, " (TTL)"); +#endif g_eeGeneral.auxSerialMode = editChoice(HW_SETTINGS_COLUMN+50, y, STR_AUX_SERIAL_MODES, g_eeGeneral.auxSerialMode, 0, UART_MODE_MAX, attr, event); if (attr && checkIncDec_Ret) { auxSerialInit(g_eeGeneral.auxSerialMode, modelTelemetryProtocol()); diff --git a/radio/src/gui/480x272/themes/darkblue.cpp b/radio/src/gui/480x272/themes/darkblue.cpp index 3d5e056fb..0b8e21306 100644 --- a/radio/src/gui/480x272/themes/darkblue.cpp +++ b/radio/src/gui/480x272/themes/darkblue.cpp @@ -139,6 +139,8 @@ class DarkblueTheme: public Theme delete calibHorus; #if defined(RADIO_T16) calibHorus = BitmapBuffer::load(getThemePath("t16.bmp")); +#elif defined(RADIO_TX16S) + calibHorus = BitmapBuffer::load(getThemePath("tx16s.bmp")); #elif defined(PCBX10) if(STICKS_PWM_ENABLED()) { calibHorus = BitmapBuffer::load(getThemePath("X10S.bmp")); diff --git a/radio/src/gui/480x272/themes/default.cpp b/radio/src/gui/480x272/themes/default.cpp index 2ce0999af..5ecd5bfbd 100644 --- a/radio/src/gui/480x272/themes/default.cpp +++ b/radio/src/gui/480x272/themes/default.cpp @@ -176,6 +176,8 @@ class DefaultTheme: public Theme delete calibHorus; #if defined(RADIO_T16) calibHorus = BitmapBuffer::load(getThemePath("t16.bmp")); +#elif defined(RADIO_TX16S) + calibHorus = BitmapBuffer::load(getThemePath("tx16s.bmp")); #elif defined(PCBX10) if(STICKS_PWM_ENABLED()) { calibHorus = BitmapBuffer::load(getThemePath("X10S.bmp")); diff --git a/radio/src/gui/480x272/topbar.cpp b/radio/src/gui/480x272/topbar.cpp index 45707f542..487e70a9b 100644 --- a/radio/src/gui/480x272/topbar.cpp +++ b/radio/src/gui/480x272/topbar.cpp @@ -90,7 +90,12 @@ void drawTopBar() /* Tx battery */ uint8_t bars = GET_TXBATT_BARS(5); - lcdDrawBitmapPattern(LCD_W-130, 24, LBM_TOPMENU_TXBATT, MENU_TITLE_COLOR); +#if defined(USB_CHARGER) + if(usbChargerLed()) + lcdDrawBitmapPattern(LCD_W-130, 24, LBM_TOPMENU_TXBATT_CHARGING, MENU_TITLE_COLOR); + else +#endif + lcdDrawBitmapPattern(LCD_W-130, 24, LBM_TOPMENU_TXBATT, MENU_TITLE_COLOR); for (unsigned int i = 0; i < 5; i++) { lcdDrawSolidFilledRect(LCD_W-122+4*i, 30, 2, 8, i >= bars ? MENU_TITLE_DISABLE_COLOR : MENU_TITLE_COLOR); } diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 0bdf7ba47..28b072f95 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -28,7 +28,7 @@ #if defined(PCBX12S) #include "lua/lua_exports_x12s.inc" // this line must be after lua headers -#elif defined(RADIO_T16) +#elif defined(RADIO_FAMILY_T16) #include "lua/lua_exports_t16.inc" #elif defined(PCBX10) #include "lua/lua_exports_x10.inc" diff --git a/radio/src/opentx.h b/radio/src/opentx.h index d89609d1f..0ef8b04c9 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -546,7 +546,7 @@ bool setTrimValue(uint8_t phase, uint8_t idx, int trim); #if defined(PCBSKY9X) #define ROTARY_ENCODER_GRANULARITY (2 << g_eeGeneral.rotarySteps) -#elif defined(RADIO_T16) +#elif defined(RADIO_FAMILY_T16) #define ROTARY_ENCODER_GRANULARITY (1) #else #define ROTARY_ENCODER_GRANULARITY (2) diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 98dff0e03..645e527d3 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -128,6 +128,8 @@ const char * getBasename(const char * path); #define OTX_FOURCC 0x3478746F // otx for X12S #elif defined(RADIO_T16) #define OTX_FOURCC 0x3F78746F // otx for Jumper T16 +#elif defined(RADIO_TX16S) + #define OTX_FOURCC 0x3878746F // otx for Radiomaster TX16S #elif defined(PCBX10) #define OTX_FOURCC 0x3778746F // otx for X10 #elif defined(PCBX9E) diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index 2a690972b..b4c72e46c 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -24,6 +24,8 @@ // not needed #elif defined(RADIO_T16) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,1, -1,1, -1,1}; +#elif defined(RADIO_TX16S) + const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, 1,1,1, -1,1, -1,1}; #elif defined(PCBX10) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,1, 1, -1}; #elif defined(PCBX9E) diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 9499e24f9..38d7006d7 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "targets/horus/board.h" #if defined(AUX_SERIAL) uint8_t auxSerialMode = 0; @@ -40,6 +41,13 @@ void auxSerialSetup(unsigned int baudrate, bool dma) GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(AUX_SERIAL_GPIO, &GPIO_InitStructure); +#if defined(AUX_SERIAL_PWR_GPIO) + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = AUX_SERIAL_PWR_GPIO_PIN; + GPIO_Init(AUX_SERIAL_PWR_GPIO, &GPIO_InitStructure); +#endif + USART_InitStructure.USART_BaudRate = baudrate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; @@ -133,6 +141,7 @@ void auxSerialSbusInit() { auxSerialSetup(SBUS_BAUDRATE, true); AUX_SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ; + AUX_SERIAL_POWER_ON(); } void auxSerialStop() diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index 86f4594f9..b94180761 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -116,11 +116,20 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S) ../../../../../syscalls.c ) +if(USB_CHARGER) + set(BOOTLOADER_SRC + ${BOOTLOADER_SRC} + ../../../../../targets/${TARGET_DIR}/usb_charger_driver.cpp + ../../../../../targets/${TARGET_DIR}/led_driver.cpp + ) + endif() + if(DEBUG) set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c ../../../../../serial.cpp + ../../../../../targets/common/arm/stm32/aux_serial_driver.cpp ) endif() else() diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 106734a2f..b0079b49e 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -205,11 +205,26 @@ int main() AUX_SERIAL_RCC_APB1Periph | SD_RCC_APB1Periph, ENABLE); - RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph | RCC_APB2Periph_SYSCFG, ENABLE); + RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph | RCC_APB2Periph_SYSCFG | AUX_SERIAL_RCC_APB2Periph, ENABLE); pwrInit(); keysInit(); + // USB charger handling +#if defined(USB_CHARGER) + if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() && !pwrPressed()) { + ledInit(); + usbChargerInit(); + ledOff(); + while (!pwrPressed()) { + if(usbChargerLed()) + GPIO_SetBits(LED_GPIO, LED_GREEN_GPIO_PIN); + else + ledOff(); + } + } +#endif + // wait a bit for the inputs to stabilize... if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { for (uint32_t i = 0; i < 150000; i++) { diff --git a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp index f43090f04..436cb0bd7 100644 --- a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp @@ -71,7 +71,7 @@ void rotaryEncoderInit() void rotaryEncoderCheck() { -#if defined(RADIO_T16) +#if defined(RADIO_FAMILY_T16) static uint8_t state = 0; uint8_t pins = ROTARY_ENCODER_POSITION(); diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index a1ac28f08..601d82dfb 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -51,8 +51,20 @@ if (PCB STREQUAL X10) set(FLAVOUR t16) set(LUA_EXPORT lua_export_t16) add_definitions(-DRADIO_T16) + add_definitions(-DRADIO_FAMILY_T16) option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" OFF) option(BLUETOOTH "Support for bluetooth module" OFF) + elseif (PCBREV STREQUAL TX16S) + set(FLAVOUR tx16s) + set(LUA_EXPORT lua_export_t16) + add_definitions(-DRADIO_TX16S) + add_definitions(-DRADIO_FAMILY_T16) + option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" ON) + option(BLUETOOTH "Support for bluetooth module" OFF) + if (NOT BLUETOOTH) + set(AUX_SERIAL ON) + endif() + set(USB_CHARGER YES) else() set(FLAVOUR x10) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) @@ -195,15 +207,26 @@ set(TARGET_SRC ../common/arm/stm32/rotary_encoder_driver.cpp ) +if(USB_CHARGER) + set(TARGET_SRC ${TARGET_SRC} usb_charger_driver.cpp) + add_definitions(-DUSB_CHARGER) +endif() + if(BLUETOOTH) add_definitions(-DBLUETOOTH) set(TARGET_SRC ${TARGET_SRC} ../common/arm/stm32/bluetooth_driver.cpp) set(SRC ${SRC} bluetooth.cpp) endif() +if (AUX_SERIAL) + add_definitions(-DAUX_SERIAL) + set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) +endif() + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} ${LCD_DRIVER} + ${AUX_SERIAL_DRIVER} board.cpp backlight_driver.cpp ../common/arm/stm32/pwr_driver.cpp diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index ac6e4e1f8..7476db295 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -41,6 +41,18 @@ void watchdogInit(unsigned int duration) IWDG->KR = 0xCCCC; // start } +#if defined(AUX_SERIAL_PWR_GPIO) +void auxSerialPowerOn() +{ + GPIO_SetBits(AUX_SERIAL_PWR_GPIO, AUX_SERIAL_PWR_GPIO_PIN); +} + +void auxSerialPowerOff() +{ + GPIO_ResetBits(AUX_SERIAL_PWR_GPIO, AUX_SERIAL_PWR_GPIO_PIN); +} +#endif + #if defined(PCBX10) && !defined(RADIO_T16) void sportUpdateInit() { @@ -110,6 +122,7 @@ void boardInit() EXTMODULE_RCC_APB2Periph | TELEMETRY_RCC_APB2Periph | BT_RCC_APB2Periph | + AUX_SERIAL_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph, ENABLE); @@ -119,6 +132,10 @@ void boardInit() __enable_irq(); +#if defined(DEBUG) && defined(AUX_SERIAL) + auxSerialInit(UART_MODE_DEBUG, 0); // default serial mode (None if DEBUG not defined) +#endif + TRACE("\nHorus board started :)"); TRACE("RCC->CSR = %08x", RCC->CSR); diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index c0289331d..8d088c6d1 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -59,7 +59,7 @@ extern uint16_t sessionTimer; #define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) -#if defined(PCBX10) && !defined(RADIO_T16) +#if defined(PCBX10) && !defined(RADIO_FAMILY_T16) #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET) #else #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET) @@ -490,6 +490,10 @@ void pwrResetHandler(); bool pwrPressed(); uint32_t pwrPressedDuration(); +// USB Charger +void usbChargerInit(); +bool usbChargerLed(); + // Led driver void ledInit(); void ledOff(); @@ -527,7 +531,7 @@ void backlightEnable(uint8_t dutyCycle = 0); #define BACKLIGHT_LEVEL_MAX 100 #if defined(PCBX12S) #define BACKLIGHT_LEVEL_MIN 5 -#elif defined(RADIO_T16) +#elif defined(RADIO_FAMILY_T16) #define BACKLIGHT_LEVEL_MIN 1 #else #define BACKLIGHT_LEVEL_MIN 46 @@ -547,6 +551,10 @@ void usbJoystickUpdate(); #define USB_NAME "Jumper T16" #define USB_MANUFACTURER 'J', 'u', 'm', 'p', 'e', 'r', ' ', ' ' /* 8 bytes */ #define USB_PRODUCT 'T', '1', '6', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */ +#elif defined(RADIO_TX16S) + #define USB_NAME "RadioMas TX16S" + #define USB_MANUFACTURER 'R', 'a', 'd', 'i', 'o', 'M', 'a ', 's ' /* 8 bytes */ + #define USB_PRODUCT 'T', 'X', '1', '6 ', 'S ', ' ', ' ', ' ' /* 8 Bytes */ #elif defined(PCBX10) #define USB_NAME "FrSky X10" #define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */ @@ -598,6 +606,26 @@ void sportUpdatePowerOff(); #define SPORT_UPDATE_POWER_OFF() #endif +// Second serial port driver +#if defined(AUX_SERIAL_GPIO) +#define DEBUG_BAUDRATE 115200 +extern uint8_t auxSerialMode; +void auxSerialInit(unsigned int mode, unsigned int protocol); +void auxSerialPutc(char c); +#define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) +void auxSerialSbusInit(); +void auxSerialStop(); +void auxSerialPowerOn(); +void auxSerialPowerOff(); +#if defined(AUX_SERIAL_PWR_GPIO) +#define AUX_SERIAL_POWER_ON() auxSerialPowerOn() +#define AUX_SERIAL__POWER_OFF() auxSerialPowerOff() +#else +#define AUX_SERIAL_POWER_ON() +#define AUX_SERIAL__POWER_OFF() +#endif +#endif + // Haptic driver void hapticInit(); void hapticDone(); diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 1e5eb137e..7fea582c3 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -38,6 +38,21 @@ #define KEYS_GPIO_PIN_DOWN GPIO_Pin_6 // PI.06 #define KEYS_GPIO_REG_RIGHT GPIOC->IDR #define KEYS_GPIO_PIN_RIGHT GPIO_Pin_4 // PC.04 +#elif defined(RADIO_TX16S) + #define KEYS_GPIO_REG_ENTER GPIOI->IDR + #define KEYS_GPIO_PIN_ENTER GPIO_Pin_8 // PI.08 + #define KEYS_GPIO_REG_PGUP GPIOH->IDR + #define KEYS_GPIO_PIN_PGUP GPIO_Pin_2 // PH.02 + #define KEYS_GPIO_REG_PGDN GPIOI->IDR + #define KEYS_GPIO_PIN_PGDN GPIO_Pin_11 // PI.11 + #define KEYS_GPIO_REG_UP GPIOI->IDR + #define KEYS_GPIO_PIN_UP GPIO_Pin_6 // PI.06 + #define KEYS_GPIO_REG_DOWN GPIOI->IDR + #define KEYS_GPIO_PIN_DOWN GPIO_Pin_4 // PI.04 + #define KEYS_GPIO_REG_LEFT GPIOI->IDR + #define KEYS_GPIO_PIN_LEFT GPIO_Pin_7 // PI.07 + #define KEYS_GPIO_REG_RIGHT GPIOI->IDR + #define KEYS_GPIO_PIN_RIGHT GPIO_Pin_5 // PI.05 #elif defined(PCBX10) #define KEYS_GPIO_REG_ENTER GPIOI->IDR #define KEYS_GPIO_PIN_ENTER GPIO_Pin_8 // PI.08 @@ -183,7 +198,7 @@ #define TRIMS_GPIO_PIN_RVU GPIO_Pin_12 // PJ.12 #define TRIMS_GPIO_REG_RHR GPIOD->IDR #define TRIMS_GPIO_PIN_RHR GPIO_Pin_7 // PD.07 - #if defined(RADIO_T16) + #if defined(RADIO_FAMILY_T16) #define TRIMS_GPIO_REG_LSU GPIOD->IDR #define TRIMS_GPIO_PIN_LSU GPIO_Pin_13 // PD.13 #define TRIMS_GPIO_REG_LSD GPIOJ->IDR @@ -215,7 +230,11 @@ #define KEYS_GPIOD_PINS (GPIO_Pin_11 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_13) #define KEYS_GPIOE_PINS (GPIO_Pin_3) #define KEYS_GPIOG_PINS (SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_LVD) +#if defined(RADIO_TX16S) + #define KEYS_GPIOH_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) +#else #define KEYS_GPIOH_PINS (GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) +#endif #define KEYS_GPIOI_PINS (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_15) #define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | GPIO_Pin_8) #endif @@ -288,7 +307,7 @@ #define ADC_DMA_Stream DMA2_Stream0 #define ADC_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) - #if defined(RADIO_T16) + #if defined(RADIO_FAMILY_T16) #define ADC_VREF_PREC2 300 #else #define ADC_VREF_PREC2 250 @@ -302,13 +321,28 @@ #define PWR_SWITCH_GPIO GPIOJ #define PWR_SWITCH_GPIO_PIN GPIO_Pin_0 // PJ.00 +// USB Charger +#if defined(USB_CHARGER) +#define USB_CHARGER_RCC_AHB1Periph RCC_AHB1Periph_GPIOG +#define USB_CHARGER_GPIO GPIOG +#define USB_CHARGER_GPIO_PIN GPIO_Pin_11 // PG.11 +#else +#define USB_CHARGER_RCC_AHB1Periph 0 +#endif + // S.Port update connector -#if defined(RADIO_T16) +#if defined(RADIO_FAMILY_T16) #define SPORT_MAX_BAUDRATE 400000 #else #define SPORT_MAX_BAUDRATE 250000 // < 400000 #endif -#if defined(PCBX10) && !defined(RADIO_T16) + +#if defined(RADIO_TX16S) + #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOA + #define SPORT_UPDATE_PWR_GPIO GPIOA + #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_15 // PA.15 + #define HAS_SPORT_UPDATE_CONNECTOR() true +#elif defined(PCBX10) && !defined(RADIO_T16) #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOH #define SPORT_UPDATE_PWR_GPIO GPIOH #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_13 // PH.13 @@ -350,6 +384,7 @@ #if defined(PCBX12S) #define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3 + #define AUX_SERIAL_RCC_APB2Periph 0 #define AUX_SERIAL_GPIO GPIOB #define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_10 // PB.10 #define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_11 // PB.11 @@ -361,9 +396,28 @@ #define AUX_SERIAL_USART_IRQn USART3_IRQn #define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1 #define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4 +#elif defined(RADIO_TX16S) && !defined(BLUETOOTH) + #define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_DMA2) + #define AUX_SERIAL_RCC_APB1Periph 0 + #define AUX_SERIAL_RCC_APB2Periph RCC_APB2Periph_USART6 + #define AUX_SERIAL_USART USART6 + #define AUX_SERIAL_GPIO_AF GPIO_AF_USART6 + #define AUX_SERIAL_USART_IRQn USART6_IRQn + #define AUX_SERIAL_GPIO GPIOG + #define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_14 // PG.14 + #define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_9 // PG.09 + #define AUX_SERIAL_GPIO_PinSource_TX GPIO_PinSource14 + #define AUX_SERIAL_GPIO_PinSource_RX GPIO_PinSource9 + #define AUX_SERIAL_USART_IRQHandler USART6_IRQHandler + #define AUX_SERIAL_DMA_Stream_RX DMA2_Stream6 + #define AUX_SERIAL_DMA_Channel_RX DMA_Channel_5 + #define AUX_SERIAL_PWR_GPIO GPIOB + #define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_0 // PB.00 + #define TRAINER_BATTERY_COMPARTMENT #else #define AUX_SERIAL_RCC_AHB1Periph 0 #define AUX_SERIAL_RCC_APB1Periph 0 + #define AUX_SERIAL_RCC_APB2Periph 0 #endif // Telemetry @@ -550,12 +604,16 @@ #define AUDIO_DMA DMA1 #endif -#if defined(RADIO_T16) +#if defined(RADIO_FAMILY_T16) #define AUDIO_UNMUTE_DELAY 120 // ms #define AUDIO_MUTE_DELAY 500 // ms #endif // I2C Bus +#if defined(RADIO_TX16S) +#define I2C_RCC_AHB1Periph 0 +#define I2C_RCC_APB1Periph 0 +#else #define I2C_RCC_AHB1Periph RCC_AHB1Periph_GPIOB #define I2C_RCC_APB1Periph RCC_APB1Periph_I2C1 #define I2C I2C1 @@ -566,6 +624,7 @@ #define I2C_SCL_GPIO_PinSource GPIO_PinSource8 #define I2C_SDA_GPIO_PinSource GPIO_PinSource9 #define I2C_SPEED 400000 +#endif // Haptic #define HAPTIC_PWM @@ -593,7 +652,7 @@ #define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR2 #endif -#if !defined(RADIO_T16) +#if !defined(RADIO_FAMILY_T16) #define EXTERNAL_ANTENNA #endif #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2) @@ -760,6 +819,7 @@ // Bluetooth #define STORAGE_BLUETOOTH +#if defined(BLUETOOTH) #define BT_RCC_APB2Periph RCC_APB2Periph_USART6 #define BT_USART USART6 #define BT_GPIO_AF GPIO_AF_USART6 @@ -770,6 +830,9 @@ #define BT_TX_GPIO_PinSource GPIO_PinSource14 #define BT_RX_GPIO_PinSource GPIO_PinSource9 #define BT_USART_IRQHandler USART6_IRQHandler +#else +#define BT_RCC_APB2Periph 0 +#endif #if defined(PCBX12S) #if PCBREV >= 13 #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOG) diff --git a/radio/src/targets/horus/keys_driver.cpp b/radio/src/targets/horus/keys_driver.cpp index 9879135dd..888c4dabc 100644 --- a/radio/src/targets/horus/keys_driver.cpp +++ b/radio/src/targets/horus/keys_driver.cpp @@ -24,7 +24,7 @@ uint32_t readKeys() { uint32_t result = 0; -#if defined(PCBX12S) +#if defined(KEYS_GPIO_REG_PGUP) if (~KEYS_GPIO_REG_PGUP & KEYS_GPIO_PIN_PGUP) result |= 1 << KEY_PGUP; #endif diff --git a/radio/src/targets/horus/usb_charger_driver.cpp b/radio/src/targets/horus/usb_charger_driver.cpp new file mode 100644 index 000000000..3ba915318 --- /dev/null +++ b/radio/src/targets/horus/usb_charger_driver.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +void usbChargerInit() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = USB_CHARGER_RCC_AHB1Periph; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(USB_CHARGER_GPIO, &GPIO_InitStructure); +} + +bool usbChargerLed() +{ + return GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_CHARGER_GPIO_PIN) == Bit_RESET; +} + diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 4f7e2cd87..e978d8277 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -786,6 +786,8 @@ void auxSerialPutc(char c); #define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) void auxSerialSbusInit(); void auxSerialStop(); +#define AUX_SERIAL_POWER_ON() +#define AUX_SERIAL__POWER_OFF() #endif // BT driver diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 31cf6a4a9..5d2c67bf9 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1309,10 +1309,12 @@ #if defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019) #define AUX_SERIAL_RCC_AHB1Periph 0 #define AUX_SERIAL_RCC_APB1Periph 0 + #define AUX_SERIAL_RCC_APB2Periph 0 #else #define TRAINER_BATTERY_COMPARTMENT #define AUX_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) #define AUX_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3 + #define AUX_SERIAL_RCC_APB2Periph 0 #define AUX_SERIAL_GPIO GPIOB #define AUX_SERIAL_GPIO_PIN_TX GPIO_Pin_10 // PB.10 #define AUX_SERIAL_GPIO_PIN_RX GPIO_Pin_11 // PB.11 diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index e6b41faae..adc3120cd 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -316,6 +316,13 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) uint8_t len = packet[1]; const uint8_t * data = packet + 2; +#if defined(AUX_SERIAL) + if (g_eeGeneral.auxSerialMode == UART_MODE_TELEMETRY_MIRROR) { + for (uint8_t c=0; c < len; c++) + auxSerialPutc(packet[c]); + } +#endif + // Switch type switch (type) { case MultiStatus: diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index ed569729a..15361a065 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -68,7 +68,9 @@ #define TR_VSWITCHES "---" "ID0""ID1""ID2" "THR""RUD""ELE""AIL""GEA""TRN" TR_TRIMS_SWITCHES TR_ROTENC_SWITCHES TR_ON_ONE_SWITCHES #endif -#if defined(PCBHORUS) +#if defined(PCBHORUS) && defined(AUX_SERIAL) + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI +#elif defined(PCBHORUS) #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBTARANIS) #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI From 128265327e6e73c7ac5a64ee781ab656dde3372c Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 31 Jan 2020 09:21:34 +0100 Subject: [PATCH 30/70] Some TX16S related changes --- radio/util/build-firmware.py | 5 +++++ tools/build-companion-nightly.sh | 4 ++++ tools/build-companion-release.sh | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py index 9658e605d..373e4a41d 100755 --- a/radio/util/build-firmware.py +++ b/radio/util/build-firmware.py @@ -149,6 +149,11 @@ def main(): cmake_options["PCBREV"] = "T16" firmware_options = options_jumper_t16 maxsize = 2 * 1024 * 1024 + elif board_name == "tx16s": + cmake_options["PCB"] = "X10" + cmake_options["PCBREV"] = "TX16S" + firmware_options = options_jumper_t16 + maxsize = 2 * 1024 * 1024 else: exit(INVALID_BOARD) diff --git a/tools/build-companion-nightly.sh b/tools/build-companion-nightly.sh index bd5eb97ad..683e0e4d6 100755 --- a/tools/build-companion-nightly.sh +++ b/tools/build-companion-nightly.sh @@ -98,6 +98,10 @@ cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=T16 -DINTERNAL_MODULE_MULTI=YES ${SRC make -j${JOBS} libsimulator rm CMakeCache.txt +cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=TX16S ${SRCDIR} +make -j${JOBS} libsimulator +rm CMakeCache.txt + cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=EXPRESS ${SRCDIR} make -j${JOBS} libsimulator rm CMakeCache.txt diff --git a/tools/build-companion-release.sh b/tools/build-companion-release.sh index 0529e9154..34757a3e8 100755 --- a/tools/build-companion-release.sh +++ b/tools/build-companion-release.sh @@ -98,6 +98,10 @@ cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=T16 -DINTERNAL_MODULE_MULTI=YES ${SRC make -j${JOBS} libsimulator rm CMakeCache.txt +cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=TX16S ${SRCDIR} +make -j${JOBS} libsimulator +rm CMakeCache.txt + cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=EXPRESS ${SRCDIR} make -j${JOBS} libsimulator rm CMakeCache.txt From ecb21a3df3b05d2ae7d1182910d16f9e1b596f25 Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 31 Jan 2020 11:15:38 +0100 Subject: [PATCH 31/70] Trigger new Sd card version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 820530334..7cccabf1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(VERSION_REVISION "6") set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) -set(SDCARD_REVISION "0025") +set(SDCARD_REVISION "0026") set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION}) cmake_minimum_required(VERSION 2.8) From 72721bde001f222ca652a800d4302967845870b8 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sat, 1 Feb 2020 15:01:20 +0100 Subject: [PATCH 32/70] Define AUX2 (4 pins) --- radio/src/targets/horus/hal.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 7fea582c3..76c459a5f 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -337,12 +337,7 @@ #define SPORT_MAX_BAUDRATE 250000 // < 400000 #endif -#if defined(RADIO_TX16S) - #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOA - #define SPORT_UPDATE_PWR_GPIO GPIOA - #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_15 // PA.15 - #define HAS_SPORT_UPDATE_CONNECTOR() true -#elif defined(PCBX10) && !defined(RADIO_T16) +#if defined(PCBX10) && !defined(RADIO_FAMILY_T16) #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOH #define SPORT_UPDATE_PWR_GPIO GPIOH #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_13 // PH.13 @@ -414,6 +409,23 @@ #define AUX_SERIAL_PWR_GPIO GPIOB #define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_0 // PB.00 #define TRAINER_BATTERY_COMPARTMENT + + #define AUX2_SERIAL_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1) + #define AUX2_SERIAL_PWR_GPIO GPIOA + #define AUX2_SERIAL_PWR_GPIO_PIN GPIO_Pin_15 // PA.15 + #define AUX2_SERIAL_RCC_APB1Periph RCC_APB1Periph_USART3 + #define AUX2_SERIAL_RCC_APB2Periph 0 + #define AUX2_SERIAL_GPIO GPIOB + #define AUX2_SERIAL_GPIO_PIN_TX GPIO_Pin_10 // PB.10 + #define AUX2_SERIAL_GPIO_PIN_RX GPIO_Pin_11 // PB.11 + #define AUX2_SERIAL_GPIO_PinSource_TX GPIO_PinSource10 + #define AUX2_SERIAL_GPIO_PinSource_RX GPIO_PinSource11 + #define AUX2_SERIAL_GPIO_AF GPIO_AF_USART3 + #define AUX2_SERIAL_USART USART3 + #define AUX2_SERIAL_USART_IRQHandler USART3_IRQHandler + #define AUX2_SERIAL_USART_IRQn USART3_IRQn + #define AUX2_SERIAL_DMA_Stream_RX DMA1_Stream1 + #define AUX2_SERIAL_DMA_Channel_RX DMA_Channel_4 #else #define AUX_SERIAL_RCC_AHB1Periph 0 #define AUX_SERIAL_RCC_APB1Periph 0 From fa6cd0307536919d4112de536b90cce3f6516562 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sat, 1 Feb 2020 15:59:45 +0100 Subject: [PATCH 33/70] Some portuguese TTS fixes --- radio/src/translations/tts_pt.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/radio/src/translations/tts_pt.cpp b/radio/src/translations/tts_pt.cpp index 34a3ff75b..a909227f5 100644 --- a/radio/src/translations/tts_pt.cpp +++ b/radio/src/translations/tts_pt.cpp @@ -96,7 +96,6 @@ I18N_PLAY_FUNCTION(pt, playNumber, getvalue_t number, uint8_t unit, uint8_t att) number = -number; } - int8_t mode = MODE(att); if (mode > 0) { if (mode == 2) { @@ -127,13 +126,20 @@ I18N_PLAY_FUNCTION(pt, playNumber, getvalue_t number, uint8_t unit, uint8_t att) if (number == 0) number = -1; } - if (number >= 100) { - PUSH_NUMBER_PROMPT(PT_PROMPT_CENTO + number/100); + + if (number > 100) { + PUSH_NUMBER_PROMPT(PT_PROMPT_CEM + number/100); number %= 100; if (number == 0) number = -1; } - PUSH_NUMBER_PROMPT(PT_PROMPT_ZERO+number); + + if (number == 100) { + PUSH_NUMBER_PROMPT(PT_PROMPT_CEM); + } + else { + PUSH_NUMBER_PROMPT(PT_PROMPT_ZERO + number); + } if (unit) { PT_PUSH_UNIT_PROMPT(unit); From bd75013b7b020291e5a599b415ee9e18fd42a92a Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 3 Feb 2020 07:06:09 +0100 Subject: [PATCH 34/70] Remove warning --- radio/src/targets/horus/board.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 8d088c6d1..d5b7bdac5 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -553,8 +553,8 @@ void usbJoystickUpdate(); #define USB_PRODUCT 'T', '1', '6', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */ #elif defined(RADIO_TX16S) #define USB_NAME "RadioMas TX16S" - #define USB_MANUFACTURER 'R', 'a', 'd', 'i', 'o', 'M', 'a ', 's ' /* 8 bytes */ - #define USB_PRODUCT 'T', 'X', '1', '6 ', 'S ', ' ', ' ', ' ' /* 8 Bytes */ + #define USB_MANUFACTURER 'R', 'a', 'd', 'i', 'o', 'M', 'a', 's' /* 8 bytes */ + #define USB_PRODUCT 'T', 'X', '1', '6', 'S', ' ', ' ', ' ' /* 8 Bytes */ #elif defined(PCBX10) #define USB_NAME "FrSky X10" #define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */ From b7523d12f0383a004e54ac66eff188161fc023e2 Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 3 Feb 2020 07:32:31 +0100 Subject: [PATCH 35/70] Fix TX16S compile, and add more radio to Travis --- radio/src/targets/horus/board.cpp | 4 ++-- radio/src/targets/horus/board.h | 2 +- tools/commit-tests.sh | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index 7476db295..abdde2106 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -53,7 +53,7 @@ void auxSerialPowerOff() } #endif -#if defined(PCBX10) && !defined(RADIO_T16) +#if HAS_SPORT_UPDATE_CONNECTOR() void sportUpdateInit() { GPIO_InitTypeDef GPIO_InitStructure; @@ -179,7 +179,7 @@ void boardInit() ledInit(); -#if defined(PCBX10) && !defined(RADIO_T16) +#if HAS_SPORT_UPDATE_CONNECTOR() sportUpdateInit(); #endif diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index d5b7bdac5..09554c063 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -596,7 +596,7 @@ extern uint32_t telemetryErrors; void telemetryPortInvertedInit(uint32_t baudrate); // Sport update driver -#if defined(PCBX10) && !defined(RADIO_T16) +#if HAS_SPORT_UPDATE_CONNECTOR() void sportUpdatePowerOn(); void sportUpdatePowerOff(); #define SPORT_UPDATE_POWER_ON() sportUpdatePowerOn() diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index 9e470343c..b3d193ed1 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -184,6 +184,24 @@ if [[ " X10 COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then make -j"${CORES}" tests-radio fi +if [[ " T16 COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on T16 boards + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X10 -PCBREV=T16 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " TX16S COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on TX16S boards + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X10 -DPCB=TX16S -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + if [[ " X12S COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X12S rm -rf ./* From e96a76ff76d1d7d689024cc1b7ca99403097c8ba Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 3 Feb 2020 07:51:19 +0100 Subject: [PATCH 36/70] Fix Travis --- tools/commit-tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index b3d193ed1..a15b698e7 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -187,7 +187,7 @@ fi if [[ " T16 COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on T16 boards rm -rf ./* - cmake "${COMMON_OPTIONS}" -DPCB=X10 -PCBREV=T16 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X10 -DPCBREV=T16 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -196,7 +196,7 @@ fi if [[ " TX16S COLORLCD ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on TX16S boards rm -rf ./* - cmake "${COMMON_OPTIONS}" -DPCB=X10 -DPCB=TX16S -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X10 -DPCBREV=TX16S -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio From ab33670e1785580c2c1e5ef0d40345b704632445 Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 3 Feb 2020 08:50:46 +0100 Subject: [PATCH 37/70] Remove a warning --- radio/src/lua/api_general.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 28b072f95..30a03355e 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -456,7 +456,7 @@ static int luaSportTelemetryPush(lua_State * L) lua_pushboolean(L, outputTelemetryBuffer.isAvailable()); return 1; } - else if (lua_gettop(L) > sizeof(SportTelemetryPacket) ) { + else if (lua_gettop(L) > int(sizeof(SportTelemetryPacket))) { lua_pushboolean(L, false); return 1; } From 54b58385279ca10273451daf8a093a8ad02b84ff Mon Sep 17 00:00:00 2001 From: 3djc Date: Mon, 3 Feb 2020 09:12:31 +0100 Subject: [PATCH 38/70] No conversion test from x10 for T16 / TX16S --- radio/src/tests/conversions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/tests/conversions.cpp b/radio/src/tests/conversions.cpp index 897d5cb59..26cdc159e 100644 --- a/radio/src/tests/conversions.cpp +++ b/radio/src/tests/conversions.cpp @@ -222,7 +222,7 @@ TEST(Conversions, ConversionX7From22) } #endif -#if defined(PCBX10) +#if defined(PCBX10) && !defined(RADIO_FAMILY_T16) TEST(Conversions, ConversionX10From22) { simuFatfsSetPaths(TESTS_BUILD_PATH "/model_22_x10/", TESTS_BUILD_PATH "/model_22_x10/"); From c81ec60e8bb21a825b0a0a3dda5cecef1e2db3f1 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 5 Feb 2020 23:47:48 +0100 Subject: [PATCH 39/70] Update CREDITS.txt --- CREDITS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CREDITS.txt b/CREDITS.txt index f90be0081..6dc75219b 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1696,3 +1696,5 @@ Fernando Rimoldi Bernard Delpy Daniel Dubovsky Jonathan Starch +Coolwind +Benoit Pichereau From 4c94dd3ba0a2e488c96494e5cbdb3b1076827a73 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 6 Feb 2020 08:15:10 +0100 Subject: [PATCH 40/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 6dc75219b..804ab0846 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1698,3 +1698,4 @@ Daniel Dubovsky Jonathan Starch Coolwind Benoit Pichereau +Darko Perković From 40d57a88537d06625c0887ebc455f9dd955972c5 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 6 Feb 2020 14:36:21 +0100 Subject: [PATCH 41/70] Add name handling to LUA timer functions (#7358) Add timer name to LUA timer functions --- radio/src/lua/api_model.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/radio/src/lua/api_model.cpp b/radio/src/lua/api_model.cpp index 990d477d4..3d9a4e48a 100644 --- a/radio/src/lua/api_model.cpp +++ b/radio/src/lua/api_model.cpp @@ -182,8 +182,9 @@ Get model timer parameters * `countdownBeep` (number) countdown beep (0­ = silent, 1 =­ beeps, 2­ = voice) * `minuteBeep` (boolean) minute beep * `persistent` (number) persistent timer + * `name` (string) timer name -@status current Introduced in 2.0.0 +@status current Introduced in 2.0.0, name added in 2.3.6 */ static int luaModelGetTimer(lua_State *L) { @@ -197,6 +198,7 @@ static int luaModelGetTimer(lua_State *L) lua_pushtableinteger(L, "countdownBeep", timer.countdownBeep); lua_pushtableboolean(L, "minuteBeep", timer.minuteBeep); lua_pushtableinteger(L, "persistent", timer.persistent); + lua_pushtablezstring(L, "name", timer.name); } else { lua_pushnil(L); @@ -216,7 +218,7 @@ Set model timer parameters @notice If a parameter is missing from the value, then that parameter remains unchanged. -@status current Introduced in 2.0.0 +@status current Introduced in 2.0.0, name added in 2.3.6 */ static int luaModelSetTimer(lua_State *L) { @@ -246,6 +248,10 @@ static int luaModelSetTimer(lua_State *L) else if (!strcmp(key, "persistent")) { timer.persistent = luaL_checkinteger(L, -1); } + if (!strcmp(key, "name")) { + const char * name = luaL_checkstring(L, -1); + str2zchar(timer.name, name, sizeof(timer.name)); + } } storageDirty(EE_MODEL); } From c7b7efbe168a53965f6070d67db2fa0126aafb87 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 6 Feb 2020 14:52:35 +0100 Subject: [PATCH 42/70] Complement #7346 (#7350) --- radio/src/targets/horus/telemetry_driver.cpp | 1 - radio/src/targets/taranis/board.cpp | 3 ++- radio/src/targets/taranis/hal.h | 1 + radio/src/targets/taranis/telemetry_driver.cpp | 1 - 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index ecd73b6ab..ffb1cbc2c 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -156,7 +156,6 @@ void telemetryPortInvertedInit(uint32_t baudrate) rxBitCount = 0; // configure bit sample timer - RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; TELEMETRY_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS TELEMETRY_TIMER->CCER = 0; TELEMETRY_TIMER->CCMR1 = 0; diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 2dfa0a886..3cd6742f3 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -113,7 +113,8 @@ void boardInit() INTMODULE_RCC_APB2Periph | EXTMODULE_RCC_APB2Periph | TRAINER_MODULE_RCC_APB2Periph | - BT_RCC_APB2Periph, + BT_RCC_APB2Periph | + TELEMETRY_RCC_APB2Periph, ENABLE); #if defined(BLUETOOTH) && !defined(PCBX9E) diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 5d2c67bf9..645ebe327 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1331,6 +1331,7 @@ // Telemetry #define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) #define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 +#define TELEMETRY_RCC_APB2Periph RCC_APB2Periph_TIM11 #define TELEMETRY_DIR_GPIO GPIOD #define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04 #if defined(PCBXLITE) || defined(PCBX9LITE) || defined(RADIO_X9DP2019) || defined(RADIO_X7ACCESS) diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index 3c9618f03..e5b0d8cfe 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -117,7 +117,6 @@ void telemetryPortInvertedInit(uint32_t baudrate) rxBitCount = 0; // configure bit sample timer - RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; TELEMETRY_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS TELEMETRY_TIMER->CCER = 0; TELEMETRY_TIMER->CCMR1 = 0; From 90fee60337e142dbd0ddc100e46bafeee376e8bf Mon Sep 17 00:00:00 2001 From: olliw42 <6089567+olliw42@users.noreply.github.com> Date: Thu, 6 Feb 2020 14:52:54 +0100 Subject: [PATCH 43/70] telemetry tim11 rcc (#7347) --- radio/src/targets/horus/hal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 76c459a5f..f5692a8c7 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -435,7 +435,7 @@ // Telemetry #define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) #define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 -#define TELEMETRY_RCC_APB2Periph RCC_APB2Periph_TIM10 +#define TELEMETRY_RCC_APB2Periph RCC_APB2Periph_TIM11 #define TELEMETRY_DIR_GPIO GPIOD #define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04 #define TELEMETRY_GPIO GPIOD From 00cd0f918c3ddc7ef7f65c772d7f9b3fedd38d65 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 6 Feb 2020 15:33:32 +0100 Subject: [PATCH 44/70] Fix #7332 (#7355) --- companion/src/logsdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/companion/src/logsdialog.cpp b/companion/src/logsdialog.cpp index e60318c69..b7fa54f16 100644 --- a/companion/src/logsdialog.cpp +++ b/companion/src/logsdialog.cpp @@ -761,7 +761,7 @@ void LogsDialog::setFlightSessions() int noSesions = sessions.size()-1; QString label = QString("%1 ").arg(noSesions); label += tr(noSesions > 1 ? "sessions" : "session"); - label += " <" + tr("total duration ") + generateDuration(getRecordTimeStamp(1), getRecordTimeStamp(n-1)) + ">"; + label += " <" + tr("time span") + generateDuration(getRecordTimeStamp(1), getRecordTimeStamp(n-1)) + ">"; ui->sessions_CB->addItem(label); // add individual sessions From 4658cd9ad844e878058ed11e65acb8be2bf6ef2d Mon Sep 17 00:00:00 2001 From: dukey32123 Date: Fri, 7 Feb 2020 00:06:57 +0100 Subject: [PATCH 45/70] Move Module Tools behind Radio Script Tools (#7360) Update Radio / Tools --- radio/src/gui/480x272/radio_tools.cpp | 34 +++++++++++---------- radio/src/gui/common/stdlcd/radio_tools.cpp | 34 +++++++++++---------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/radio/src/gui/480x272/radio_tools.cpp b/radio/src/gui/480x272/radio_tools.cpp index 407a5b2fe..21cabf522 100644 --- a/radio/src/gui/480x272/radio_tools.cpp +++ b/radio/src/gui/480x272/radio_tools.cpp @@ -91,23 +91,7 @@ bool menuRadioTools(event_t event) uint8_t index = 0; -#if defined(INTERNAL_MODULE_PXX2) - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) - addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) - addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); -#elif defined(INTERNAL_MODULE_MULTI) - addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); -#endif -#if defined(PXX2)|| defined(MULTIMODULE) - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER) || isModuleMultimodule(EXTERNAL_MODULE)) - addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE); -#endif -#if defined(PXX2) - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) - addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); -#endif #if defined(LUA) FILINFO fno; @@ -130,6 +114,24 @@ bool menuRadioTools(event_t event) } #endif +#if defined(INTERNAL_MODULE_PXX2) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); + + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); +#elif defined(INTERNAL_MODULE_MULTI) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); +#endif +#if defined(PXX2)|| defined(MULTIMODULE) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER) || isModuleMultimodule(EXTERNAL_MODULE)) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE); +#endif +#if defined(PXX2) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); +#endif + if (index == 0) { lcdDrawCenteredText(LCD_H/2, STR_NO_TOOLS); } diff --git a/radio/src/gui/common/stdlcd/radio_tools.cpp b/radio/src/gui/common/stdlcd/radio_tools.cpp index 478c052b3..d5bfd12d4 100644 --- a/radio/src/gui/common/stdlcd/radio_tools.cpp +++ b/radio/src/gui/common/stdlcd/radio_tools.cpp @@ -87,23 +87,7 @@ void menuRadioTools(event_t event) uint8_t index = 0; -#if defined(INTERNAL_MODULE_PXX2) - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) - addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) - addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); -#elif defined(INTERNAL_MODULE_MULTI) - addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); -#endif -#if defined(PXX2)|| defined(MULTIMODULE) - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER) || isModuleMultimodule(EXTERNAL_MODULE)) - addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE); -#endif -#if defined(PXX2) - if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) - addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); -#endif #if defined(LUA) FILINFO fno; @@ -127,6 +111,24 @@ void menuRadioTools(event_t event) } #endif +#if defined(INTERNAL_MODULE_PXX2) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); + + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); +#elif defined(INTERNAL_MODULE_MULTI) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); +#endif +#if defined(PXX2)|| defined(MULTIMODULE) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER) || isModuleMultimodule(EXTERNAL_MODULE)) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE); +#endif +#if defined(PXX2) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); +#endif + if (index == 0) { lcdDrawCenteredText(LCD_H/2, STR_NO_TOOLS); } From 7f5276224e9bf3319ee475a87c09c2f224bbc2fd Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 7 Feb 2020 09:54:35 +0100 Subject: [PATCH 46/70] Fix LUA telemetry (+/-/exit handling) (#7356) Fix LUA telemetry (+/-/exit handling) --- radio/src/gui/128x64/gui.h | 2 +- radio/src/gui/128x64/menus.h | 2 +- radio/src/gui/128x64/view_main.cpp | 2 +- radio/src/gui/128x64/view_telemetry.cpp | 76 ------------- radio/src/gui/212x64/gui.h | 2 +- radio/src/gui/212x64/menus.h | 2 +- radio/src/gui/212x64/view_main.cpp | 2 +- radio/src/gui/212x64/view_telemetry.cpp | 62 ----------- radio/src/gui/common/stdlcd/CMakeLists.txt | 1 + .../src/gui/common/stdlcd/view_telemetry.cpp | 100 ++++++++++++++++++ radio/src/lua/interface.cpp | 2 +- 11 files changed, 108 insertions(+), 145 deletions(-) create mode 100644 radio/src/gui/common/stdlcd/view_telemetry.cpp diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index 329a9c3a4..8ac31d239 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -302,7 +302,7 @@ void showAlertBox(const char * title, const char * text, const char * action , u #define LOAD_MODEL_BITMAP() #define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView -#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetryFrsky +#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry #define IS_OTHER_VIEW_DISPLAYED() false void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags); diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index d861a626f..daa3f1885 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -45,7 +45,7 @@ inline bool isModelMenuDisplayed() void onMainViewMenu(const char * result); void menuFirstCalib(event_t event); void menuMainView(event_t event); -void menuViewTelemetryFrsky(event_t event); +void menuViewTelemetry(event_t event); void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); enum MenuRadioIndexes diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 737a4dc44..b1ab8cd79 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -397,7 +397,7 @@ void menuMainView(event_t event) #endif case EVT_KEY_TELEMETRY: - chainMenu(menuViewTelemetryFrsky); + chainMenu(menuViewTelemetry); killEvents(event); break; diff --git a/radio/src/gui/128x64/view_telemetry.cpp b/radio/src/gui/128x64/view_telemetry.cpp index f6d5d7301..86d369377 100644 --- a/radio/src/gui/128x64/view_telemetry.cpp +++ b/radio/src/gui/128x64/view_telemetry.cpp @@ -206,79 +206,3 @@ bool displayTelemetryScreen() return true; } - -enum NavigationDirection { - none, - up, - down -}; -#define decrTelemetryScreen() direction = up -#define incrTelemetryScreen() direction = down - -#if defined(NAVIGATION_XLITE) - #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_LEFT) && IS_SHIFT_PRESSED()) - #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED()) -#elif defined(NAVIGATION_X7) - #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE)) - #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_BREAK(KEY_PAGE)) -#elif defined(NAVIGATION_9X) - #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_UP)) - #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_DOWN)) -#else - #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_UP)) - #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_DOWN)) -#endif - -void menuViewTelemetryFrsky(event_t event) -{ - enum NavigationDirection direction = none; - - if (event == EVT_KEY_FIRST(KEY_EXIT) && TELEMETRY_SCREEN_TYPE(s_frsky_view) != TELEMETRY_SCREEN_TYPE_SCRIPT) { - killEvents(event); - chainMenu(menuMainView); - } -#if defined(LUA) - else if (event == EVT_KEY_LONG(KEY_EXIT)) { - killEvents(event); - chainMenu(menuMainView); - } -#endif - else if (EVT_KEY_PREVIOUS_VIEW(event)) { - killEvents(event); - decrTelemetryScreen(); - } - else if (EVT_KEY_NEXT_VIEW(event)) { - killEvents(event); - incrTelemetryScreen(); - } - else if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - POPUP_MENU_ADD_ITEM(STR_RESET_TELEMETRY); - POPUP_MENU_ADD_ITEM(STR_RESET_FLIGHT); - POPUP_MENU_START(onMainViewMenu); - } - - for (int i=0; i<=TELEMETRY_SCREEN_TYPE_MAX; i++) { - if (direction == up) { - if (s_frsky_view-- == 0) - s_frsky_view = TELEMETRY_VIEW_MAX; - } - else if (direction == down) { - if (s_frsky_view++ == TELEMETRY_VIEW_MAX) - s_frsky_view = 0; - } - else { - direction = down; - } - if (displayTelemetryScreen()) { - return; - } - } - - drawTelemetryTopBar(); - lcdDrawText(2*FW, 3*FH, "No Telemetry Screens"); - displayRssiLine(); -} - -#undef EVT_KEY_PREVIOUS_VIEW -#undef EVT_KEY_NEXT_VIEW diff --git a/radio/src/gui/212x64/gui.h b/radio/src/gui/212x64/gui.h index 3883a2e86..c430a0646 100644 --- a/radio/src/gui/212x64/gui.h +++ b/radio/src/gui/212x64/gui.h @@ -303,7 +303,7 @@ FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModes #endif #define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView -#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetryFrsky +#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry #define IS_OTHER_VIEW_DISPLAYED() (menuHandlers[0] == menuMainViewChannelsMonitor || menuHandlers[0] == menuChannelsView) #endif // _GUI_H_ diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index c5025c728..bdfb8f591 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -39,7 +39,7 @@ void menuFirstCalib(event_t event); void menuMainViewChannelsMonitor(event_t event); void menuChannelsView(event_t event); void menuMainView(event_t event); -void menuViewTelemetryFrsky(event_t event); +void menuViewTelemetry(event_t event); void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); void menuModelNotes(event_t event); void menuStatisticsView(event_t event); diff --git a/radio/src/gui/212x64/view_main.cpp b/radio/src/gui/212x64/view_main.cpp index 720e3ccbf..bdbcb10a6 100644 --- a/radio/src/gui/212x64/view_main.cpp +++ b/radio/src/gui/212x64/view_main.cpp @@ -470,7 +470,7 @@ void menuMainView(event_t event) break; case EVT_KEY_LONG(KEY_PAGE): - chainMenu(menuViewTelemetryFrsky); + chainMenu(menuViewTelemetry); killEvents(event); break; diff --git a/radio/src/gui/212x64/view_telemetry.cpp b/radio/src/gui/212x64/view_telemetry.cpp index 04dc411c5..fa8740667 100644 --- a/radio/src/gui/212x64/view_telemetry.cpp +++ b/radio/src/gui/212x64/view_telemetry.cpp @@ -200,65 +200,3 @@ bool displayTelemetryScreen() return true; } -enum NavigationDirection { - none, - up, - down -}; - -#define decrTelemetryScreen() direction = up -#define incrTelemetryScreen() direction = down - -void menuViewTelemetryFrsky(event_t event) -{ - enum NavigationDirection direction = none; - - switch (event) { - case EVT_KEY_FIRST(KEY_EXIT): - case EVT_KEY_LONG(KEY_EXIT): - killEvents(event); - chainMenu(menuMainView); - break; - - case EVT_KEY_LONG(KEY_PAGE): - killEvents(event); - // no break; - - case EVT_KEY_FIRST(KEY_UP): - decrTelemetryScreen(); - break; - - case EVT_KEY_BREAK(KEY_PAGE): - case EVT_KEY_FIRST(KEY_DOWN): - incrTelemetryScreen(); - break; - - case EVT_KEY_LONG(KEY_ENTER): - killEvents(event); - POPUP_MENU_ADD_ITEM(STR_RESET_TELEMETRY); - POPUP_MENU_ADD_ITEM(STR_RESET_FLIGHT); - POPUP_MENU_START(onMainViewMenu); - break; - } - - for (int i=0; i<=TELEMETRY_SCREEN_TYPE_MAX; i++) { - if (direction == up) { - if (s_frsky_view-- == 0) - s_frsky_view = TELEMETRY_VIEW_MAX; - } - else if (direction == down) { - if (s_frsky_view++ == TELEMETRY_VIEW_MAX) - s_frsky_view = 0; - } - else { - direction = down; - } - if (displayTelemetryScreen()) { - return; - } - } - - drawTelemetryTopBar(); - lcdDrawText(8*FW, 3*FH, "No Telemetry Screens"); - displayRssiLine(); -} diff --git a/radio/src/gui/common/stdlcd/CMakeLists.txt b/radio/src/gui/common/stdlcd/CMakeLists.txt index 0d3f726b3..f20235ced 100644 --- a/radio/src/gui/common/stdlcd/CMakeLists.txt +++ b/radio/src/gui/common/stdlcd/CMakeLists.txt @@ -15,6 +15,7 @@ set(GUI_SRC ../common/stdlcd/radio_hardware.cpp ../common/stdlcd/radio_version.cpp ../common/stdlcd/radio_trainer.cpp + ../common/stdlcd/view_telemetry.cpp model_curve_edit.cpp ) diff --git a/radio/src/gui/common/stdlcd/view_telemetry.cpp b/radio/src/gui/common/stdlcd/view_telemetry.cpp new file mode 100644 index 000000000..e2bf39503 --- /dev/null +++ b/radio/src/gui/common/stdlcd/view_telemetry.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +extern bool displayTelemetryScreen(); +extern void displayRssiLine(); + +enum NavigationDirection { + NAVIGATION_DIRECTION_NONE, + NAVIGATION_DIRECTION_UP, + NAVIGATION_DIRECTION_DOWN +}; +#define decrTelemetryScreen() direction = NAVIGATION_DIRECTION_UP +#define incrTelemetryScreen() direction = NAVIGATION_DIRECTION_DOWN + +#if defined(NAVIGATION_XLITE) + #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_LEFT) && IS_SHIFT_PRESSED()) + #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED()) +#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D) + #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE)) + #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_BREAK(KEY_PAGE)) +#elif defined(NAVIGATION_9X) + #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_UP)) + #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_DOWN)) +#else + #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_UP)) + #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_DOWN)) +#endif + +void menuViewTelemetry(event_t event) +{ + enum NavigationDirection direction = NAVIGATION_DIRECTION_NONE; + + if (event == EVT_KEY_FIRST(KEY_EXIT) && TELEMETRY_SCREEN_TYPE(s_frsky_view) != TELEMETRY_SCREEN_TYPE_SCRIPT) { + killEvents(event); + chainMenu(menuMainView); + } +#if defined(LUA) + else if (event == EVT_KEY_LONG(KEY_EXIT)) { + killEvents(event); + chainMenu(menuMainView); + } +#endif + else if (EVT_KEY_PREVIOUS_VIEW(event)) { + killEvents(event); + decrTelemetryScreen(); + } + else if (EVT_KEY_NEXT_VIEW(event)) { + killEvents(event); + incrTelemetryScreen(); + } + else if (event == EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + POPUP_MENU_ADD_ITEM(STR_RESET_TELEMETRY); + POPUP_MENU_ADD_ITEM(STR_RESET_FLIGHT); + POPUP_MENU_START(onMainViewMenu); + } + + for (int i=0; i<=TELEMETRY_SCREEN_TYPE_MAX; i++) { + if (direction == NAVIGATION_DIRECTION_UP) { + if (s_frsky_view-- == 0) + s_frsky_view = TELEMETRY_VIEW_MAX; + } + else if (direction == NAVIGATION_DIRECTION_DOWN) { + if (s_frsky_view++ == TELEMETRY_VIEW_MAX) + s_frsky_view = 0; + } + else { + direction = NAVIGATION_DIRECTION_DOWN; + } + if (displayTelemetryScreen()) { + return; + } + } + + drawTelemetryTopBar(); + lcdDrawText(LCD_W / 2, 3 * FH, "No Telemetry Screens", CENTERED); + displayRssiLine(); +} + +#undef EVT_KEY_PREVIOUS_VIEW +#undef EVT_KEY_NEXT_VIEW diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index 73b71da62..a0cef2c1d 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -952,7 +952,7 @@ bool luaDoOneRunPermanentScript(event_t evt, int i, uint32_t scriptType) TelemetryScriptData & script = g_model.screens[sid.reference-SCRIPT_TELEMETRY_FIRST].script; filename = script.file; #endif - if ((scriptType & RUN_TELEM_FG_SCRIPT) && (menuHandlers[0]==menuViewTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view)) { + if ((scriptType & RUN_TELEM_FG_SCRIPT) && (menuHandlers[0]==menuViewTelemetry && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view)) { lua_rawgeti(lsScripts, LUA_REGISTRYINDEX, sid.run); lua_pushunsigned(lsScripts, evt); inputsCount = 1; From a2599da189620cc12333858a30f8b8ce0e8c0e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Charpentier?= Date: Tue, 11 Feb 2020 14:43:13 +0100 Subject: [PATCH 47/70] Updated French translation (#7372) --- companion/src/translations/companion_fr.ts | 182 +++++++++++---------- 1 file changed, 94 insertions(+), 88 deletions(-) diff --git a/companion/src/translations/companion_fr.ts b/companion/src/translations/companion_fr.ts index b4ff19c18..98fb5663a 100644 --- a/companion/src/translations/companion_fr.ts +++ b/companion/src/translations/companion_fr.ts @@ -728,58 +728,58 @@ Manche Droit: Profondeur, Direction Boards - + Left Horizontal Gauche Horizontal - + Left Vertical Gauche Vertical - + Right Vertical Droit Vertical - + Right Horizontal Droit Horizontal - + Aux. 1 - + Aux. 2 - - + + Unknown Inconnu - + Rud Dir - + Ele Prf - + Thr Gaz - + Ail @@ -2862,272 +2862,278 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Firmware - + Channel values displayed in us Positions de voies affichées en µs - + No OverrideCH functions available Désactive la fonction spéciale "Remplacer VOIExx" - + Possibility to enable FAI MODE (no telemetry) at field Possibilité d'activer le mode FAI (télémétrie désactivée) sur le terrain - + FAI MODE (no telemetry) always enabled Mode FAI (télémétrie toujours désactivée) - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 Masque le protocole D8. Légalement obligatoire sur les radios Européennes importées après le 1er janvier 2015 - - + + Disable HELI menu and cyclic mix support Supprimer le menu HELICO et les mixages cycliques - - + + Disable Global variables Supprimer le support des variables globales - - + + Enable Lua custom scripts screen Activer l'écran des scripts Lua personnalisés - + Support for PPM internal module hack Support du remplacement du module interne par un module PPM - + Use alternative SQT5 font Utiliser la police alternative SQT5 - + Disable RAS (SWR) Désactiver le RAS (SWR). Utile uniquement pour les X9D+ avec un RAS/SWR non fonctionnel - + Pots use in menus navigation Support de la navigation dans les menus avec les POTS - + FrSky Taranis X9D+ - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D - + Haptic module installed Module vibreur installé - + FrSky Taranis X9E - + Confirmation before radio shutdown Confirmation avant l'arrêt de la radio - + Horus gimbals installed (Hall sensors) Manches Horus à effet HALL installés - + FrSky Taranis X9-Lite - + FrSky Taranis X9-Lite S - + FrSky Taranis X7 / X7S - + FrSky Taranis X7 / X7S Access - + FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite - + FrSky Horus X10 / X10S - - + + Support for ACCESS internal module replacement Prise en charge du module de remplacement interne ACCESS - + FrSky Horus X10 Express / X10S Express - + FrSky Horus X12S - + Use ONLY with first DEV pcb version Exclusivement pour les Horus DEV - + Enable non certified R9M firmwares Activer les firmwares R9M non certifiés - - + + Support for MULTI internal module Prise en charge du module MULTI interne - + + Support for bluetooth module Prise en charge du module Bluetooth - + + Radiomaster TX16S + + + + Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support Activer le menu hélico et les mixages CCPM - + Global variables Variables globales - + Enable non certified firmwares Activer les firmwares non certifiés - + In model setup menus automatically set source by moving the control Sélectionner les sources des mixeurs en bougeant le contrôle désiré - + In model setup menus automatically set switch by moving the control Sélectionner les interrupteurs en bougeant le contrôle désiré - + No graphical check boxes and sliders Pas de cases à cocher et de curseurs graphiques - + Battery graph Graphique de la batterie - + Don't use bold font for highlighting active items Ne pas mettre les lignes actives en gras - + Turnigy 9XR with m128 chip Turnigy 9XR avec une puce m128 - + Turnigy 9XR - + 9X with stock board 9X avec carte mère d'origine - + Enable resetting values by pressing up and down at the same time Permet la remise à zéro des valeurs en pressant haut-bas en même temps, valeur min avec gauche/bas, valeur max avec haut/droite, inversion avec gauche/droite - + 9X with stock board and m128 chip Carte 9x avec un chip m128 - + 9X with AR9X board 9X avec carte AR9X - + Jumper T12 / T12 Pro - + Jumper T16 / T16+ / T16 Pro - + 9X with Sky9x board 9X avec carte Sky9x - + 9X with Gruvin9x board 9X avec carte Gruvin9x - + DIY MEGA2560 radio Radio DIY à base de MEGA2560 @@ -6035,8 +6041,8 @@ Les colonnes contenant l'altitude "GAlt" et la vitesse "GSpd - total duration - durée totale + time span + plage de temps @@ -9630,22 +9636,22 @@ Mixage actif par défaut si non-renseigné. OpenTxEepromInterface - + Unknown error Erreur inconnue - + ... plus %1 errors ... plus %1 erreurs - + Cannot write radio settings Impossible d'écrire les paramètres de la radio - + Cannot write model %1 Impossible d'écrire le modèle %1 @@ -11774,62 +11780,62 @@ La valeur par défaut est configurée dans le profil radio sélectionné.Simulateur Radio (%1) - + Could not determine startup data source. Impossible de déterminer les données source. - + Could not load data, possibly wrong format. Impossible de charger les données, mauvais format. - + Data Load Error Erreur de lecture des données - + Invalid startup data provided. Plese specify a proper file/path. Données de démarrage fournies non valides. Veuillez spécifier un fichier/chemin approprié. - + Simulator Startup Error Erreur de démarrage du simulateur - + Error saving data: could open file for writing: '%1' Erreur de sauvegarde des données: impossible d'écrire le fichier '%1' - + Error saving data: could not get data from simulator interface. Erreur de sauvegarde des données: impossible de récupérer les données depuis l'interface de simulation. - + An unexpected error occurred while attempting to save radio data to file '%1'. Une erreur inattendue s'est produite lors de l'enregistrement des données radio dans le fichier '%1'. - + Data Save Error Erreur de sauvegarde des données - + Cannot open joystick, joystick disabled Impossible d'accéder au Joystick, Joystick désactivé - + Radio firmware error: %1 Erreur firmware radio: %1 - + - Flight Mode %1 (#%2) - Phase de Vol %1 (#%2) From 0cbb8107af20b275d08308246cf7e00fc370f02d Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 12 Feb 2020 16:51:15 +0100 Subject: [PATCH 48/70] Add support for CRSF bat% (#7377) --- radio/src/telemetry/crossfire.cpp | 53 ++++++++++++++++--------------- radio/src/telemetry/crossfire.h | 1 + radio/src/translations/cz.h.txt | 1 + radio/src/translations/de.h.txt | 1 + radio/src/translations/en.h.txt | 1 + radio/src/translations/es.h.txt | 1 + radio/src/translations/fi.h.txt | 1 + radio/src/translations/fr.h.txt | 1 + radio/src/translations/it.h.txt | 1 + radio/src/translations/nl.h.txt | 1 + radio/src/translations/pl.h.txt | 1 + radio/src/translations/pt.h.txt | 1 + radio/src/translations/se.h.txt | 1 + 13 files changed, 40 insertions(+), 25 deletions(-) diff --git a/radio/src/telemetry/crossfire.cpp b/radio/src/telemetry/crossfire.cpp index b233583a4..724fbe1a0 100644 --- a/radio/src/telemetry/crossfire.cpp +++ b/radio/src/telemetry/crossfire.cpp @@ -21,31 +21,32 @@ #include "opentx.h" const CrossfireSensor crossfireSensors[] = { - {LINK_ID, 0, ZSTR_RX_RSSI1, UNIT_DB, 0}, - {LINK_ID, 1, ZSTR_RX_RSSI2, UNIT_DB, 0}, - {LINK_ID, 2, ZSTR_RX_QUALITY, UNIT_PERCENT, 0}, - {LINK_ID, 3, ZSTR_RX_SNR, UNIT_DB, 0}, - {LINK_ID, 4, ZSTR_ANTENNA, UNIT_RAW, 0}, - {LINK_ID, 5, ZSTR_RF_MODE, UNIT_RAW, 0}, - {LINK_ID, 6, ZSTR_TX_POWER, UNIT_MILLIWATTS, 0}, - {LINK_ID, 7, ZSTR_TX_RSSI, UNIT_DB, 0}, - {LINK_ID, 8, ZSTR_TX_QUALITY, UNIT_PERCENT, 0}, - {LINK_ID, 9, ZSTR_TX_SNR, UNIT_DB, 0}, - {BATTERY_ID, 0, ZSTR_BATT, UNIT_VOLTS, 1}, - {BATTERY_ID, 1, ZSTR_CURR, UNIT_AMPS, 1}, - {BATTERY_ID, 2, ZSTR_CAPACITY, UNIT_MAH, 0}, - {GPS_ID, 0, ZSTR_GPS, UNIT_GPS_LATITUDE, 0}, - {GPS_ID, 0, ZSTR_GPS, UNIT_GPS_LONGITUDE, 0}, - {GPS_ID, 2, ZSTR_GSPD, UNIT_KMH, 1}, - {GPS_ID, 3, ZSTR_HDG, UNIT_DEGREE, 3}, - {GPS_ID, 4, ZSTR_ALT, UNIT_METERS, 0}, - {GPS_ID, 5, ZSTR_SATELLITES, UNIT_RAW, 0}, - {ATTITUDE_ID, 0, ZSTR_PITCH, UNIT_RADIANS, 3}, - {ATTITUDE_ID, 1, ZSTR_ROLL, UNIT_RADIANS, 3}, - {ATTITUDE_ID, 2, ZSTR_YAW, UNIT_RADIANS, 3}, - {FLIGHT_MODE_ID, 0, ZSTR_FLIGHT_MODE, UNIT_TEXT, 0}, - {CF_VARIO_ID, 0, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 2}, - {0, 0, "UNKNOWN", UNIT_RAW, 0}, + {LINK_ID, 0, ZSTR_RX_RSSI1, UNIT_DB, 0}, + {LINK_ID, 1, ZSTR_RX_RSSI2, UNIT_DB, 0}, + {LINK_ID, 2, ZSTR_RX_QUALITY, UNIT_PERCENT, 0}, + {LINK_ID, 3, ZSTR_RX_SNR, UNIT_DB, 0}, + {LINK_ID, 4, ZSTR_ANTENNA, UNIT_RAW, 0}, + {LINK_ID, 5, ZSTR_RF_MODE, UNIT_RAW, 0}, + {LINK_ID, 6, ZSTR_TX_POWER, UNIT_MILLIWATTS, 0}, + {LINK_ID, 7, ZSTR_TX_RSSI, UNIT_DB, 0}, + {LINK_ID, 8, ZSTR_TX_QUALITY, UNIT_PERCENT, 0}, + {LINK_ID, 9, ZSTR_TX_SNR, UNIT_DB, 0}, + {BATTERY_ID, 0, ZSTR_BATT, UNIT_VOLTS, 1}, + {BATTERY_ID, 1, ZSTR_CURR, UNIT_AMPS, 1}, + {BATTERY_ID, 2, ZSTR_CAPACITY, UNIT_MAH, 0}, + {BATTERY_ID, 3, ZSTR_BATT_PERCENT, UNIT_PERCENT, 0}, + {GPS_ID, 0, ZSTR_GPS, UNIT_GPS_LATITUDE, 0}, + {GPS_ID, 0, ZSTR_GPS, UNIT_GPS_LONGITUDE, 0}, + {GPS_ID, 2, ZSTR_GSPD, UNIT_KMH, 1}, + {GPS_ID, 3, ZSTR_HDG, UNIT_DEGREE, 3}, + {GPS_ID, 4, ZSTR_ALT, UNIT_METERS, 0}, + {GPS_ID, 5, ZSTR_SATELLITES, UNIT_RAW, 0}, + {ATTITUDE_ID, 0, ZSTR_PITCH, UNIT_RADIANS, 3}, + {ATTITUDE_ID, 1, ZSTR_ROLL, UNIT_RADIANS, 3}, + {ATTITUDE_ID, 2, ZSTR_YAW, UNIT_RADIANS, 3}, + {FLIGHT_MODE_ID, 0, ZSTR_FLIGHT_MODE, UNIT_TEXT, 0}, + {CF_VARIO_ID, 0, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 2}, + {0, 0, "UNKNOWN", UNIT_RAW, 0}, }; const CrossfireSensor & getCrossfireSensor(uint8_t id, uint8_t subId) @@ -157,6 +158,8 @@ void processCrossfireTelemetryFrame() processCrossfireTelemetryValue(BATT_CURRENT_INDEX, value); if (getCrossfireTelemetryValue<3>(7, value)) processCrossfireTelemetryValue(BATT_CAPACITY_INDEX, value); + if (getCrossfireTelemetryValue<1>(10, value)) + processCrossfireTelemetryValue(BATT_REMAINING_INDEX, value); break; case ATTITUDE_ID: diff --git a/radio/src/telemetry/crossfire.h b/radio/src/telemetry/crossfire.h index 3daed0d57..79cc5f025 100644 --- a/radio/src/telemetry/crossfire.h +++ b/radio/src/telemetry/crossfire.h @@ -64,6 +64,7 @@ enum CrossfireSensorIndexes { BATT_VOLTAGE_INDEX, BATT_CURRENT_INDEX, BATT_CAPACITY_INDEX, + BATT_REMAINING_INDEX, GPS_LATITUDE_INDEX, GPS_LONGITUDE_INDEX, GPS_GROUND_SPEED_INDEX, diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index fe2f4a921..2244f2fe9 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -1199,6 +1199,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 1cfef0aef..98fd1df8e 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -1205,6 +1205,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 9ab4f8725..7620e6bf3 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -1203,6 +1203,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 3d7a70d43..1b5b7c096 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -1224,6 +1224,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 241e4fdcb..6bafcb221 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -1212,6 +1212,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 88fa0689f..55548862c 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -1227,6 +1227,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 0f5e5b047..b5feb04b8 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -1221,6 +1221,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index e67be0298..d28dcbca8 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -1213,6 +1213,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index a52b0da24..dc6a86aac 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -1220,6 +1220,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 2d4d6fc71..7b77891c6 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -1209,6 +1209,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 85b31e4d9..8639b0378 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -1220,6 +1220,7 @@ #define ZSTR_CURR "Curr" #define ZSTR_CAPACITY "Capa" #define ZSTR_VFAS "VFAS" +#define ZSTR_BATT_PERCENT "Bat%" #define ZSTR_ASPD "ASpd" #define ZSTR_GSPD "GSpd" #define ZSTR_HDG "Hdg" From f40264b6582d83ebe28129616fba2323f09ee0da Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 12 Feb 2020 16:53:21 +0100 Subject: [PATCH 49/70] Remove redundant code/feature (#7368) Remove redundant code/feature --- radio/src/gui/480x272/menus.h | 3 -- radio/src/gui/480x272/radio_diaganas.cpp | 14 ++++++-- radio/src/gui/480x272/view_statistics.cpp | 39 ----------------------- radio/src/opentx.h | 4 +-- 4 files changed, 13 insertions(+), 47 deletions(-) diff --git a/radio/src/gui/480x272/menus.h b/radio/src/gui/480x272/menus.h index 37e33a58f..cefa95378 100644 --- a/radio/src/gui/480x272/menus.h +++ b/radio/src/gui/480x272/menus.h @@ -151,7 +151,6 @@ const uint8_t STATS_ICONS[] = { ICON_STATS, ICON_STATS_THROTTLE_GRAPH, ICON_STATS_DEBUG, - ICON_STATS_ANALOGS, #if defined(DEBUG_TRACE_BUFFER) ICON_STATS_TIMERS #endif @@ -240,13 +239,11 @@ enum MenuRadioIndexes bool menuStatsGraph(event_t event); bool menuStatsDebug(event_t event); -bool menuStatsAnalogs(event_t event); bool menuStatsTraces(event_t event); static const MenuHandlerFunc menuTabStats[] = { menuStatsGraph, menuStatsDebug, - menuStatsAnalogs, #if defined(DEBUG_TRACE_BUFFER) menuStatsTraces, #endif diff --git a/radio/src/gui/480x272/radio_diaganas.cpp b/radio/src/gui/480x272/radio_diaganas.cpp index 37d16f2f7..2892457dc 100644 --- a/radio/src/gui/480x272/radio_diaganas.cpp +++ b/radio/src/gui/480x272/radio_diaganas.cpp @@ -29,7 +29,7 @@ bool menuRadioDiagAnalogs(event_t event) { SIMPLE_SUBMENU(STR_MENU_RADIO_ANALOGS, ICON_MODEL_SETUP, 0); - for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) { + for (uint8_t i = 0; i < NUM_ANALOGS; i++) { coord_t y = MENU_HEADER_HEIGHT + 1 + (i / 2) * FH; uint8_t x = i & 1 ? LCD_W / 2 + 10 : LEFT_NAME_COLUMN; lcdDrawNumber(x, y, i + 1, LEADING0 | LEFT, 2); @@ -40,7 +40,12 @@ bool menuRadioDiagAnalogs(event_t event) lcdDrawNumber(x + ANA_OFFSET + 30 - 1, y, avgJitter[i].get(), RIGHT); lcdDrawNumber(x + ANA_OFFSET + 70 - 1, y, (int16_t) calibratedAnalogs[CONVERT_MODE(i)] * 25 / 256, RIGHT); #else - lcdDrawNumber(x + ANA_OFFSET - 1, y, (int16_t) calibratedAnalogs[CONVERT_MODE(i)] * 25 / 256, RIGHT); + if (i < NUM_STICKS + NUM_POTS + NUM_SLIDERS) + lcdDrawNumber(x + ANA_OFFSET - 1, y, (int16_t) calibratedAnalogs[CONVERT_MODE(i)] * 25 / 256, RIGHT); +#if NUM_MOUSE_ANALOGS > 0 + else if (i >= MOUSE1) + lcdDrawNumber(x + ANA_OFFSET - 1, y, (int16_t) calibratedAnalogs[CALIBRATED_MOUSE1 + i - MOUSE1] * 25 / 256, RIGHT); +#endif #endif } @@ -51,5 +56,10 @@ bool menuRadioDiagAnalogs(event_t event) lcdDrawText(LCD_W / 2, RAS_TOP_POSITION, "XJTVER : "); lcdDrawNumber(lcdNextPos, RAS_TOP_POSITION, telemetryData.xjtVersion, 0); } + +#if (NUM_PWMSTICKS > 0) && !defined(SIMU) + lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + 8 * FH, STICKS_PWM_ENABLED() ? "Sticks: PWM" : "Sticks: ANA"); +#endif + return true; } diff --git a/radio/src/gui/480x272/view_statistics.cpp b/radio/src/gui/480x272/view_statistics.cpp index c13dff60e..34eb9b0c2 100644 --- a/radio/src/gui/480x272/view_statistics.cpp +++ b/radio/src/gui/480x272/view_statistics.cpp @@ -188,45 +188,6 @@ bool menuStatsDebug(event_t event) return true; } -bool menuStatsAnalogs(event_t event) -{ - SIMPLE_MENU("Analogs", STATS_ICONS, menuTabStats, e_StatsAnalogs, 1); - - for (uint8_t i=0; i 0 - else if (i >= MOUSE1) - lcdDrawNumber(x+100, y, (int16_t)calibratedAnalogs[CALIBRATED_MOUSE1+i-MOUSE1]*25/256); -#endif -#endif - } - - // RAS - if ((isModuleXJT(INTERNAL_MODULE) && IS_INTERNAL_MODULE_ON()) || (isModulePXX1(EXTERNAL_MODULE) && !IS_INTERNAL_MODULE_ON())) { - lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+7*FH, "RAS"); - lcdDrawNumber(MENUS_MARGIN_LEFT+100, MENU_CONTENT_TOP+7*FH, telemetryData.swrInternal.value()); - lcdDrawText(MENUS_MARGIN_LEFT + LCD_W/2, MENU_CONTENT_TOP+7*FH, "XJTVER"); - lcdDrawNumber(LCD_W/2 + MENUS_MARGIN_LEFT+100, MENU_CONTENT_TOP+7*FH, telemetryData.xjtVersion); - } - -#if (NUM_PWMSTICKS > 0) && !defined(SIMU) - lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+8*FH, STICKS_PWM_ENABLED() ? "Sticks: PWM" : "Sticks: ANA"); -#endif - - return true; -} - - #if defined(DEBUG_TRACE_BUFFER) #define STATS_TRACES_INDEX_POS MENUS_MARGIN_LEFT #define STATS_TRACES_TIME_POS MENUS_MARGIN_LEFT + 4*10 diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 0ef8b04c9..cac27516d 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1366,9 +1366,7 @@ extern uint16_t s_anaFilt[NUM_ANALOGS]; #if defined(JITTER_MEASURE) extern JitterMeter rawJitter[NUM_ANALOGS]; extern JitterMeter avgJitter[NUM_ANALOGS]; -#if defined(PCBHORUS) - #define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuStatsAnalogs) -#elif defined(PCBTARANIS) +#if defined(PCBHORUS) || defined(PCBTARANIS) #define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuRadioDiagAnalogs) #elif defined(CLI) #define JITTER_MEASURE_ACTIVE() (1) From e8ccd39113efa9d54358c17e2fb07e766adaaa71 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sat, 15 Feb 2020 17:47:00 +0100 Subject: [PATCH 50/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 804ab0846..5dae08514 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1699,3 +1699,4 @@ Jonathan Starch Coolwind Benoit Pichereau Darko Perković +Burt Pickard-Richardson From c2e5e4f566254e10a2ced37275bcac07aeb14d87 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 17 Feb 2020 15:01:39 +0100 Subject: [PATCH 51/70] No "Execute" function if LUA not defined on Horus --- radio/src/gui/480x272/radio_sdmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/radio/src/gui/480x272/radio_sdmanager.cpp b/radio/src/gui/480x272/radio_sdmanager.cpp index d4da41e3b..9a44203a5 100644 --- a/radio/src/gui/480x272/radio_sdmanager.cpp +++ b/radio/src/gui/480x272/radio_sdmanager.cpp @@ -337,9 +337,11 @@ bool menuRadioSdManager(event_t _event) } #endif +#if defined(LUA) if (isExtensionMatching(ext, SCRIPTS_EXT)) { POPUP_MENU_ADD_ITEM(STR_EXECUTE_FILE); } +#endif if (isExtensionMatching(ext, TEXT_EXT) || isExtensionMatching(ext, SCRIPTS_EXT)) { POPUP_MENU_ADD_ITEM(STR_VIEW_TEXT); From 18b5fbf33e6dfb3dce84ef8c1fb228eac5d20b23 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 18 Feb 2020 11:11:52 +0100 Subject: [PATCH 52/70] Add copy min/max to outputs (#7396) * Add copy min/max to outputs * Also copy ppm center --- radio/src/gui/128x64/model_outputs.cpp | 4 ++++ radio/src/gui/212x64/model_outputs.cpp | 4 ++++ radio/src/gui/480x272/model_outputs.cpp | 4 ++++ radio/src/opentx.cpp | 19 +++++++++++++++++++ radio/src/opentx.h | 1 + radio/src/translations.cpp | 1 + radio/src/translations.h | 1 + radio/src/translations/cz.h.txt | 1 + radio/src/translations/de.h.txt | 1 + radio/src/translations/en.h.txt | 1 + radio/src/translations/es.h.txt | 1 + radio/src/translations/fi.h.txt | 1 + radio/src/translations/fr.h.txt | 1 + radio/src/translations/it.h.txt | 1 + radio/src/translations/nl.h.txt | 1 + radio/src/translations/pl.h.txt | 1 + radio/src/translations/pt.h.txt | 1 + radio/src/translations/se.h.txt | 1 + 18 files changed, 45 insertions(+) diff --git a/radio/src/gui/128x64/model_outputs.cpp b/radio/src/gui/128x64/model_outputs.cpp index a069e2362..0fde67159 100644 --- a/radio/src/gui/128x64/model_outputs.cpp +++ b/radio/src/gui/128x64/model_outputs.cpp @@ -215,6 +215,9 @@ void onLimitsMenu(const char *result) else if (result == STR_EDIT) { pushMenu(menuModelLimitsOne); } + else if (result == STR_COPY_MIN_MAX_TO_OUTPUTS) { + copyMinMaxToOutputs(s_currIdx); + } } void menuModelLimits(event_t event) @@ -240,6 +243,7 @@ void menuModelLimits(event_t event) POPUP_MENU_ADD_ITEM(STR_RESET); POPUP_MENU_ADD_ITEM(STR_COPY_TRIMS_TO_OFS); POPUP_MENU_ADD_ITEM(STR_COPY_STICKS_TO_OFS); + POPUP_MENU_ADD_ITEM(STR_COPY_MIN_MAX_TO_OUTPUTS); POPUP_MENU_START(onLimitsMenu); } diff --git a/radio/src/gui/212x64/model_outputs.cpp b/radio/src/gui/212x64/model_outputs.cpp index f3f776285..c1cd1de04 100644 --- a/radio/src/gui/212x64/model_outputs.cpp +++ b/radio/src/gui/212x64/model_outputs.cpp @@ -86,6 +86,9 @@ void onLimitsMenu(const char *result) copyTrimsToOffset(ch); storageDirty(EE_MODEL); } + else if (result == STR_COPY_MIN_MAX_TO_OUTPUTS) { + copyMinMaxToOutputs(ch); + } } void menuModelLimits(event_t event) @@ -142,6 +145,7 @@ void menuModelLimits(event_t event) POPUP_MENU_ADD_ITEM(STR_RESET); POPUP_MENU_ADD_ITEM(STR_COPY_TRIMS_TO_OFS); POPUP_MENU_ADD_ITEM(STR_COPY_STICKS_TO_OFS); + POPUP_MENU_ADD_ITEM(STR_COPY_MIN_MAX_TO_OUTPUTS); POPUP_MENU_START(onLimitsMenu); } diff --git a/radio/src/gui/480x272/model_outputs.cpp b/radio/src/gui/480x272/model_outputs.cpp index af5128fd7..3dd2d8f21 100644 --- a/radio/src/gui/480x272/model_outputs.cpp +++ b/radio/src/gui/480x272/model_outputs.cpp @@ -80,6 +80,9 @@ void onLimitsMenu(const char *result) copyTrimsToOffset(ch); storageDirty(EE_MODEL); } + else if (result == STR_COPY_MIN_MAX_TO_OUTPUTS) { + copyMinMaxToOutputs(ch); + } } bool menuModelLimits(event_t event) @@ -133,6 +136,7 @@ bool menuModelLimits(event_t event) POPUP_MENU_ADD_ITEM(STR_RESET); POPUP_MENU_ADD_ITEM(STR_COPY_TRIMS_TO_OFS); POPUP_MENU_ADD_ITEM(STR_COPY_STICKS_TO_OFS); + POPUP_MENU_ADD_ITEM(STR_COPY_MIN_MAX_TO_OUTPUTS); POPUP_MENU_START(onLimitsMenu); } diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 1bf9e8342..258eb74f8 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1725,6 +1725,25 @@ void copyTrimsToOffset(uint8_t ch) storageDirty(EE_MODEL); } +void copyMinMaxToOutputs(uint8_t ch) +{ + LimitData *ld = limitAddress(ch); + int16_t min = ld->min; + int16_t max = ld->max; + int16_t center = ld->ppmCenter; + + pauseMixerCalculations(); + + for (uint8_t chan = 0; chan < MAX_OUTPUT_CHANNELS; chan++) { + ld = limitAddress(chan); + ld->min = min; + ld->max = max; + ld->ppmCenter = center; + } + + resumeMixerCalculations(); + storageDirty(EE_MODEL); +} #if defined(STARTUP_ANIMATION) diff --git a/radio/src/opentx.h b/radio/src/opentx.h index cac27516d..8a8ea96a9 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -867,6 +867,7 @@ void instantTrim(); void evalTrims(); void copyTrimsToOffset(uint8_t ch); void copySticksToOffset(uint8_t ch); +void copyMinMaxToOutputs(uint8_t ch); void moveTrimsToOffsets(); typedef uint16_t ACTIVE_PHASES_TYPE; diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 8e333fcc4..1dfb9a692 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -536,6 +536,7 @@ const char STR_PT[] = TR_PT; const char STR_PTS[] = TR_PTS; const char STR_SMOOTH[] = TR_SMOOTH; const char STR_COPY_STICKS_TO_OFS[] = TR_COPY_STICKS_TO_OFS; +const char STR_COPY_MIN_MAX_TO_OUTPUTS[] = TR_COPY_MIN_MAX_TO_OUTPUTS; const char STR_COPY_TRIMS_TO_OFS[] = TR_COPY_TRIMS_TO_OFS; const char STR_INCDEC[] = TR_INCDEC; const char STR_GLOBALVAR[] = TR_GLOBALVAR; diff --git a/radio/src/translations.h b/radio/src/translations.h index 239fd7c71..df0cfd67d 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -821,6 +821,7 @@ extern const char STR_PT[]; extern const char STR_PTS[]; extern const char STR_SMOOTH[]; extern const char STR_COPY_STICKS_TO_OFS[]; +extern const char STR_COPY_MIN_MAX_TO_OUTPUTS[]; extern const char STR_COPY_TRIMS_TO_OFS[]; extern const char STR_INCDEC[]; extern const char STR_GLOBALVAR[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 2244f2fe9..cdcf5ae13 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -962,6 +962,7 @@ #define TR_PTS " b." #define TR_SMOOTH "Hladká" #define TR_COPY_STICKS_TO_OFS TR("Páky do subtrimu", "Kopie pák do subtrimu") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Trimy do subtrimu", "Kopíe trimů do subtrimu") #define TR_INCDEC "Zvěšit/Zmenšit" #define TR_GLOBALVAR "Glob. proměnná" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 98fd1df8e..effe773d7 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -968,6 +968,7 @@ #define TR_PTS "Pts" #define TR_SMOOTH "Runden" #define TR_COPY_STICKS_TO_OFS TR("Copy Stk ->Subtrim", "Kopie Stick to Servo-Mitte") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Copy Trim->Subtrim", "Kopie Trimm to Servo-Mitte") // "Trim to Subtrim" #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Global Var" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 7620e6bf3..f37006215 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -967,6 +967,7 @@ #define TR_PTS "pts" #define TR_SMOOTH "Smooth" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Copy sticks to subtrim") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Copy trims to subtrim") #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Global var" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 1b5b7c096..c1ae1f49c 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -987,6 +987,7 @@ #define TR_PTS "pts" #define TR_SMOOTH "Smooth" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Copy Sticks To Offset") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Copy trims to subtrim") #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Global Var" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 6bafcb221..839269089 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -981,6 +981,7 @@ #define TR_PTS "pts" #define TR_SMOOTH "Smooth" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Copy Sticks To Offset") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Copy trims to subtrim") #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Global Var" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 55548862c..2e6eb35df 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -983,6 +983,7 @@ #define TR_PTS "pts" #define TR_SMOOTH "Lissage" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Manche vers subtrim") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Trim vers subtrim") #define TR_INCDEC "Inc/décrementer" #define TR_GLOBALVAR "Var. globale" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index b5feb04b8..2125f0189 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -983,6 +983,7 @@ #define TR_PTS "pti" #define TR_SMOOTH "Smussa" #define TR_COPY_STICKS_TO_OFS TR(INDENT "Cp. stick->subtrim", INDENT "Copia Sticks su Subtrim") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR(INDENT "Cp. trim->subtrim", INDENT "Copia Trims su Subtrim") #define TR_INCDEC "Inc/Decrementa" #define TR_GLOBALVAR "Var Globale" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index d28dcbca8..6e3388f4c 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -969,6 +969,7 @@ #define TR_PTS "Ptn" #define TR_SMOOTH "Zacht" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Kopieer Sticks naar Subtrim") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Kopieer Trim naar Subtrim") #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Globale Var" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index dc6a86aac..2fe3c84a3 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -982,6 +982,7 @@ #define TR_PTS "pkty" #define TR_SMOOTH "Gładka" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Skopiuj Drążki Do Offsetu") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Skopiuj Trymery Do subtrymerów") #define TR_INCDEC "Zwiększ/Zmnie" #define TR_GLOBALVAR "Zm.Global." diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 7b77891c6..33b3568e2 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -972,6 +972,7 @@ #define TR_PTS "pts" #define TR_SMOOTH "Smooth" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Copy Sticks To Offset") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Copy trims to subtrim") #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Global Var" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 8639b0378..8bbb15270 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -982,6 +982,7 @@ #define TR_PTS "pkt" #define TR_SMOOTH "Mjuk" #define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Spara spakar som subtrim") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") #define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Spara trimmar som subtrim") #define TR_INCDEC "Inkr/Dekrement" #define TR_GLOBALVAR "Globala Var" From f6075b3c0bceb28471136bf9610252cf213102d2 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 18 Feb 2020 11:26:37 +0100 Subject: [PATCH 53/70] Fix X9E RTC batt voltage readout (#7382) --- radio/src/targets/common/arm/stm32/adc_driver.cpp | 4 ++-- radio/src/targets/taranis/hal.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index b4c72e46c..3972ab86c 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -30,9 +30,9 @@ const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,1, 1, -1}; #elif defined(PCBX9E) #if defined(HORUS_STICKS) - const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,-1, -1,-1,-1}; + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; #else - const int8_t adcDirection[NUM_ANALOGS] = {1,1,-1,-1, -1,-1,-1,1, -1,1,-1, -1,-1,-1}; + const int8_t adcDirection[NUM_ANALOGS] = {1,1,-1,-1, -1,-1,-1,1, -1,1,1, -1,-1,-1}; #endif const uint8_t adcMapping[NUM_ANALOGS] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/, 11 /*POT1*/, 4 /*POT2*/, 5 /*POT3*/, 6 /*POT4*/, diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 645ebe327..b8d1c7177 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -754,7 +754,7 @@ #define ADC_EXT_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_EXT_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) #define ADC_EXT_SAMPTIME 3 // sample time = 56 cycles - #define ADC_VREF_PREC2 200 + #define ADC_VREF_PREC2 300 #elif defined(PCBX9DP) #define HARDWARE_POT1 #define HARDWARE_POT2 From a4125582f137a57b5617f884e8ef1c7f4a640c3d Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 18 Feb 2020 12:42:24 +0100 Subject: [PATCH 54/70] Improve textView on colorlcd (#7395) --- radio/src/gui/480x272/bitmapbuffer.h | 18 ++++++++++++++++++ radio/src/gui/480x272/lcd.h | 7 ------- radio/src/gui/480x272/view_text.cpp | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/radio/src/gui/480x272/bitmapbuffer.h b/radio/src/gui/480x272/bitmapbuffer.h index 760215198..b9cdc0381 100644 --- a/radio/src/gui/480x272/bitmapbuffer.h +++ b/radio/src/gui/480x272/bitmapbuffer.h @@ -41,6 +41,14 @@ typedef int coord_t; typedef uint32_t LcdFlags; typedef uint16_t display_t; +int getTextWidth(const char * s, int len=0, LcdFlags flags=0); + +#if LCD_W >= 480 +#define LCD_COLS 80 +#else +#define LCD_COLS 30 +#endif + enum BitmapFormats { BMP_RGB565, @@ -275,6 +283,16 @@ class BitmapBuffer: public BitmapBufferBase uint8_t drawCharWithCache(coord_t x, coord_t y, const BitmapBuffer * font, const uint16_t * spec, int index, LcdFlags flags); + void drawTextMaxWidth(coord_t x, coord_t y, const char * s, LcdFlags flags, coord_t maxWidth) + { + for (int col = LCD_COLS; col > 0; col--) { + if (getTextWidth(s, col, flags) <= maxWidth) { + drawSizedText(x, y, s, col, flags); + return; + } + } + } + void drawText(coord_t x, coord_t y, const char * s, LcdFlags flags) { drawSizedText(x, y, s, 255, flags); diff --git a/radio/src/gui/480x272/lcd.h b/radio/src/gui/480x272/lcd.h index c66865d85..dfb42e829 100644 --- a/radio/src/gui/480x272/lcd.h +++ b/radio/src/gui/480x272/lcd.h @@ -24,12 +24,6 @@ #include "bitmapbuffer.h" #include "opentx_types.h" -#if LCD_W >= 480 - #define LCD_COLS 40 -#else - #define LCD_COLS 30 -#endif - #define CENTER /* lcd common flags */ @@ -254,7 +248,6 @@ inline int getBitmapHeight(const uint8_t * bmp) uint8_t getMappedChar(uint8_t c); uint8_t getFontHeight(LcdFlags flags); -int getTextWidth(const char * s, int len=0, LcdFlags flags=0); inline void lcdDrawBitmapPattern(coord_t x, coord_t y, const uint8_t * img, LcdFlags flags=0, coord_t offset=0, coord_t width=0) { diff --git a/radio/src/gui/480x272/view_text.cpp b/radio/src/gui/480x272/view_text.cpp index 3038887bf..a7969d21f 100644 --- a/radio/src/gui/480x272/view_text.cpp +++ b/radio/src/gui/480x272/view_text.cpp @@ -56,7 +56,7 @@ bool menuTextView(event_t event) } for (int i=0; idrawTextMaxWidth(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + i * FH, reusableBuffer.viewText.lines[i], 0, LCD_W - 2 * MENUS_MARGIN_LEFT); } #if 0 From c8eab1a31abca61ea9ee276f482deb9d531d5138 Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 19 Feb 2020 09:34:36 +0100 Subject: [PATCH 55/70] Improve spannish TTS. This fixes #7398 --- radio/util/tts_es.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/radio/util/tts_es.py b/radio/util/tts_es.py index 3b436ecd6..01d28d3dd 100755 --- a/radio/util/tts_es.py +++ b/radio/util/tts_es.py @@ -70,6 +70,7 @@ for s, f in [("me tienes abandonada", "inactiv"), ("A1 crítica", "a1_red"), ("Alarma A2", "a2_org"), ("A2 crítica", "a2_red"), + ("Bienvenido a open t equis", "hello"), ("recepcion de señal baja", "rssi_org"), ("recepción de señal crítica", "rssi_red"), ("Problemas con la antena del transmisor", "swr_red"), @@ -77,7 +78,7 @@ for s, f in [("me tienes abandonada", "inactiv"), ("Telemetría disponible", "telemok"), ("servo overload", "servoko"), ("power overload", "rxko"), - ("receiver still connected", "modelpwr"), + ("El receptor esta conectado", "modelpwr"), ]: systemSounds.append((s, filename(f))) for i, s in enumerate(["cronómetro", "cronómetro", "transmisión", "recepción", "A1", "A2", "altitud", "motor", From dea4800da33f8a0f13ad81d7d0dfd16145a3ff01 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 20 Feb 2020 09:04:50 +0100 Subject: [PATCH 56/70] Allow range check for LR12 with 212 GUI (#7394) --- radio/src/gui/212x64/model_setup.cpp | 2 +- radio/src/pulses/modules_helpers.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 2d90d70da..e73c2938e 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -353,7 +353,7 @@ void menuModelSetup(event_t event) LABEL(InternalModule), INTERNAL_MODULE_TYPE_ROWS, MODULE_CHANNELS_ROWS(INTERNAL_MODULE), - IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleFailsafeAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1)), + IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleRangeAvailable(INTERNAL_MODULE)? (uint8_t)2 : (uint8_t)1)), // RxNum, Range check and Register buttons IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // RxNum for ACCESS IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), // Failsafe IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 1), // Range check and Register buttons diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index 1f1f30fbe..4d358c36b 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -421,6 +421,11 @@ inline bool isModuleBindRangeAvailable(uint8_t moduleIdx) return isModulePXX2(moduleIdx) || isModulePXX1(moduleIdx) || isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx); } +inline bool isModuleRangeAvailable(uint8_t moduleIdx) +{ + return isModuleXJTD16(moduleIdx) || isModuleXJTLR12(moduleIdx); +} + constexpr uint8_t MAX_RXNUM = 63; inline uint8_t getMaxRxNum(uint8_t idx) From 88b756ac1d6b5d6b14da467fd921939f11bb53cb Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 20 Feb 2020 09:21:20 +0100 Subject: [PATCH 57/70] Bring back RAS to Horus (#7392) --- radio/src/telemetry/frsky.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/radio/src/telemetry/frsky.h b/radio/src/telemetry/frsky.h index e99c0f237..458a4901f 100644 --- a/radio/src/telemetry/frsky.h +++ b/radio/src/telemetry/frsky.h @@ -282,16 +282,16 @@ inline bool isRasValueValid() { return true; } -#elif defined(PCBX10) -inline bool isRasValueValid() -{ - return false; -} #elif defined(PCBX9DP) || defined(PCBX9E) inline bool isRasValueValid() { return telemetryData.xjtVersion != 0x0000 && telemetryData.xjtVersion != 0x00FF; } +#elif defined(PCBHORUS) +inline bool isRasValueValid() +{ + return true; +} #else inline bool isRasValueValid() { From 61bde526cceb7a73d8c58f2db3b61633ff96efca Mon Sep 17 00:00:00 2001 From: olliw42 <6089567+olliw42@users.noreply.github.com> Date: Thu, 20 Feb 2020 09:25:09 +0100 Subject: [PATCH 58/70] Add color option to luaLcdDrawPoint() (#7386) Add color option to luaLcdDrawPoint() --- radio/src/lua/api_lcd.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/radio/src/lua/api_lcd.cpp b/radio/src/lua/api_lcd.cpp index 039aa5547..e42a5f1cc 100644 --- a/radio/src/lua/api_lcd.cpp +++ b/radio/src/lua/api_lcd.cpp @@ -71,6 +71,8 @@ Draw a single pixel at (x,y) position @param y (positive number) y position +@param flags (unsigned number) drawing flags + @notice Taranis has an LCD display width of 212 pixels and height of 64 pixels. Position (0,0) is at top left. Y axis is negative, top line is 0, bottom line is 63. Drawing on an existing black pixel produces white pixel (TODO check this!) @@ -82,7 +84,8 @@ static int luaLcdDrawPoint(lua_State *L) if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); - lcdDrawPoint(x, y); + LcdFlags att = luaL_optunsigned(L, 3, 0); + lcdDrawPoint(x, y, att); return 0; } From 262fc12d5e543ae2d2a611fc647602aa31797972 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 20 Feb 2020 09:34:17 +0100 Subject: [PATCH 59/70] Cosmetics --- radio/src/lua/api_lcd.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/radio/src/lua/api_lcd.cpp b/radio/src/lua/api_lcd.cpp index e42a5f1cc..9acd475e0 100644 --- a/radio/src/lua/api_lcd.cpp +++ b/radio/src/lua/api_lcd.cpp @@ -98,14 +98,14 @@ Draw a straight line on LCD @param x2,y2 (positive numbers) end coordinate -@param pattern TODO +@param pattern SOLID or DOTTED -@param flags TODO +@param flags lcdflags @notice If the start or the end of the line is outside the LCD dimensions, then the whole line will not be drawn (starting from OpenTX 2.1.5) -@status current Introduced in 2.0.0 +@status current Introduced in 2.0.0, flags introduced in 2.3.6 */ static int luaLcdDrawLine(lua_State *L) { From c4a6f55600e77adc8d4581efbe896c1d3c169a48 Mon Sep 17 00:00:00 2001 From: 3djc Date: Thu, 20 Feb 2020 09:49:45 +0100 Subject: [PATCH 60/70] Cosmetics --- radio/src/lua/api_lcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/lua/api_lcd.cpp b/radio/src/lua/api_lcd.cpp index 9acd475e0..3c2b32638 100644 --- a/radio/src/lua/api_lcd.cpp +++ b/radio/src/lua/api_lcd.cpp @@ -71,7 +71,7 @@ Draw a single pixel at (x,y) position @param y (positive number) y position -@param flags (unsigned number) drawing flags +@param flags (optional) lcdflags @notice Taranis has an LCD display width of 212 pixels and height of 64 pixels. Position (0,0) is at top left. Y axis is negative, top line is 0, From 33ff85dbd40e9cbf25925a0a746b5146a088326d Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 24 Feb 2020 09:20:32 +0100 Subject: [PATCH 61/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 5dae08514..66a04772f 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1700,3 +1700,4 @@ Coolwind Benoit Pichereau Darko Perković Burt Pickard-Richardson +Roland Nittby From 3f49af7e6debafd76b45b1ff088c7b4693b8ae82 Mon Sep 17 00:00:00 2001 From: jessyjames Date: Mon, 24 Feb 2020 10:54:17 +0100 Subject: [PATCH 62/70] Some translation (#7409) --- radio/src/translations/de.h.txt | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index effe773d7..24c37b13e 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -645,15 +645,15 @@ #define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") #define TR_MODULE_WAITFORBIND "Bind to load protocol" #define TR_MODULE_BINDING "Binding" -#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Module\nUpgrade required") -#define TR_MODULE_UPGRADE TR("Upg. advised", "Module update recommended") +#define TR_MODULE_UPGRADE_ALERT TR3("Upg. needed", "Module upgrade required", "Modul\nUpdate nötig") +#define TR_MODULE_UPGRADE TR("Upg. advised", "Modulupdate empfohlen") #define TR_REBIND "Rebinding required" #define TR_REG_OK "Registration ok" #define TR_BIND_OK "Bind successful" -#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON" -#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF" -#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON" -#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" +#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem AN" +#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem AUS" +#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem AN" +#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem AUS" #define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") #define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status") @@ -677,18 +677,18 @@ #define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spannungsquelle") //9XR-Pro #define TR_CURRENT TR(INDENT "Strom", INDENT "Stromquelle") #define TR_SELECT_MODEL "Modell auswählen" -#define TR_CREATE_CATEGORY "Modelltyp erzeugen" +#define TR_CREATE_CATEGORY "Modelltyp erstellen" #define TR_RENAME_CATEGORY "Modelltyp umbenennen" #define TR_DELETE_CATEGORY "Modelltyp löschen" -#define TR_CREATE_MODEL "Neues Modell" +#define TR_CREATE_MODEL TR("Neues Modell" , "Neues Modell erstellen") #define TR_DUPLICATE_MODEL "Kopiere Modell" #define TR_COPY_MODEL "Kopiere Modell" #define TR_MOVE_MODEL "Verschiebe Modell" #define TR_BACKUP_MODEL "Modell auf SD-Karte" //9XR-Pro -#define TR_DELETE_MODEL "Modell löschen" // TODO merged into DELETEMODEL? +#define TR_DELETE_MODEL "Lösche Modell" // TODO merged into DELETEMODEL? #define TR_RESTORE_MODEL TR("Modell wiederher.", "Modell wiederherstellen") -#define TR_DELETE_ERROR "Fehler beim Löschen" -#define TR_CAT_NOT_EMPTY "Kategorie nicht leer" +#define TR_DELETE_ERROR "Fehler beim\nLöschen" +#define TR_CAT_NOT_EMPTY "Modelltyp nicht leer" #define TR_SDCARD_ERROR "SD-Kartenfehler" #define TR_NO_SDCARD "Keine SD-Karte" #define TR_WAITING_FOR_RX "Waiting for RX..." @@ -820,19 +820,19 @@ #define TR_MIXERS_MONITOR "==>Mischer Monitor" #define TR_PATH_TOO_LONG "Pfad zu Lang" #define TR_VIEW_TEXT "View Text" -#define TR_FLASH_BOOTLOADER TR("Flash bootloader","Flash bootloader selbst") // +#define TR_FLASH_BOOTLOADER TR("Flash bootloader","Flash bootloader") // #define TR_FLASH_EXTERNAL_DEVICE TR("Flash ext. Gerät","Flash externes Gerät") #define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" -#define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") +#define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetoothmodul") #define TR_FLASH_POWER_MANAGEMENT_UNIT TR("Flash pwr mngt unit", "Flash power management unit") #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash int. XJT","Flash internes XJT-Modul") -#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") -#define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. mod","Flash extern module") -#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") -#define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") -#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" -#define TR_WRITING "Writing..." +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash int. Multimodul") +#define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. mod","Flash ext. Modul") +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash ext. Multimodul") +#define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware Updatefehler") +#define TR_FIRMWARE_UPDATE_SUCCESS TR3("Flash successful","Flash successful","Update erfolgreich") +#define TR_WRITING "Schreibe..." #define TR_CONFIRM_FORMAT "Formatieren bestätigen?" #define TR_INTERNALRF "Internes HF-Modul" #define TR_INTERNAL_MODULE TR("Int. module","Internal module") @@ -961,15 +961,15 @@ #define TR_PRESET "Preset" #define TR_MIRROR "Spiegeln" #define TR_CLEAR "Löschen" -#define TR_RESET TR("Servowert reset","Servowerte rücksetzen") +#define TR_RESET TR("Servowert reset","Servowerte zurücksetzen") #define TR_RESET_SUBMENU TR("Reset Werte ==>", "Reset=>Timer Flug Telem") #define TR_COUNT "Punkte" #define TR_PT "Pt" #define TR_PTS "Pts" #define TR_SMOOTH "Runden" -#define TR_COPY_STICKS_TO_OFS TR("Copy Stk ->Subtrim", "Kopie Stick to Servo-Mitte") -#define TR_COPY_MIN_MAX_TO_OUTPUTS TR("Cpy min/max to all", "Copy min/max/center to all outputs") -#define TR_COPY_TRIMS_TO_OFS TR("Copy Trim->Subtrim", "Kopie Trimm to Servo-Mitte") // "Trim to Subtrim" +#define TR_COPY_STICKS_TO_OFS TR3("Copy Stk ->Subtrim", "Kopiere Stick zu Subtrim", "Kopiere Knüppelposition auf Subtrim") +#define TR_COPY_MIN_MAX_TO_OUTPUTS TR3("Cpy min/max to all", "Kopiere min/max zu allen" , "Kopiere Limits & Mitte auf alle Kanäle") +#define TR_COPY_TRIMS_TO_OFS TR3("Copy Trim->Subtrim", "Kopiere Trimm zu Subtrim" , "Kopiere Trimmposition auf Subtrim") // "Trim to Subtrim" #define TR_INCDEC "Inc/Decrement" #define TR_GLOBALVAR "Global Var" #define TR_MIXSOURCE "Mixer Quelle" From 3919e1dec8d1a495d65d39d5820aecb007700826 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Tue, 25 Feb 2020 09:32:13 +0100 Subject: [PATCH 63/70] Update CREDITS.txt --- CREDITS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CREDITS.txt b/CREDITS.txt index 66a04772f..7c3c5f652 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1701,3 +1701,4 @@ Benoit Pichereau Darko Perković Burt Pickard-Richardson Roland Nittby +Frank Barbas From a83bd2742db7fd5f0d8621171e66fb9a3ae67964 Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 25 Feb 2020 09:46:47 +0100 Subject: [PATCH 64/70] TX16S v2.2 prep --- radio/src/targets/horus/hal.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index f5692a8c7..350ca595e 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -118,8 +118,13 @@ #define SWITCHES_GPIO_PIN_E_L GPIO_Pin_3 // PE.03 #define STORAGE_SWITCH_F #define HARDWARE_SWITCH_F +#if defined(RADIO_TX16S) +#define SWITCHES_GPIO_REG_F GPIOC->IDR +#define SWITCHES_GPIO_PIN_F GPIO_Pin_13 // PC.13 +#else #define SWITCHES_GPIO_REG_F GPIOH->IDR #define SWITCHES_GPIO_PIN_F GPIO_Pin_3 // PH.03 +#endif #define STORAGE_SWITCH_G #define HARDWARE_SWITCH_G #define SWITCHES_GPIO_REG_G_H GPIOG->IDR @@ -231,7 +236,8 @@ #define KEYS_GPIOE_PINS (GPIO_Pin_3) #define KEYS_GPIOG_PINS (SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_LVD) #if defined(RADIO_TX16S) - #define KEYS_GPIOH_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) + #define KEYS_GPIOC_PINS (GPIO_Pin_13) + #define KEYS_GPIOH_PINS (GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) #else #define KEYS_GPIOH_PINS (GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) #endif From 562ee338b1e36697519b7410ad4d731dd21b64be Mon Sep 17 00:00:00 2001 From: 3djc Date: Tue, 25 Feb 2020 10:34:18 +0100 Subject: [PATCH 65/70] Touch GPIO def --- radio/src/targets/horus/board.cpp | 2 ++ radio/src/targets/horus/hal.h | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index abdde2106..3e8ad4752 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -95,6 +95,7 @@ void boardInit() HAPTIC_RCC_AHB1Periph | INTMODULE_RCC_AHB1Periph | EXTMODULE_RCC_AHB1Periph | + I2C_TOUCH_RCC_AHB1Periph | GPS_RCC_AHB1Periph | SPORT_UPDATE_RCC_AHB1Periph, ENABLE); @@ -110,6 +111,7 @@ void boardInit() AUDIO_RCC_APB1Periph | INTMODULE_RCC_APB1Periph | EXTMODULE_RCC_APB1Periph | + I2C_TOUCH_RCC_APB1Periph | GPS_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph, ENABLE); diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 350ca595e..293759f21 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -835,6 +835,24 @@ #define TIMER_2MHz_RCC_APB1Periph RCC_APB1Periph_TIM7 #define TIMER_2MHz_TIMER TIM7 +// Touch +#if defined(TOUCHPANEL) +#define I2C_TOUCH_RCC_AHB1Periph RCC_AHB1Periph_GPIOB +#define I2C_TOUCH_RCC_APB1Periph RCC_APB1Periph_I2C1 +#define I2C_TOUCH I2C1 +#define I2C_TOUCH_GPIO GPIOB +#define I2C_TOUCH_SCL_GPIO_PIN GPIO_Pin_8 // PB.08 +#define I2C_TOUCH_SDA_GPIO_PIN GPIO_Pin_7 // PB.07 + +#define I2C_TOUCH_RESET_GPIO GPIOF +#define I2C_TOUCH_RESET_GPIO_PIN GPIO_Pin_10 // PF.10 +#define I2C_TOUCH_INT_GPIO GPIOH +#define I2C_TOUCH_INT_GPIO_PIN GPIO_Pin_3 // PH.03 +#else +#define I2C_TOUCH_RCC_AHB1Periph 0 +#define I2C_TOUCH_RCC_APB1Periph 0 +#endif + // Bluetooth #define STORAGE_BLUETOOTH #if defined(BLUETOOTH) From d2b5591b698e8470751ba6d8d767aad85827ed1d Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 26 Feb 2020 09:46:10 +0100 Subject: [PATCH 66/70] TX16S pcbrev 2.3 --- radio/src/targets/horus/hal.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 293759f21..748d66d3c 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -41,8 +41,8 @@ #elif defined(RADIO_TX16S) #define KEYS_GPIO_REG_ENTER GPIOI->IDR #define KEYS_GPIO_PIN_ENTER GPIO_Pin_8 // PI.08 - #define KEYS_GPIO_REG_PGUP GPIOH->IDR - #define KEYS_GPIO_PIN_PGUP GPIO_Pin_2 // PH.02 + #define KEYS_GPIO_REG_PGUP GPIOC->IDR + #define KEYS_GPIO_PIN_PGUP GPIO_Pin_13 // PC.13 #define KEYS_GPIO_REG_PGDN GPIOI->IDR #define KEYS_GPIO_PIN_PGDN GPIO_Pin_11 // PI.11 #define KEYS_GPIO_REG_UP GPIOI->IDR @@ -118,13 +118,8 @@ #define SWITCHES_GPIO_PIN_E_L GPIO_Pin_3 // PE.03 #define STORAGE_SWITCH_F #define HARDWARE_SWITCH_F -#if defined(RADIO_TX16S) -#define SWITCHES_GPIO_REG_F GPIOC->IDR -#define SWITCHES_GPIO_PIN_F GPIO_Pin_13 // PC.13 -#else #define SWITCHES_GPIO_REG_F GPIOH->IDR #define SWITCHES_GPIO_PIN_F GPIO_Pin_3 // PH.03 -#endif #define STORAGE_SWITCH_G #define HARDWARE_SWITCH_G #define SWITCHES_GPIO_REG_G_H GPIOG->IDR @@ -237,7 +232,6 @@ #define KEYS_GPIOG_PINS (SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_LVD) #if defined(RADIO_TX16S) #define KEYS_GPIOC_PINS (GPIO_Pin_13) - #define KEYS_GPIOH_PINS (GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) #else #define KEYS_GPIOH_PINS (GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) #endif @@ -847,7 +841,7 @@ #define I2C_TOUCH_RESET_GPIO GPIOF #define I2C_TOUCH_RESET_GPIO_PIN GPIO_Pin_10 // PF.10 #define I2C_TOUCH_INT_GPIO GPIOH -#define I2C_TOUCH_INT_GPIO_PIN GPIO_Pin_3 // PH.03 +#define I2C_TOUCH_INT_GPIO_PIN GPIO_Pin_2 // PH.02 #else #define I2C_TOUCH_RCC_AHB1Periph 0 #define I2C_TOUCH_RCC_APB1Periph 0 From ec693f1b65ee243844a2629e55438f63063c6d00 Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 26 Feb 2020 10:08:04 +0100 Subject: [PATCH 67/70] Compile fixes --- radio/src/targets/horus/hal.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 748d66d3c..f3a5e2fda 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -227,14 +227,13 @@ #define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RSD) #elif defined(PCBX10) #define KEYS_GPIOB_PINS (GPIO_Pin_12 | GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_8 | GPIO_Pin_9) +#if defined(RADIO_TX16S) + #define KEYS_GPIOC_PINS (GPIO_Pin_13) +#endif #define KEYS_GPIOD_PINS (GPIO_Pin_11 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_13) #define KEYS_GPIOE_PINS (GPIO_Pin_3) #define KEYS_GPIOG_PINS (SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_LVD) -#if defined(RADIO_TX16S) - #define KEYS_GPIOC_PINS (GPIO_Pin_13) -#else #define KEYS_GPIOH_PINS (GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) -#endif #define KEYS_GPIOI_PINS (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_15) #define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | GPIO_Pin_8) #endif From 177b379c28b07c6738850634e24da975c967aca4 Mon Sep 17 00:00:00 2001 From: 3djc Date: Wed, 26 Feb 2020 11:44:47 +0100 Subject: [PATCH 68/70] Cosmetics --- radio/src/targets/horus/hal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index f3a5e2fda..ed5422834 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -829,7 +829,7 @@ #define TIMER_2MHz_TIMER TIM7 // Touch -#if defined(TOUCHPANEL) +#if defined(HARDWARE_TOUCH) #define I2C_TOUCH_RCC_AHB1Periph RCC_AHB1Periph_GPIOB #define I2C_TOUCH_RCC_APB1Periph RCC_APB1Periph_I2C1 #define I2C_TOUCH I2C1 From bb0412b11da22b528eccf60619b1a4abf0f1dfca Mon Sep 17 00:00:00 2001 From: 3djc Date: Fri, 28 Feb 2020 09:31:24 +0100 Subject: [PATCH 69/70] Add T5/T6 to Companion for relevant radios (#7415) * Hopefully correct ui * Continued * Cosmetics * Prevent crashes * Fix T5/T6 not saving * Windows compilation fix * Add sliders for T5/T6 * Cosmetics Co-authored-by: Andre Bernet --- companion/src/modeledit/flightmode.ui | 356 ++++++++++++++++-------- companion/src/modeledit/flightmodes.cpp | 24 +- 2 files changed, 260 insertions(+), 120 deletions(-) diff --git a/companion/src/modeledit/flightmode.ui b/companion/src/modeledit/flightmode.ui index ab279a437..f3dff650e 100644 --- a/companion/src/modeledit/flightmode.ui +++ b/companion/src/modeledit/flightmode.ui @@ -58,7 +58,7 @@ - + Qt::Horizontal @@ -85,24 +85,18 @@ - - - - - 0 - 0 - - + + Qt::Horizontal - - QSlider::TicksBothSides + + + 40 + 20 + - - 25 - - + @@ -136,25 +130,6 @@ - - - - - 0 - 0 - - - - Qt::Horizontal - - - QSlider::TicksBothSides - - - 25 - - - @@ -166,16 +141,6 @@ - - - - trim1 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -284,11 +249,59 @@ + + + + trim1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 25 + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 25 + + + @@ -299,7 +312,7 @@ - + @@ -310,65 +323,6 @@ - - - - trim3 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Qt::AlignCenter - - - true - - - -896 - - - 896 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - @@ -418,23 +372,201 @@ + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::AlignCenter + + + true + + + -896 + + + 896 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + trim3 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + - - + + + + + + trim6 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::AlignCenter + + + true + + + -896 + + + 896 + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 40 + + + + + + + + Qt::Horizontal - - - 40 - 20 - + + QSlider::TicksBothSides - + + 25 + + + + + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 25 + + + + + + + + + trim5 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::AlignCenter + + + true + + + -896 + + + 896 + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 40 + + + + + diff --git a/companion/src/modeledit/flightmodes.cpp b/companion/src/modeledit/flightmodes.cpp index e1b01c1a9..53f5d7585 100644 --- a/companion/src/modeledit/flightmodes.cpp +++ b/companion/src/modeledit/flightmodes.cpp @@ -80,20 +80,28 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI } // The trims - QString labels[CPN_MAX_STICKS]; + QString labels[CPN_MAX_TRIMS]; for(int i=0; i < CPN_MAX_STICKS; i++) { labels[i] = firmware->getAnalogInputName(i); } + labels[4] = "T5"; + labels[5] = "T6"; - - trimsLabel << ui->trim1Label << ui->trim2Label << ui->trim3Label << ui->trim4Label; - trimsUse << ui->trim1Use << ui->trim2Use << ui->trim3Use << ui->trim4Use; - trimsValue << ui->trim1Value << ui->trim2Value << ui->trim3Value << ui->trim4Value; - trimsSlider << ui->trim1Slider << ui->trim2Slider << ui->trim3Slider << ui->trim4Slider; + trimsLabel << ui->trim1Label << ui->trim2Label << ui->trim3Label << ui->trim4Label << ui->trim5Label << ui->trim6Label; + trimsUse << ui->trim1Use << ui->trim2Use << ui->trim3Use << ui->trim4Use << ui->trim5Use << ui->trim6Use; + trimsValue << ui->trim1Value << ui->trim2Value << ui->trim3Value << ui->trim4Value << ui->trim5Value << ui->trim6Value; + trimsSlider << ui->trim1Slider << ui->trim2Slider << ui->trim3Slider << ui->trim4Slider << ui->trim5Slider << ui->trim6Slider; Board::Type board = firmware->getBoard(); - for (int i=0; i<4; i++) { + for (int i = getBoardCapability(board,Board::NumTrims); i < CPN_MAX_TRIMS; i++) { + trimsLabel[i]->hide(); + trimsUse[i]->hide(); + trimsValue[i]->hide(); + trimsSlider[i]->hide(); + } + + for (int i = 0; i < getBoardCapability(board,Board::NumTrims); i++) { trimsLabel[i]->setText(labels[CONVERT_MODE(i+1)-1]); QComboBox * cb = trimsUse[i]; @@ -293,7 +301,7 @@ void FlightModePanel::update() ui->fadeIn->setValue(float(phase.fadeIn)/scale); ui->fadeOut->setValue(float(phase.fadeOut)/scale); - for (int i=0; i<4; i++) { + for (int i = 0; i < getBoardCapability(firmware->getBoard(), Board::NumTrims); i++) { int trimsMax = firmware->getCapability(ExtendedTrimsRange); if (trimsMax == 0 || !model->extendedTrims) { trimsMax = firmware->getCapability(TrimsRange); From ec56892de618a66e679e565cb68c9559c783f0d0 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sun, 1 Mar 2020 09:48:13 +0100 Subject: [PATCH 70/70] Update CREDITS.txt --- CREDITS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CREDITS.txt b/CREDITS.txt index 7c3c5f652..52e7ad5f4 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1702,3 +1702,5 @@ Darko Perković Burt Pickard-Richardson Roland Nittby Frank Barbas +Scott McCoy +Fabrice Debonnet