1

Bonjour à tous!

J'ai programmé une fonction d'attente, et, ne pouvant utiliser les timers (je désactive ou redirige les Auto ints 1 et 5) j'utilise les Programmable Rate Generator.

C'est la première fois que j'utilise les PRG mais je pense avoir réussi à avoir un résultat correct :
void attendre(unsigned char temps)
{
char Rate, Start;

if (!IsPRGEnabled()) EnablePRG();
Rate=PRG_getRate();
Start=PRG_getStart();

PRG_setStart(temps);
PRG_setRate(0);
while (PRG_getValue()!=0xFF);

PRG_setRate(Rate);
PRG_setStart(Start); }


Tout d'abord, y a t'il une quelconque erreur dans ma fonction?

Deuxième question : Il se trouve que dans mon programme l'utilisateur déplace un curseur. Or si je ne met pas de fonction "attendre" le curseur se déplace beaucoup trop vite (et en plus niveau compatibilité entre les différentes machines c'est pas génial puisque le curseur n'ira pas aussi vite sur une machine que sur l'autre, non?). Mais si je met ma fonction "attendre", le curseur devient alors trop lent, surtout étant donné que je n'ai pas encore mis d'autres fonctionnalités à mon programme qui vont fatalement diminuer la vitesse de déplacement.

Donc en gros je cherche le juste milieu, que je n'ai pas réussi à atteindre (j'ai eu beau mettre le PRG_setRate à 0 -vitesse la plus élevée- et rentrer en argument de ma fonction temps=1, c'est toujours trop lent!).
Auriez-vous une technique à me donner pour résoudre ce problème s'il-vous-plait ? smile

Enfin j'ai une dernière question, subsidiaire cette fois-ci :
A l'origine je souhaitais utiliser les timers, or à cause de mes redirections d'ints, l'USER_TIMER (timer n°6) n'est plus utilisable. Ok.
Mais il existe aussi l'USER1_TIMER (timer n°1) qui est disponible pour une utilisation personnelle, non?

Quand j'ai essayé de m'en servir, ça ne marchait pas (calculatrice bloquée et reset de l'émulateur -je suis sous TiEmu-).

Merci d'avances de vos réponses!

Daniel.
avatar
Ancien pseudo : worfang.

2

C'est quoi ta bibliothèque ?
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

3

Euhh quand tu parles de bibliothèque tu parles de librairies, soit les librairies que je charge en début de programme?

Si mon interprétation est la bonne, je ne charge que tigcclib.h.

Si je suis à coté de la plaque dans ma réponse, pourrais-tu préciser un peu le terme bibliothèque s'il-te-plaît? smile
avatar
Ancien pseudo : worfang.

4

Oui c'est ça. Bibliothèque est la traduction française de library il me semble wink

J'ai posé cette question car je pensais que les programmable rate generators étaient fournis par une bibliothèque externe. J'ignorais que TIGCC fournissait ça de base.

Tu es sûr qu'ils fonctionnent quand les interruptions matérielles 1 et 5 sont désactivées ?
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

5

Bah normalement oui. A vrai dire je n'aurais pas pensé à utiliser les PRG tout seul, mais c'était une solution qu'on m'avait donné il y a quelques mois pour un problème similaire. A l'époque je m'étais passé des PRG (j'avais préféré ne pas rediriger l'auto int 5).
Comme à l'époque je virais déjà les auto ints 1 et 5, les PRG devraient marcher.
avatar
Ancien pseudo : worfang.

6

Daniel Vouaux (./1) :
rentrer en argument de ma fonction temps=1
Ce n'est pas la valeur qui permet d'avoir la vitesse la plus élevée, il faut mettre 0xFF.
Daniel Vouaux (./1) :
while (PRG_getValue()!=0xFF);
Tu ne devrais pas utiliser ça.
Il se peut que le compteur retourne à 0 avant que tu ne lises la valeur, il faut utiliser l'interruption 5, c'est ça que déclenchent les PRG.

avatar

7

Mais je redirige déjà l'int 5, donc je ne peux pas utiliser les PRG non plus?

Ou bien j'active l'auto int 5 en début de fonction et je le remet comme je veux à la fin? Dans ce cas là autant utiliser les timers classiques.
avatar
Ancien pseudo : worfang.

8

Non, les PRG, c'est de la tigccliberie. Et ca n'a pas besoin des autoints:
#define DisablePRG() ({ asm volatile ("bclr #3,0x600015"); })
#define EnablePRG() ({ asm volatile ("bset #3,0x600015"); })
#define IsPRGEnabled() (!!((*((volatile unsigned char*)0x600015))&0x8))
#define PRG_getRate() (((*((unsigned char*)0x600015))&0x30)>>4)
extern unsigned char PRG_getStart(void)__ATTR_LIB_C__;
#define PRG_getValue() (*((volatile unsigned char*)0x600017))
#define PRG_setRate(x) (*((unsigned char*)0x600015)=(*((unsigned char*)0x600015)&0xCF)|(((x)&0x3)<<4))
#define PRG_setStart(x) (*((volatile unsigned char*)0x600017)=(x))


Ton problème est que PRG_getStart prend du temps (pas le choix: on doit attendre une boucle complète pour détecter le bon point de départ).
Mes les init (getrate / getstart) en phase d'initialisation seulement et pas dans la fonction attendre.

9

Merci beaucoup PpHd!
Mon curseur va enfin à une vitesse convenable.

Thepro> Si jamais je met le temps à 0xFF, dans ce cas là la boucle sera instantannée, non? Du moins elle sera instantannée (donc ne présentant pas grand intérêt) tant que je conserverais ma condition "while (PRG_getValue()!=0xFF);". Quelle condition pourrais-je alors utiliser au lieu de celle-ci?
avatar
Ancien pseudo : worfang.

10

0xFF, c'est la valeur pour que ce soit le plus rapide, à toi de choisir celle qu'il faut pour que ton programme aille à la bonne vitesse.
avatar

11

Je crois que tu confonds le rate et le state.

12

Euhh c'est bien possible, sachant que je ne sais pas ce qu'est le state (état?). grin

Pour ce qui est de la vitesse, celle que j'ai actuellement (en mettant ma variable temps à 1) me convient.

Encore merci.
avatar
Ancien pseudo : worfang.

13

14

Euhh je ne vois pas trop trop de quoi tu veux parler.
Qu'est-ce qu'un "Handler d'interruption"?
avatar
Ancien pseudo : worfang.

15

16

J'ai regardé dans la doc de TIGCC. Je comprend pas trop l'intérêt d'un Handler dans mon cas. sad

Si j'ai bien compris, tu veux que je bidouille l'int 5?

Le truc c'est que j'ai besoin de ma redirection de l'int 5 actuelle pour ne pas avoir de bugs quand l'utilisateur appuye sur une touche (rowread, keytest...).
avatar
Ancien pseudo : worfang.

17

18

Martial Demolins (./17) :
en C, tu dois pratiquement pas pouvoir empêcher l'int5 de se produire, sauf peut-être en bidouillant les ports).


OSSetSR (0X500);

19

20

Je comprend à peu prêt tes explications (et c'est pas facile, je maitrise pas du tout du tout ce genre de choses), mais je ne réussis toujours pas à en saisir la portée.
En gros je devrais créer moi-même un interrupt handler qui fait ce que je veux (être un timer? j'ai un gros doute sur ce que je suis en train d'écrire =_= ).

En fait de base l'auto int 5 a une routine qui fait foirer la lecture clavier.
Le DUMMY_HANDLER se contente juste d'associer à l'auto int 5 la routine "ne fait rien et retourne au programme directement".
C'est bien cela?

Désolé je suis vraiment un noob sur ce sujet. tsss
avatar
Ancien pseudo : worfang.

21

22

D'accord.

Est-ce que tu sais, au niveau de temps, combien de fois par seconde est appelé le PRG (quoique c'est variable il me semble, en fonction de la valeur qu'on rentre en Rate)? C'est 1/20 comme pour les timers?
avatar
Ancien pseudo : worfang.

23

24

25

Daniel Vouaux, il y a un exemple d'utilisation de l'interruption 5 sur cette page.
Il n'y a pas grand-chose à modifier pour faire ce que tu veux smile
avatar

26

Encore merci de vos réponses.

En fait, le Handler, c'est exactement comme une autre fonction, sauf qu'il doit être associé à un auto int (le 5 dans notre exemple) et que, de ce fait, il sera répété tous les 1/20ème de seconde, c'est ça?

J'essaye de cerner un peu mieux la bête. ^_^
avatar
Ancien pseudo : worfang.

27

28

Okéééééééééééééé.

Ah ouais ça peut être pratique alors grin .
avatar
Ancien pseudo : worfang.

29

Dans mon cas, je pourrais faire ma boucle "attendre" de cette façon (corrigez moi si j'ai des erreurs):
volatile int Compteur=0;

DEFINE_INT_HANDLER(mon_int_d_attente_5)
{
Compteur++;
}

void attendre(unsigned short temps)
{
INT_HANDLER ancien_int_5;
ancien_int_5=GetIntVec (AUTO_INT_5);
SetIntVec (AUTO_INT_5, mon_int_d_attente_5);

while (compteur<temps);

SetIntVec(AUTO_INT_5, ancien_int_5); }


Est-ce que c'est ça? Remarque si tu t'y connais pas trop en C Martial, tu ne pourras pas trop m'aider là-dessus je suppose.. wink Il va falloir que je me mette à l'assembleur. grin
avatar
Ancien pseudo : worfang.

30

Tu peux modifier l'interruption dans le programme principal au lieu de le faire dans attendre. Comme ça :
volatile int Compteur = 0; 

DEFINE_INT_HANDLER(mon_int_d_attente_5) { 
    Compteur++; 
}

void attendre(unsigned short temps) {
    int fin_compteur = Compteur + temps;
    while (Compteur < fin_compteur); 
}

void _main() { 
    INT_HANDLER ancien_int_5; 
    ancien_int_5 = GetIntVec (AUTO_INT_5); 
    SetIntVec (AUTO_INT_5, mon_int_d_attente_5); 
...
    attendre(temps)
...
    SetIntVec(AUTO_INT_5, ancien_int_5); 
}
avatar