π
<-

Ndless KeyListener

C, C++, ASM...

Ndless KeyListener

Unread postby MishaShapo » 06 May 2016, 05:05

Hi, I am trying to create a keylistener in Ndless that will print an ASCII string to the USB port through NspireIO. I have looked at the Zlock and nClock examples to try and emulate them, but my code doesn't seem to work. It sends the "URTX" message and then the calculator freezes, but I do know the program is running because when I press the flag button (the button that terminates the outer while loop in my main method) then the calculator goes back to normal.

Can anyone please point out what I am doing wrong? Thank you. :)


Salut, je suis en train de créer un keyListener en Ndless qui imprimera une chaîne ASCII au port USB via NspireIO. J'ai regardé les exemples ZLOCK et nClock pour essayer de les imiter, mais mon code ne semble pas fonctionner. Il envoie le message "Urtx", puis la calculatrice se fige, mais je ne sais que le programme est en cours d'exécution parce que quand je presse le bouton de drapeau (le bouton qui met fin à l'extérieur tout en boucle dans ma méthode principale), le calculateur va revenir à la normale.

Quelqu'un peut-il s'il vous plaît souligner ce que je fais mal? Je vous remercie. :)

Code: Select all
#include <os.h>
#include "libndls.h"
#include <nspireio/nspireio.h>
char *cmd = "";
bool quit = false;

void pushButton(){
    if(isKeyPressed(KEY_NSPIRE_0)) cmd = "0";
    if(isKeyPressed(KEY_NSPIRE_1)) cmd = "1";
    if(isKeyPressed(KEY_NSPIRE_2)) cmd = "2";
    if(isKeyPressed(KEY_NSPIRE_3)) cmd = "3";
    if(isKeyPressed(KEY_NSPIRE_4)) cmd = "4";
    if(isKeyPressed(KEY_NSPIRE_5)) cmd = "5";
    if(isKeyPressed(KEY_NSPIRE_6)) cmd = "6";
    if(isKeyPressed(KEY_NSPIRE_7)) cmd = "7";
    if(isKeyPressed(KEY_NSPIRE_8)) cmd = "8";
    if(isKeyPressed(KEY_NSPIRE_9)) cmd = "9";
    if(isKeyPressed(KEY_NSPIRE_A)) cmd = "A";
    if(isKeyPressed(KEY_NSPIRE_B)) cmd = "B";
    if(isKeyPressed(KEY_NSPIRE_C)) cmd = "C";
    if(isKeyPressed(KEY_NSPIRE_D)) cmd = "D";
    if(isKeyPressed(KEY_NSPIRE_E)) cmd = "E";
    if(isKeyPressed(KEY_NSPIRE_F)) cmd = "F";
    if(isKeyPressed(KEY_NSPIRE_G)) cmd = "G";
    if(isKeyPressed(KEY_NSPIRE_H)) cmd = "H";
    if(isKeyPressed(KEY_NSPIRE_I)) cmd = "I";
    if(isKeyPressed(KEY_NSPIRE_J)) cmd = "J";
    if(isKeyPressed(KEY_NSPIRE_K)) cmd = "K";
    if(isKeyPressed(KEY_NSPIRE_L)) cmd = "L";
    if(isKeyPressed(KEY_NSPIRE_M)) cmd = "M";
    if(isKeyPressed(KEY_NSPIRE_N)) cmd = "N";
    if(isKeyPressed(KEY_NSPIRE_O)) cmd = "O";
    if(isKeyPressed(KEY_NSPIRE_P)) cmd = "P";
    if(isKeyPressed(KEY_NSPIRE_Q)) cmd = "Q";
    if(isKeyPressed(KEY_NSPIRE_R)) cmd = "R";
    if(isKeyPressed(KEY_NSPIRE_S)) cmd = "S";
    if(isKeyPressed(KEY_NSPIRE_T)) cmd = "T";
    if(isKeyPressed(KEY_NSPIRE_U)) cmd = "U";
    if(isKeyPressed(KEY_NSPIRE_V)) cmd = "V";
    if(isKeyPressed(KEY_NSPIRE_W)) cmd = "W";
    if(isKeyPressed(KEY_NSPIRE_X)) cmd = "X";
    if(isKeyPressed(KEY_NSPIRE_Y)) cmd = "Y";
    if(isKeyPressed(KEY_NSPIRE_Z)) cmd = "Z";
    if(isKeyPressed(KEY_NSPIRE_ESC)) cmd = "ESC";
    if(isKeyPressed(KEY_NSPIRE_DEL)) cmd = "DEL";
    if(isKeyPressed(KEY_NSPIRE_ENTER)) cmd = "ENT";
    if(isKeyPressed(KEY_NSPIRE_RET)) cmd = "RET";
    if(isKeyPressed(KEY_NSPIRE_SPACE)) cmd = " ";
    if(isKeyPressed(KEY_NSPIRE_NEGATIVE)) cmd = "-";
    if(isKeyPressed(KEY_NSPIRE_PERIOD)) cmd = ".";
    if(isKeyPressed(KEY_NSPIRE_THETA)) cmd = "THETA";
    if(isKeyPressed(KEY_NSPIRE_COMMA)) cmd = ",";
    if(isKeyPressed(KEY_NSPIRE_PLUS)) cmd = "+";
    if(isKeyPressed(KEY_NSPIRE_eEXP)) cmd = "eEXP";
    if(isKeyPressed(KEY_NSPIRE_PI)) cmd = "PI";
    if(isKeyPressed(KEY_NSPIRE_QUES)) cmd = "QUES";
    if(isKeyPressed(KEY_NSPIRE_QUESEXCL)) cmd = "QUESEXCL";
    if(isKeyPressed(KEY_NSPIRE_MINUS)) cmd = "-";
    if(isKeyPressed(KEY_NSPIRE_TENX)) cmd = "TENX";
    if(isKeyPressed(KEY_NSPIRE_EE)) cmd = "EE";
    if(isKeyPressed(KEY_NSPIRE_COLON)) cmd = ":";
    if(isKeyPressed(KEY_NSPIRE_MULTIPLY)) cmd = "*";
    if(isKeyPressed(KEY_NSPIRE_SQU)) cmd = "SQU";
    if(isKeyPressed(KEY_NSPIRE_II)) cmd = "II";
    if(isKeyPressed(KEY_NSPIRE_QUOTE)) cmd = "\"";
    if(isKeyPressed(KEY_NSPIRE_DIVIDE)) cmd = "/";
    if(isKeyPressed(KEY_NSPIRE_TAN)) cmd = "TAN";
    if(isKeyPressed(KEY_NSPIRE_COS)) cmd = "COS";
    if(isKeyPressed(KEY_NSPIRE_SIN)) cmd = "SIN";
    if(isKeyPressed(KEY_NSPIRE_EXP)) cmd = "EXP";
    if(isKeyPressed(KEY_NSPIRE_GTHAN)) cmd = ">";
    if(isKeyPressed(KEY_NSPIRE_APOSTROPHE)) cmd = "'";
    if(isKeyPressed(KEY_NSPIRE_CAT)) cmd = "CAT";
    if(isKeyPressed(KEY_NSPIRE_FRAC)) cmd = "FRAC";
    if(isKeyPressed(KEY_NSPIRE_RP)) cmd = "RP";
    if(isKeyPressed(KEY_NSPIRE_LP)) cmd = "LP";
    if(isKeyPressed(KEY_NSPIRE_VAR)) cmd = "VAR";
    if(isKeyPressed(KEY_NSPIRE_DEL)) cmd = "DEL";
    if(isKeyPressed(KEY_NSPIRE_LTHAN)) cmd = "<";
    if(isKeyPressed(KEY_NSPIRE_FLAG)){ cmd = "FLAG";quit=true;}
    if(isKeyPressed(KEY_NSPIRE_CLICK)) cmd = "CLICK";
    if(isKeyPressed(KEY_NSPIRE_HOME)) cmd = "HOME";
    if(isKeyPressed(KEY_NSPIRE_MENU)) cmd = "MENU";
    if(isKeyPressed(KEY_NSPIRE_BAR)) cmd = "BAR";
    if(isKeyPressed(KEY_NSPIRE_TAB)) cmd = "TAB";
    if(isKeyPressed(KEY_NSPIRE_EQU)) cmd = "EQU";
    if(isKeyPressed(KEY_NSPIRE_UP)) cmd = "UP";
    if(isKeyPressed(KEY_NSPIRE_UPRIGHT)) cmd = "UPRIGHT";
    if(isKeyPressed(KEY_NSPIRE_RIGHT)) cmd = "RIGHT";
    if(isKeyPressed(KEY_NSPIRE_RIGHTDOWN)) cmd = "RIGHTDOWN";
    if(isKeyPressed(KEY_NSPIRE_DOWN)) cmd = "DOWN";
    if(isKeyPressed(KEY_NSPIRE_DOWNLEFT)) cmd = "DOWNLEFT";
    if(isKeyPressed(KEY_NSPIRE_LEFT)) cmd = "LEFT";
    if(isKeyPressed(KEY_NSPIRE_LEFTUP)) cmd = "LEFTUP";
    if(isKeyPressed(KEY_NSPIRE_SHIFT)) cmd = "SHIFT";
    if(isKeyPressed(KEY_NSPIRE_CTRL)) cmd = "CTRL";
    if(isKeyPressed(KEY_NSPIRE_DOC)) cmd = "DOC";
    if(isKeyPressed(KEY_NSPIRE_TRIG)) cmd = "TRIG";
    if(isKeyPressed(KEY_NSPIRE_SCRATCHPAD)) cmd = "SCRPAD";

    uart_puts(cmd);
    uart_puts("!");
}

int main(int argc, char* argv[]){

    if(argc < 1) return 0;
    cmd = "URTX";
    uart_puts(cmd);
    uart_puts("!");
    while(!quit){
        while(!any_key_pressed()){
        }
        pushButton();
    }
    return 0;
}


User avatar
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 68%
 
Posts: 17
Joined: 06 May 2016, 04:58
Gender: Not specified
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby Ti64CLi++ » 06 May 2016, 10:49

Bonjour,
Avec quoi compiles-tu ton code? Sous Linux ou sous Windows?
Image
User avatar
Ti64CLi++Modo
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 32.5%
 
Posts: 3446
Images: 75
Joined: 04 Jul 2014, 14:40
Location: Clermont-Ferrand 63
Gender: Male
Calculator(s):
MyCalcs profile
Class: ENS Rennes
GitHub: Ti64CLi

Re: Ndless KeyListener

Unread postby Vogtinator » 06 May 2016, 11:17

It sends the "URTX" message and then the calculator freezes, but I do know the program is running because when I press the flag button (the button that terminates the outer while loop in my main method) then the calculator goes back to normal.


Of course, the nspire doesn't do anything else than your loop as Ndless apps aren't multithreaded by default.
You have two options here, either add a hook somewhere in the OS or start a new thread with the OS's TCC_Create_Task function, currently not exposed by ndless as not quite stable.

nClock and zLock both use the first approach, hooking the OS's code at a place that is regularily executed.
For nClock, search for "hook_nclock" in nclock.c and you'll find everything necessary to get it running.

If you want to go the second route, I made a PoC with multithreading on https://www.omnimaga.org/ti-nspire-proj ... #msg398134
You can find the addresses for other OS's in the ndless sdk (https://github.com/ndless-nspire/Ndless ... scalls/idc).
User avatar
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Level up: 1.6%
 
Posts: 217
Joined: 29 Mar 2014, 15:55
Gender: Male
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby MishaShapo » 07 May 2016, 06:50

