Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Essai de communication via port Serial 3-pins CG10/20/50
Slyvtt Hors ligne Community Manager Points: 834 Défis: 0 Message

Essai de communication via port Serial 3-pins CG10/20/50

Posté le 11/05/2022 08:22

Hello,

ayant juste un petit peu de temps, cette fin de semaine avant d'être une semaine off-line, je voulais regarder un peu la libsnd et le port serial 3-pins. Je me suis donc imprégné de la documentation que j'ai pu trouver ici et là. Mes recherches m'ont permis d'identifier les sources suivantes :
- les sources de la libsnd de Thomas Williamson (utilisée dans l'excellentissime Nesizm) et du PrizmSDK
- la doc de la bible PC collectée par Simon Lothar (partie CG20 - Serial) dispo ici : serial CG20
- l'explication de texte des syscalls correspondants dans le Wiki de Cemetech ici : wiki Serial

A partir de cela, je me suis fait une mini-librairie (je sais, c'est maladif en ce moment ) appelée libserial (original, vous ne trouvez pas) qui reprend les syscalls suivants directement liés au port serial 3-pins, ainsi que le header correspondant (serial.h) :
- Serial_ClearRX
- Serial_ClearTX
- Serial_Close
- Serial_IsOpen
- Serial_Open
- Serial_Peek
- Serial_PollRX
- Serial_PollTX
- Serial_Read
- Serial_ReadSingle
- Serial_Write
- Serial_WriteSingle
- Serial_WriteUnbuffered

ainsi que les suivants, plus ou moins éloignés, mais repris dans le prizmSDK (je les virerais si il ne servent effectivement pas) :
- App_LINK_GetDeviceInfo
- App_LINK_GetReceiveTimeout_ms
- App_LINK_Send_ST9_Packet
- App_LINK_SetReceiveTimeout_ms
- App_LINK_SetRemoteBaud
- App_LINK_TransmitInit
- App_LINK_Transmit
- Comm_Close
- Comm_Open
- Comm_Terminate
- Comm_TryCheckPacket

Pour vérifier que tout fonctionne, j'ai fait un simple petit programme pour vérifier l'état du port serial (ouvert et / ou fermé), puis procéder à son ouverture et à sa fermeture, tout cela sur ma CG50 (Graph 90+E) et ma CG20 pour vérifier que les syscalls sont toujours bien utilisables. Ok, ça compile, ça link et surtout ça fonctionne. Voici le code utilisé :

Vérif, ouverture et fermeture du port Serial - Cliquer pour dérouler
Vérif, ouverture et fermeture du port Serial - Cliquer pour enrouler


#include <gint/display.h>
#include <gint/keyboard.h>
#include <serial.h>

int main(void)
{
    dclear(C_WHITE);
    dtext(1, 1, C_BLACK, "Sample fxSDK Communication add-in.");

    if (Serial_IsOpen() != 1)
    {
        dtext(1,21, C_RED, "Serial port is CLOSED !!!" );
        dtext(1,31, C_RGB( 31, 24, 0), "Trying to Open it ..." );
        unsigned char mode[6]={0,9,0,0,0,0};
        Serial_Open( mode );
    }

    if (Serial_IsOpen() == 1) dtext(1,41, C_GREEN, "Serial port is now OPEN !!!" );
    else
    {
        dtext(1,41, C_RED, "Failed to open the Serial port : STILL CLOSED !!!" );
        dtext(1,51, C_BLACK, "Press a key to exit back to OS ..." );
        dupdate();
        getkey();
        return 0;
    }

    if (Serial_IsOpen() == 1)
    {
        dtext(1,121, C_RED, "Now closing the Serial Port !!!" );
        Serial_Close( 1 );
    }

    if (Serial_IsOpen() != 1) dtext(1,141, C_GREEN, "Serial port is now Closed !!!" );

    dupdate();

    getkey();

    return 1;
}



C'est donc un début vraiment encourageant, dans le sens où la gestion du port se fait correctement et la mini librairie semble bien fonctionner de son côté.

Bon, donc plein d'espoir, j'essaie de passer à l'étape suivante :
- sur une des 2 machines, envoyer un paquet de char dans le buffer de transmission (donc transmettre, en langage décodé),
- sur l'autre machine, recevoir un paquet de char dans le buffer de réception (donc recevoir ).

Le but étant ici juste d'envoyer d'un côté et de lire de l'autre côté, sans contrôle d'erreur et tout ce qu'il faudrait faire pour avoir des vraies communications "sérieuses" (donc pas taper merci ) ... on reste dans le très très expérimental par un gars qui découvre .

Ceci étant réalisé par le code suivant (enfin, l'expression adéquate serait plutôt : "ceci devant être réalisé par le code suivant" ) :

Envoi et réception sur port Serial - Cliquer pour dérouler
Envoi et réception sur port Serial - Cliquer pour enrouler
*

#include <gint/display.h>
#include <gint/keyboard.h>
#include <serial.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    dclear(C_WHITE);
    dtext(1, 1, C_BLACK, "Sample fxSDK Communication add-in.");

    if (Serial_IsOpen() != 1)
    {
        dtext(1,21, C_RED, "Serial port is CLOSED !!!" );
        dtext(1,31, C_RGB( 31, 24, 0), "Trying to Open it ..." );
        unsigned char mode[6]={0,9,0,0,0,0};
        Serial_Open( mode );
    }

    if (Serial_IsOpen() == 1) dtext(1,41, C_GREEN, "Serial port is now OPEN !!!" );
    else
    {
        dtext(1,41, C_RED, "Failed to open the Serial port : STILL CLOSED !!!" );
        dtext(1,51, C_BLACK, "Press a key to exit back to OS ..." );
        getkey();
        return 0;
    }

    dtext(1,210, C_BLACK, "SEND");
    dtext(60, 210, C_BLACK, "RECV");

    dtext(1, 61, C_BLACK, "Press F1 to set Send mode and F2 to set Receive mode" );
    dupdate();

    if (getkey().key == KEY_F1)
    {
        char MessageToSend[256];
        strcpy( MessageToSend, "Hello World !!!" );
        int CountSend = 15;

        dprint(1, 81, C_BLUE, "Will send a message %s ", MessageToSend );
        dupdate();
        getkey();

//        int result = Serial_Write( (unsigned char*) MessageToSend, CountSend ); // Fait Crash la babasse

        int result = Serial_WriteSingle( (unsigned char) 'Y' ); // idem, fait aussi crash la babasse

        if (result==0)
        {
            dprint(1, 101, C_GREEN, "Message sent" );
        }
        else if (result==2)
        {
            dprint(1, 101, C_RED, "buffer is full" );
        }
        dupdate();
        getkey();

    }
    else if (getkey().key == KEY_F2)
    {
        unsigned char MessageRead[256];
        int MaxCountRead = 256;
        short int CountRead = 0;
        dtext(1, 81, C_BLUE, "Will receive a message " );
        dupdate();

        int result = Serial_Read( MessageRead, MaxCountRead, &CountRead );
        if (result==0)
        {
            dprint(1, 101, C_GREEN, "%s", MessageRead );
        }
        else if (result==1)
        {
            dprint(1, 101, C_RED, "buffer is empty" );
        }
        dupdate();
        getkey();
    }


    if (Serial_IsOpen() == 1)
    {
        dtext(1,121, C_RED, "Now closing the Serial Port !!!" );
        Serial_Close( 1 );
    }

    if (Serial_IsOpen() != 1) dtext(1,141, C_GREEN, "Serial port is now Closed !!!" );

    dupdate();

    getkey();
    return 1;
}




En mode réception (appui sur F2 sur une des machines, cela semble fonctionner (sauf qu'il y a rien à lire donc j'ai le message correspondant affiché), par contre en émission (sur l'autre machine, après appui sur F1), j'ai systématiquement un crash avec reboot de la machine sur la ligne du Serial_Write/Serial_WriteSingle.

J'ai bien entendu testé chacune des machines en réception ET en émission, et c'est bien le même comportement sur chacune d'elle. L'émission fait systématiquement crasher et rebooter la machine.

Auriez-vous une idée ou un semblant d'idée pouvant expliquer ce comportement ?

Je précise que les syscalls sont bien ceux de la page ici (avec leur code respectifs) : serial CG20

Ciao

Sly


Yannis300307 Hors ligne Membre Points: 57 Défis: 0 Message

Citer : Posté le 10/08/2022 16:27 | #


Mon programme marchait mais pour je ne sais quelle raison sans que je ne change rien, il recrash comme avant ou ne veut pas ouvrir la connexion ...
Si qq a une idée ...
Yannis300307 Hors ligne Membre Points: 57 Défis: 0 Message

Citer : Posté le 11/09/2022 12:15 | #


Bonjour je pence que j'ai mal fait (ou compris) qq chose car gint_world_switch(GINT_CALL(Serial_ReadSingle)) renvoie 0 (ou un pointeur vers 0) à tous les cous. Comment je peux récupérer le résultat ?

EDIT: Serial_ReadSingle(*var) marche sans gint_world_switch finalement mais le buffer de réception s'update que quand je démarre le programme ...

Merci
Lephenixnoir En ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 11/09/2022 13:27 | #


EDIT: Serial_ReadSingle(*var) marche sans gint_world_switch finalement mais le buffer de réception s'update que quand je démarre le programme ...

C'est normal gint contrôle les interruptions donc l'OS n'a jamais l'opportunité de récupérer les données. Il faut bien faire un world switch. Tu lui passes quels paramètres durant le world switch ?

Edit : parce que la valeur de retour c'est un code d'erreur, par l'octet.

char c;
int rc = gint_world_switch(GINT_CALL(Serial_ReadSingle, &c));

Edit 2 : Oui et fais pas un world switch à chaque appel hein ^^"
Yannis300307 Hors ligne Membre Points: 57 Défis: 0 Message

Citer : Posté le 11/09/2022 13:29 | #


Je lui donne un pointeur vers la variable de sortie.
Je vais essayer avec gint_world_switch()

EDIT : avec gint_world_switch ça marche parfaitement !

Merci
Lephenixnoir En ligne Administrateur Points: 22599 Défis: 149 Message

Citer : Posté le 11/09/2022 14:17 | #


Cool ! N'oublie pas que gint_world_switch() a un coût, si tu effectues plusieurs appels à la lib serial d'un coup il vaut mieux faire un seul world switch et faire tous les appels à la suite dedans :

void read_3_characters(char *c1, char *c2, char *c3)
{
    /* Exemple bidon */
    Serial_ReadSingle(c1);
    Serial_ReadSingle(c2);
    Serial_ReadSingle(c3);
}

char c1, c2, c3;
gint_world_switch(GINT_CALL(read_3_characters, &c1, &c2, &c3));

Tu peux rester dans le world switch aussi longtemps que tu veux tant que n'utilises pas le matériel via gint (typiquement pour dupdate(), getkey(), il faut revenir dans gint). Tu peux quand même calculer, stocker des variables, allouer de la mémoire, etc.
Yannis300307 Hors ligne Membre Points: 57 Défis: 0 Message

Citer : Posté le 11/09/2022 15:59 | #


Lephenixnoir a écrit :
Cool ! N'oublie pas que gint_world_switch() a un coût, si tu effectues plusieurs appels à la lib serial d'un coup il vaut mieux faire un seul world switch et faire tous les appels à la suite dedans :


Oui je dois envoyer une image pixel par pixel donc ça fait beaucoup de call. Je vais penser à faire une fonction.
Slyvtt Hors ligne Community Manager Points: 834 Défis: 0 Message

Citer : Posté le 12/09/2022 19:04 | #


A lire rapidement j’ai l’impression que tu as résolu certains problèmes Yannis300307.

N’hésite pas à nous lâcher un morceau de code qui fonctionne pour servir de tuto à d’autres qui voudraient essayer.

Désolé en ce moment je suis hyperbooké et j’ai pas eu le temps de me remettre dessus.
Yannis300307 Hors ligne Membre Points: 57 Défis: 0 Message

Citer : Posté le 12/09/2022 19:12 | #


Slyvtt a écrit :
A lire rapidement j’ai l’impression que tu as résolu certains problèmes Yannis300307.


Oui mais... je sais pas vraiment comment ça se fait car je n'est rien fait de particulier et ça s'est mit à marcher ...

Slyvtt a écrit :
N’hésite pas à nous lâcher un morceau de code qui fonctionne pour servir de tuto à d’autres qui voudraient essayer.


J'ai écrit du code mais il n'est pas très lisible et tres spécifique. Si mon projet fini par marcher, je pourrais peut être le publier.

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2022 | Il y a 74 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd