pixy2 smart camera library www.pixycam.com

Pixy2 Library project (using UART interface)

Revision:
3:6ba43af28440
Parent:
1:dd81f4065b6b
Child:
5:28e47187bb5c
--- a/pixy2.cpp	Fri Mar 01 13:25:12 2019 +0000
+++ b/pixy2.cpp	Mon Mar 11 14:54:44 2019 +0000
@@ -9,21 +9,33 @@
     Pixy2_buffer = (Byte*) malloc (0x100);
 }
 
+/* Le programme utilise l'interruption de la liaison série pour recevoir le message et avancer la machine d'état pour permettre au programme de ne pas être bloquant en réception.
+   Lorsqu'on appelle une fonction, elle retourne le code -2 pour signifier que le message de réponse de la caméra n'est pas completement reçu...
+   Les étapes de fonctionnement sont les suivantes :
+   
+   * idle : La caméra n'a pas été solicité => on envoi le message de requête.
+   * messageSent : La requête a été transmise, mais la réponse n'est pas encore arrivée.
+   * receivingHeader : Le mot de synchro a été reçu, le reste de l'entête est en cours de réception.
+   * headerReceived : L'entête a été intégralement reçu et peut être traité (tache interne) pour définir la payload.
+   * receivingData : On est en train de recevoir la payload.
+   * dataReceived : La réponse a été intégralement reçue et est disponible pour le traitement (et la libération).
+*/
+
 void PIXY2::pixy2_getByte ()    // Interruption de la pixy2
 {
     static Byte             startPoint;
     T_Word                  *buffer;
     
-    Pixy2_buffer[wPointer] = _Pixy2->getc();                                 // On stocke l'octet reçu dans la première case dispo du tableau temporaire
+    Pixy2_buffer[wPointer] = _Pixy2->getc();                                        // On stocke l'octet reçu dans la première case dispo du tableau temporaire
     wPointer++;
     
     switch (etat) {
-        case messageSent : // Si on a envoyé une requete => on attend un entête
-            if ( (wPointer - rPointer) >= 2) { // On attend d'avoir reçu 2 octets
+        case messageSent :                                                          // Si on a envoyé une requete => on attend un entête
+            if ( (wPointer - rPointer) >= 2) {                                      // On attend d'avoir reçu 2 octets
                 startPoint = wPointer - 1;
-                buffer = (T_Word*) &Pixy2_buffer[startPoint]; //On pointe la structure sur les 2 derniers octets reçus
+                buffer = (T_Word*) &Pixy2_buffer[startPoint];                       //On pointe la structure sur les 2 derniers octets reçus
                 if ((buffer->mot == PIXY2_CSSYNC) || (buffer->mot == PIXY2_SYNC)) {
-                    etat = receivingHeader;     // On passe à l'état réception de l'entête
+                    etat = receivingHeader;                                         // On passe à l'état réception de l'entête
                     rPointer = startPoint;
                     if (buffer->mot == PIXY2_SYNC)      frameContainChecksum = 0;   // On mémorise qu'il n'y a pas de checksum à vérifier
                     else                                frameContainChecksum = 1;   // On mémorise qu'il y a un checksum à vérifier
@@ -31,21 +43,21 @@
             }
             break;
 
-        case receivingHeader :  //Si on est en train de recevoir un entête (entre le SYNC et... La fin de l'entête)
+        case receivingHeader :                                                      //Si on est en train de recevoir un entête (entre le SYNC et... La fin de l'entête)
             if ((frameContainChecksum && ((wPointer - rPointer) == PIXY2_CSHEADERSIZE)) || (!frameContainChecksum && ((wPointer - rPointer) == PIXY2_NCSHEADERSIZE))) {
                 //Si on a reçu 6 octets pour une trame avec checksum ou 4 pour une trame sans checksum
-                etat = headerReceived;          //On passe à entête reçu
-                dataSize = Pixy2_buffer[startPoint+3]; // Et on lit la taille de la payload
+                etat = headerReceived;                                              //On passe à entête reçu
+                dataSize = Pixy2_buffer[startPoint+3];                              // Et on lit la taille de la payload
             }
             break;
 
-        case headerReceived :   // Si on vient de recevoir le premier octet de données
-            startPoint = wPointer;  // On enregistre sa position
-            etat = receivingData;   // Et on dit que l'on est en train de recevoir des données
+        case headerReceived :                                                       // Si on vient de recevoir le premier octet de données
+            startPoint = wPointer;                                                  // On enregistre sa position
+            etat = receivingData;                                                   // Et on dit que l'on est en train de recevoir des données
             break;
 
-        case receivingData :    // Si on est en train de recevoir des données.
-            if (wPointer == (dataSize + startPoint)) etat = dataReceived; //Quand on a reçu toutes les données promises on dit que c'est OK
+        case receivingData :                                                        // Si on est en train de recevoir des données.
+            if (wPointer == (dataSize + startPoint)) etat = dataReceived;           //Quand on a reçu toutes les données promises on dit que c'est OK
             break;
 
         default : // On ne traite volontairement ici pas tous les cas, en particulier idle et dataReceived. C'est à la fonction de le faire ! Le reste est lié à des réceptions de données.
@@ -305,37 +317,77 @@
     int                 cr = 0;
     
     switch (etat) {
-        case idle :
-            PIXY2::pixy2_sndGetVersion();
-            etat = messageSent;
-            rPointer = wPointer;
-            cr = -2;                        //Busy
+        case idle :                                                                 // Si la caméra est inactive
+            PIXY2::pixy2_sndGetVersion();                                           // On envoie la trame de demande de la version
+            etat = messageSent;                                                     // On passe à l'attente du message de réponse
+            rPointer = wPointer;                                                    // On enregistre la position du pointeur de FIFO
+            cr = -2;                    //Busy                                      // On signale à l'utilisateur que la caméra est maintenant occupée
             break;
             
-        case dataReceived :
-            if (frameContainChecksum) {
-                if ( pixy2_validateChecksum (&Pixy2_buffer[rPointer]) ) {
-                    if (msg->pixType == PIXY2_REP_VERS) {
+        case dataReceived :                                                         // Quand on a reçu l'intégralité du message
+            if (frameContainChecksum) {                                             // Si la trame contient un checksum
+                if ( pixy2_validateChecksum (&Pixy2_buffer[rPointer]) ) {           // On lance la validation du checksum           
+                    if (msg->pixType == PIXY2_REP_VERS) {                           // On vérifie que la trame est du type convenable
                         version = (T_Pixy2Version*) &Pixy2_buffer[rPointer + PIXY2_CSHEADERSIZE];
-                        etat = idle;
-                    } else cr = -7;   // Type Error
-                } else cr = -3;       // Checksum Error
-            } else {
-                if (msg->pixType == PIXY2_REP_VERS) {
+                                                                                    // Si le checksum et le type sont bon, on mappe le pointeur de résultat sur la FIFO (ligne précédente)                        
+                        etat = idle;                                                // Et on annoce que la pixy est libre
+                    } else cr = -7;     // Type Error                               // Si le type ne correspond pas on signale une erreur
+                } else cr = -3;         // Checksum Error                           // Si le checksum est faux on retourne une erreur aussi !
+            } else {                                                                // S'il n'y a pas de checksum (pas normal mais on ne sait jamais)
+                if (msg->pixType == PIXY2_REP_VERS) {                               // On vérifie que la trame est du type convenable                               
                     version = (T_Pixy2Version*) &Pixy2_buffer[rPointer + PIXY2_NCSHEADERSIZE];
-                    etat = idle;
-                } else cr = -7;       // Type Error
+                                                                                    // Si le checksum et le type sont bon, on mappe le pointeur de résultat sur la FIFO (ligne précédente)                        
+                    etat = idle;                                                    // Et on annoce que la pixy est libre
+                } else cr = -7;         // Type Error                               // Si le type ne correspond pas on signale une erreur
             }
             break;
 
-        default :
-            cr = -1;                // Busy
+        default :                                                                   // Dans tous les autres cas
+            cr = -2;                    // Busy                                     // On signale que la caméra est occupée.
             break;
     }
     return cr;
 }
 
-int PIXY2::pixy2_getResolution (T_Pixy2Resolution *resolution){return 0;}
+int PIXY2::pixy2_getResolution (T_Pixy2Resolution *resolution){
+
+    T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[rPointer];
+    int                 cr = 0;
+    
+    switch (etat) {
+        case idle :                                                                 // Si la caméra est inactive
+            PIXY2::pixy2_sndGetResolution();                                        // On envoie la trame de demande de la résolution
+            etat = messageSent;                                                     // On passe à l'attente du message de réponse
+            rPointer = wPointer;                                                    // On enregistre la position du pointeur de FIFO
+            cr = -2;                    //Busy                                      // On signale à l'utilisateur que la caméra est maintenant occupée
+            break;
+            
+        case dataReceived :                                                         // Quand on a reçu l'intégralité du message
+            if (frameContainChecksum) {                                             // Si la trame contient un checksum
+                if ( pixy2_validateChecksum (&Pixy2_buffer[rPointer]) ) {           // On lance la validation du checksum           
+                    if (msg->pixType == PIXY2_REP_RESOL) {                          // On vérifie que la trame est du type convenable
+                        resolution = (T_Pixy2Resolution*) &Pixy2_buffer[rPointer + PIXY2_CSHEADERSIZE];
+                                                                                    // Si le checksum et le type sont bon, on mappe le pointeur de résultat sur la FIFO (ligne précédente)                        
+                        etat = idle;                                                // Et on annoce que la pixy est libre
+                    } else cr = -7;     // Type Error                               // Si le type ne correspond pas on signale une erreur
+                } else cr = -3;         // Checksum Error                           // Si le checksum est faux on retourne une erreur aussi !
+            } else {                                                                // S'il n'y a pas de checksum (pas normal mais on ne sait jamais)
+                if (msg->pixType == PIXY2_REP_RESOL) {                              // On vérifie que la trame est du type convenable                               
+                    resolution = (T_Pixy2Resolution*) &Pixy2_buffer[rPointer + PIXY2_NCSHEADERSIZE];
+                                                                                    // Si le checksum et le type sont bon, on mappe le pointeur de résultat sur la FIFO (ligne précédente)                        
+                    etat = idle;                                                    // Et on annoce que la pixy est libre
+                } else cr = -7;         // Type Error                               // Si le type ne correspond pas on signale une erreur
+            }
+            break;
+
+        default :                                                                   // Dans tous les autres cas
+            cr = -2;                    // Busy                                     // On signale que la caméra est occupée.
+            break;
+    }
+    return cr;
+}
+
+
 int PIXY2::pixy2_setCameraBrightness (Byte brightness){return 0;}
 int PIXY2::pixy2_setServos (Word s0, Word s1){return 0;} 
 int PIXY2::pixy2_setLED (Byte red, Byte green, Byte blue){return 0;}