Hi, Vogtinator, thank you for the reply. I see that I have to use the hooks system you mentioned. I also read through another forum post on this same topic where you explained hooks https://www.omnimaga.org/calculator-c-language/ndless-hooking-tutorial-(especially-key-hooks) . I think that I understand the concept I am just having trouble finding the hook addresses. You said on that other forum that I would have to use the firebird debugger, and if that's the case, then I still have some learning to do. I am also a little confused on the difference between a hook, an interrupt, and a syscall. Could you please give me a rough idea of the difference between them? Or do you want me to make another topic for that question?

Thanks again for replying. :)
Last edited by MishaShapo on 07 May 2016, 16:41, edited 1 time in total.
User avatar
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 68%
 
Posts: 17
Joined: 06 May 2016, 04:58
Gender: Not specified
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby Vogtinator » 07 May 2016, 10:21

You may be able to reuse the nClock hook. I don't know how often it is called though.

I am also a little confused on the difference between a hook, an interrupt, and a syscall. Could you please give me a rough idea of the difference between them?

A hook is a modification of running code at strategic places to make it call your code.
An interrupt (IRQ/FIQ) is a signal from the hardware which causes the CPU to jump to a specific address (0x18/0x1C on ARM).
A syscall is also called a software interrupt (SWI), as it is like a hardware interrupt, just caused by software (0x08 on ARM).
Ndless programs use SWIs to make calls to ndless and the OS.
User avatar
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Level up: 1.6%
 
Posts: 217
Joined: 29 Mar 2014, 15:55
Gender: Male
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby MishaShapo » 07 May 2016, 16:45

Vogtinator, I tried to use the nClock hooks, but it did not fire regularly. How would I go about finding the OS's key interrupt handler as you said in the other forum post? I know it has to do with assembly and using the firebird debugger. But I am new to GDB and assembly in general. But if there are any resources that I should read/watch I will do that. Thanks for helping me with this. Its a project for a teacher of mine, and I really want to get it to her before the school year ends, so I appreciate you helping me with this. :)
User avatar
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 68%
 
Posts: 17
Joined: 06 May 2016, 04:58
Gender: Not specified
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby Vogtinator » 07 May 2016, 17:52

Finding that is quite easy, by printing the PC during reads of the keypad. Just tell me which OS and I'll find it.
User avatar
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Level up: 1.6%
 
Posts: 217
Joined: 29 Mar 2014, 15:55
Gender: Male
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby MishaShapo » 07 May 2016, 18:21

I will be using TI-Nspire CX (both CAS and non-CAS) with Ndless 4.2. Also, what do you mean "PC"? Thank you so much!!
User avatar
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 68%
 
Posts: 17
Joined: 06 May 2016, 04:58
Gender: Not specified
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby Vogtinator » 07 May 2016, 18:36

PC is the program counter. The pointer to the current instruction.
You should be able to hook 0x10069ce0 on CX CAS and 0x1006A220 on CX.
User avatar
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Level up: 1.6%
 
Posts: 217
Joined: 29 Mar 2014, 15:55
Gender: Male
Calculator(s):
MyCalcs profile

Re: Ndless KeyListener

Unread postby MishaShapo » 07 May 2016, 19:20

Hi, Vogtinator, the hooks work! But sadly not for the touchpad and it has crashed once with this error:

Code: Select all
Warning (110ee3a0): Bad write_word: 90020018 00180018
Error (110ee3c4): LDRD/STRD with odd-numbered data register

Would it be possible to find the hook for the touchpad as well? If not, I can make this work. :)

EDIT: I've noticed the error occurs when the calculator wakes up from sleep.
User avatar
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 68%
 
Posts: 17
Joined: 06 May 2016, 04:58
Gender: Not specified
Calculator(s):
MyCalcs profile

Next

Return to Native: Ndless, Linux, ...

Who is online

Users browsing this forum: ClaudeBot [spider] and 5 guests

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1515 utilisateurs:
>1503 invités
>6 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)