H A / Pixy2_UART
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pixy2.cpp Source File

pixy2.cpp

00001 #include "pixy2.h"
00002 
00003 extern  int sommeDeControle,sommeRecue;
00004 extern Serial pc;
00005 
00006 PIXY2::PIXY2(PinName tx, PinName rx, int debit) : Pixy2_numBlocks(0), Pixy2_numVectors(0), Pixy2_numIntersections(0), Pixy2_numBarcodes(0)
00007 {   
00008     _Pixy2 = new Serial (tx, rx, debit);
00009     _Pixy2->attach (callback(this,&PIXY2::pixy2_getByte));
00010     etat = idle;
00011     Pixy2_buffer = (Byte*) malloc (0x100); 
00012 }
00013 
00014 PIXY2::~PIXY2()
00015 {
00016     free (Pixy2_buffer);
00017 }
00018 
00019 // POUR DEBUG //
00020 T_Pixy2State PIXY2::getEtat()
00021 {
00022     return this->etat;
00023 }
00024 
00025 void PIXY2::affDataSize()
00026 {
00027     pc.printf("dataSize : %d\n\r", this->dataSize);
00028 }
00029 // Pour détail d'une trame (a mettre dans la fct correspondante) :
00030 //pc.printf("pixSync : %d, pixType : %d, pixLength : %d, pixChecksum : %d\n\r", msg->pixSync, msg->pixType, msg->pixLength, msg->pixChecksum);
00031 
00032 /* 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.
00033    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...
00034    Les étapes de fonctionnement sont les suivantes :
00035    
00036    * idle : La caméra n'a pas été solicité => on peut envoyer le message de requête.
00037    * messageSent : La requête a été transmise, mais la réponse n'est pas encore arrivée.
00038    * receivingHeader : Le mot de synchro a été reçu, le reste de l'entête est en cours de réception.
00039    * receivingData : L'entête a été intégralement reçu (et traité) et on est en train de recevoir la payload.
00040    * dataReceived : La réponse a été intégralement reçue et est disponible pour le traitement (et la libération).
00041    
00042    On utilise plusieurs pointeurs : 
00043    * wPointer est le pointeur d'écriture des octets reçus dans le buffer de réception
00044    * hPointer est le pointeur de l'entête du message
00045    * dPointer est le pointeur de la zone de données
00046    
00047    On rajoute une variable : dataSize, qui définit la quantité de données à recevoir (issue de l'entête)
00048    
00049    **** COMMENT CA MARCHE ****
00050    
00051    Au début wPointer = 0. Quand wPointer est supérieur à 1 (donc qu'on a reçu au moins 2 octets), on regarde si on a reçu le code de début de trame 0xC1AF
00052    Si ce n'est pas le cas, on continue de recevoir les octets et on les stock jusqu'à trouver le code de début de trame.
00053    Quand on trouve le code, on enregistre le point de départ (c'est hPointer) comme étant la position actuelle du wPointer-1.
00054    A partir de ça, on attend de recevoir les 6 premiers octets de l'entête :
00055    * start of frame (hPointer et hPointer + 1)
00056    * identification du type (hPointer + 2)
00057    * taille des données (hPointer + 3)
00058    Et ensuite si on a une trame avec un checksum (normal) :
00059    * le checksum (hPointer + 4 et hPointer + 5)
00060    * les données (hPointer + 6 et suivant)
00061    Et si on a une trame sans checksum (pas normal) :
00062    * les données (hPointer + 4 et suivant)
00063    
00064    On continue alors de recevoir des octets jusqu'à ce que wPointer soit égal à dPointer + dataSize - 1
00065    par exemple si la data fait 4 octets et une trame avec checksum, on reçoit tant que wPointer est inférieur à 9 (6 + 4 - 1)
00066    ou pour la même quantité de données mais avec une trame sans checksum 7 (4 + 4 - 1)...
00067    
00068                                           Automate des fonctions.
00069 
00070          appel de la fonction    
00071    /---        publique      ---\ /-------------------- géré par l'interruption -------------------\
00072 
00073     |------|  envoi   |---------|  start  |-----------|  header  |-----------|  trame  |----------|
00074     |      |  ordre   |         |  reçu   | receiving |   reçu   | receiving |  reçue  |   data   |
00075     | Idle |----+---->| msgSent |----+--->|   header  |----+---->|    data   |----+--->| received |---\
00076     |      |          |         |   C1AF  |           |    6o    |           | (data   |          |   |
00077     |------|          |---------|(ou C1AE)|-----------|          |-----------|  size)  |----------|   |
00078        |                                                                                              |
00079        \-------------------<---------------------------+---------------------------<------------------/
00080                                           lecture des données reçues
00081                                                          
00082        \-------------------------------  appel de la fonction publique  ------------------------------/
00083 
00084     Pour l'utilisateur seul l'appel de la fonction publique est nécessaire.
00085     Tant qu'il récupère un code de retour -1, cela signifie que la tâche n'est pas achevée
00086     Quand le code reçu est 0, cela signifie que le résultat est disponible
00087     Toutes les autres valeurs signifient une erreur
00088 */
00089 
00090 void PIXY2::pixy2_getByte ()    // Interruption de la pixy2
00091 {
00092     T_Word                  *buffer;
00093     
00094     Pixy2_buffer[wPointer] = _Pixy2->getc();                                        // On stocke l'octet reçu dans la première case dispo du buffer de réception
00095     
00096     
00097     switch (etat) {
00098         case messageSent :                                                          // Si on a envoyé une requete => on attend un entête
00099             if (wPointer > 0) {                                                     // On attend d'avoir reçu 2 octets
00100                 buffer = (T_Word*) &Pixy2_buffer[wPointer-1];                       // On pointe la structure sur les 2 derniers octets reçus
00101                 if ((buffer->mot == PIXY2_CSSYNC) || (buffer->mot == PIXY2_SYNC)) { // Si c'est un mot d'entête
00102                     etat = receivingHeader;                                         // On passe à l'état réception de l'entête
00103                     hPointer = wPointer - 1;                                        // On initialise le pointeur de l'entête
00104                     if (buffer->mot == PIXY2_SYNC) {
00105                         frameContainChecksum = 0;                                   // Si c'est un entête sans checksum, on mémorise qu'il n'y a pas de checksum à vérifier
00106                         dPointer = hPointer + PIXY2_NCSHEADERSIZE;
00107                     } else {
00108                         frameContainChecksum = 1;                                   // Sinon, on mémorise qu'il y a un checksum à vérifier
00109                         dPointer = hPointer + PIXY2_CSHEADERSIZE;
00110                     }
00111                 }                                                                   // Si on n'a pas de mot d'entête on attend d'en trouver un...
00112             }
00113             break;
00114 
00115         case receivingHeader :                                                      // Si on est en train de recevoir un entête (entre le SYNC et... La fin de l'entête)
00116             if ((frameContainChecksum && ((wPointer - hPointer) == (PIXY2_CSHEADERSIZE - 1))) || (!frameContainChecksum && ((wPointer - hPointer) == (PIXY2_NCSHEADERSIZE - 1)))) {
00117                                                                                     // Si on a reçu 6 octets pour une trame avec checksum ou 4 pour une trame sans checksum, c'est à dire un entête complet
00118                 etat = receivingData;                                               // On dit que l'on va de recevoir des données
00119                 dataSize = Pixy2_buffer[hPointer + 3];                              // On enregistre la taille de la payload
00120                 if (dataSize == 0)                                                  // Si on ne doit recevoir qu'un entête, on a terminé
00121                     etat = idle;                                                    // On revient à l'état d'attente d'ordre
00122             }    
00123             break;
00124 
00125         case receivingData :                                                        // Si on est en train de recevoir des données.
00126             if (wPointer == ((dataSize - 1) + dPointer)) {                          // Quand on a reçu toutes les données
00127                 etat = dataReceived;                                                // On dit que c'est OK pour leur traitement         
00128             }
00129             break;
00130 
00131         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.
00132             break;
00133     }
00134     wPointer++;                                                                     // on pointe la case suivante du buffer de réception
00135 
00136 }
00137 
00138 T_pixy2ErrorCode PIXY2::pixy2_sndGetVersion (void){
00139     T_pixy2SendBuffer   msg;
00140     int                 i = 0, dataSize = 0;
00141     msg.frame.header.pixSync = PIXY2_SYNC;
00142     msg.frame.header.pixType = PIXY2_ASK_VERS;
00143     msg.frame.header.pixLength = dataSize;
00144     do {
00145         while(!_Pixy2->writable());
00146         _Pixy2->putc(msg.data[i]);
00147         i++;
00148     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00149     return PIXY2_OK;
00150 }
00151 
00152 T_pixy2ErrorCode PIXY2::pixy2_sndGetResolution (void){
00153     T_pixy2SendBuffer   msg;
00154     int                 i = 0, dataSize = 1;
00155     msg.frame.header.pixSync = PIXY2_SYNC;
00156     msg.frame.header.pixType = PIXY2_ASK_RESOL;
00157     msg.frame.header.pixLength = dataSize;
00158     msg.frame.data[0] = 0;
00159     do {
00160         while(!_Pixy2->writable());
00161         _Pixy2->putc(msg.data[i]);
00162         i++;
00163     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00164     return PIXY2_OK;
00165 }
00166 
00167 T_pixy2ErrorCode PIXY2::pixy2_sndSetCameraBrightness (Byte brightness){
00168     T_pixy2SendBuffer   msg;
00169     int                 i = 0, dataSize = 1;
00170     msg.frame.header.pixSync = PIXY2_SYNC;
00171     msg.frame.header.pixType = PIXY2_SET_BRIGHT;
00172     msg.frame.header.pixLength = dataSize;
00173     msg.frame.data[0] = brightness;
00174     do {
00175         while(!_Pixy2->writable());
00176         _Pixy2->putc(msg.data[i]);
00177         i++;
00178     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00179     return PIXY2_OK;
00180 }
00181 
00182 T_pixy2ErrorCode PIXY2::pixy2_sndSetServo (Word s0, Word s1){
00183     T_pixy2SendBuffer   msg;
00184     int                 i = 0, dataSize = 4;
00185     T_Word              tmp;
00186     msg.frame.header.pixSync = PIXY2_SYNC;
00187     msg.frame.header.pixType = PIXY2_SET_SERVOS;
00188     msg.frame.header.pixLength = dataSize;
00189     tmp.mot = s0;
00190     msg.frame.data[0] = tmp.octet[0];
00191     msg.frame.data[1] = tmp.octet[1];
00192     tmp.mot = s1;
00193     msg.frame.data[2] = tmp.octet[0];
00194     msg.frame.data[3] = tmp.octet[1];
00195     do {
00196         while(!_Pixy2->writable());
00197         _Pixy2->putc(msg.data[i]);
00198         i++;
00199     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00200     return PIXY2_OK;
00201 }
00202 
00203 T_pixy2ErrorCode PIXY2::pixy2_sndSetLED (Byte red, Byte green, Byte blue){
00204     T_pixy2SendBuffer   msg;
00205     int                 i = 0, dataSize = 3;
00206     msg.frame.header.pixSync = PIXY2_SYNC;
00207     msg.frame.header.pixType = PIXY2_SET_LED;
00208     msg.frame.header.pixLength = dataSize;
00209     msg.frame.data[0] = red;
00210     msg.frame.data[1] = green;
00211     msg.frame.data[2] = blue;
00212     do {
00213         while(!_Pixy2->writable());
00214         _Pixy2->putc(msg.data[i]);
00215         i++;
00216     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00217     return PIXY2_OK;
00218 }
00219 
00220 T_pixy2ErrorCode PIXY2::pixy2_sndSetLamp (Byte upper, Byte lower){
00221     T_pixy2SendBuffer   msg;
00222     int                 i = 0, dataSize = 2;
00223     msg.frame.header.pixSync = PIXY2_SYNC;
00224     msg.frame.header.pixType = PIXY2_SET_LAMP;
00225     msg.frame.header.pixLength = dataSize;
00226     msg.frame.data[0] = upper;
00227     msg.frame.data[1] = lower;
00228     do {
00229         while(!_Pixy2->writable());
00230         _Pixy2->putc(msg.data[i]);
00231         i++;
00232     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00233     return PIXY2_OK;
00234 }
00235 
00236 T_pixy2ErrorCode PIXY2::pixy2_sndGetFPS (void){
00237     T_pixy2SendBuffer   msg;
00238     int                 i = 0, dataSize = 0;
00239     msg.frame.header.pixSync = PIXY2_SYNC;
00240     msg.frame.header.pixType = PIXY2_ASK_FPS;
00241     msg.frame.header.pixLength = dataSize;
00242     do {
00243         while(!_Pixy2->writable());
00244         _Pixy2->putc(msg.data[i]);
00245         i++;
00246     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00247     return PIXY2_OK;
00248 }
00249 
00250 T_pixy2ErrorCode PIXY2::pixy2_sndGetBlocks (Byte sigmap, Byte maxBloc){
00251     T_pixy2SendBuffer   msg;
00252     int                 i = 0, dataSize = 2;
00253     msg.frame.header.pixSync = PIXY2_SYNC;
00254     msg.frame.header.pixType = PIXY2_ASK_BLOC;
00255     msg.frame.header.pixLength = dataSize;
00256     msg.frame.data[0] = sigmap;
00257     msg.frame.data[1] = maxBloc;
00258     do {
00259         while(!_Pixy2->writable());
00260         _Pixy2->putc(msg.data[i]);
00261         i++;
00262     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00263     return PIXY2_OK;
00264 }
00265 
00266 T_pixy2ErrorCode PIXY2::pixy2_sndGetLineFeature (Byte type, Byte feature){
00267     T_pixy2SendBuffer   msg;
00268     int                 i = 0, dataSize = 2;
00269     msg.frame.header.pixSync = PIXY2_SYNC;
00270     msg.frame.header.pixType = PIXY2_ASK_LINE;
00271     msg.frame.header.pixLength = dataSize;
00272     msg.frame.data[0] = type;
00273     msg.frame.data[1] = feature;
00274     do {
00275         while(!_Pixy2->writable());
00276         _Pixy2->putc(msg.data[i]);
00277         i++;
00278     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00279     return PIXY2_OK;
00280 }
00281 
00282 T_pixy2ErrorCode PIXY2::pixy2_sndSetMode (Byte mode){
00283     T_pixy2SendBuffer   msg;
00284     int                 i = 0, dataSize = 1;
00285     msg.frame.header.pixSync = PIXY2_SYNC;
00286     msg.frame.header.pixType = PIXY2_SET_MODE;
00287     msg.frame.header.pixLength = dataSize;
00288     msg.frame.data[0] = mode;
00289     do {
00290         while(!_Pixy2->writable());
00291         _Pixy2->putc(msg.data[i]);
00292         i++;
00293     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00294     return PIXY2_OK;
00295 }
00296 
00297 T_pixy2ErrorCode PIXY2::pixy2_sndSetNextTurn (Word angle){
00298     T_pixy2SendBuffer   msg;
00299     int                 i = 0, dataSize = 2;
00300     T_Word              tmp;
00301     tmp.mot = angle;
00302     msg.frame.header.pixSync = PIXY2_SYNC;
00303     msg.frame.header.pixType = PIXY2_SET_TURN;
00304     msg.frame.header.pixLength = dataSize;
00305     tmp.mot = angle;
00306     msg.frame.data[0] = tmp.octet[0];
00307     msg.frame.data[1] = tmp.octet[1];
00308     do {
00309         while(!_Pixy2->writable());
00310         _Pixy2->putc(msg.data[i]);
00311         i++;
00312     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00313     return PIXY2_OK;
00314 }
00315 
00316 T_pixy2ErrorCode PIXY2::pixy2_sndSetDefaultTurn (Word angle){
00317     T_pixy2SendBuffer   msg;
00318     int                 i = 0, dataSize = 2;
00319     T_Word              tmp;
00320     tmp.mot = angle;
00321     msg.frame.header.pixSync = PIXY2_SYNC;
00322     msg.frame.header.pixType = PIXY2_SET_DEFTURN;
00323     msg.frame.header.pixLength = dataSize;
00324     tmp.mot = angle;
00325     msg.frame.data[0] = tmp.octet[0];
00326     msg.frame.data[1] = tmp.octet[1];
00327     do {
00328         while(!_Pixy2->writable());
00329         _Pixy2->putc(msg.data[i]);
00330         i++;
00331     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00332     return PIXY2_OK;
00333 }
00334 
00335 T_pixy2ErrorCode PIXY2::pixy2_sndSetVector (Byte vectorIndex){
00336     T_pixy2SendBuffer   msg;
00337     int                 i = 0, dataSize = 1;
00338     msg.frame.header.pixSync = PIXY2_SYNC;
00339     msg.frame.header.pixType = PIXY2_SET_VECTOR;
00340     msg.frame.header.pixLength = dataSize;
00341     msg.frame.data[0] = vectorIndex;
00342     do {
00343         while(!_Pixy2->writable());
00344         _Pixy2->putc(msg.data[i]);
00345         i++;
00346     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00347     return PIXY2_OK;
00348 }
00349 
00350 T_pixy2ErrorCode PIXY2::pixy2_sndReverseVector (void){
00351     T_pixy2SendBuffer   msg;
00352     int                 i = 0, dataSize = 0;
00353     msg.frame.header.pixSync = PIXY2_SYNC;
00354     msg.frame.header.pixType = PIXY2_SET_REVERSE;
00355     msg.frame.header.pixLength = dataSize;
00356     do {
00357         while(!_Pixy2->writable());
00358         _Pixy2->putc(msg.data[i]);
00359         i++;
00360     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00361     return PIXY2_OK;
00362 }
00363 
00364 T_pixy2ErrorCode PIXY2::pixy2_sndGetRGB (Word x, Word y, Byte saturate){
00365     T_pixy2SendBuffer   msg;
00366     int                 i = 0, dataSize = 5;
00367     msg.frame.header.pixSync = PIXY2_SYNC;
00368     msg.frame.header.pixType = PIXY2_ASK_VIDEO;
00369     msg.frame.header.pixLength = dataSize;
00370     msg.frame.data[0] = x;
00371     msg.frame.data[1] = y;
00372     msg.frame.data[2] = saturate;
00373     do {
00374         while(!_Pixy2->writable());
00375         _Pixy2->putc(msg.data[i]);
00376         i++;
00377     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00378     return PIXY2_OK;
00379 }
00380 
00381 /*  La fonction est bloquante à l'envoi (pas vraiment le choix), mais elle est non bloquante en réception. On essayera de faire une fonction non bloquante en envoi avec write, mais c'est pas la priorité.
00382 Le principe c'est de stocker dans un buffer circulaire les données au fur et à mesure qu'elle sont reçues et de traiter uniquement en castant les infos. Pour cela, il faut recevoir et stocker. */
00383 
00384 T_pixy2ErrorCode PIXY2::pixy2_getVersion (T_pixy2Version **ptrVersion){
00385 
00386     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00387     T_pixy2ErrorCode    cr = PIXY2_OK;
00388     
00389     switch (etat) {
00390         case idle :                                                                 // Si la caméra est inactive
00391             wPointer = 0;                                                           // On remonte en haut du buffer
00392             cr = PIXY2::pixy2_sndGetVersion();                                      // On envoie la trame de demande de la version
00393             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00394             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00395             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00396             break;
00397             
00398         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00399             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00400                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00401                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00402                 }
00403             }
00404             if (msg->pixType == PIXY2_REP_VERS) {                                   // On vérifie que la trame est du type convenable (REPONSE VERSION)
00405                 *ptrVersion =   (T_pixy2Version*) &Pixy2_buffer[dPointer];          // On mappe le pointeur de structure sur le buffer de réception.         
00406             } else {                                                                // Si ce n'est pas le bon type
00407                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00408                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00409                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00410             }
00411             etat = idle;                                                            // On annonce que la pixy est libre
00412             break;
00413 
00414         default :                                                                   // Dans tous les autres cas
00415             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00416             break;
00417     }
00418     return cr;
00419 }
00420 
00421 T_pixy2ErrorCode PIXY2::pixy2_getResolution (T_pixy2Resolution **ptrResolution){
00422 
00423     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00424     T_pixy2ErrorCode    cr = PIXY2_OK;
00425     
00426     switch (etat) {
00427         case idle :                                                                 // Si la caméra est inactive
00428             wPointer = 0;                                                           // On remonte en haut du buffer
00429             cr = PIXY2::pixy2_sndGetResolution();                                   // On envoie la trame de demande de la résolution
00430             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00431             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00432             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00433             break;
00434             
00435         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00436             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00437                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00438                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00439                 }
00440             }
00441             if (msg->pixType == PIXY2_REP_RESOL) {                                  // On vérifie que la trame est du type convenable (REPONSE RESOLUTION)
00442                 *ptrResolution = (T_pixy2Resolution*) &Pixy2_buffer[dPointer];      // On mappe le pointeur de structure sur le buffer de réception.
00443             } else {                                                                // Si ce n'est pas le bon type
00444                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00445                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00446                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00447             }
00448             etat = idle;                                                            // On annoce que la pixy est libre
00449             break;
00450 
00451         default :                                                                   // Dans tous les autres cas
00452             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00453             break;
00454     }
00455     return cr;
00456 }
00457 
00458 T_pixy2ErrorCode PIXY2::pixy2_setCameraBrightness (Byte brightness){
00459 
00460     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00461     T_pixy2ErrorCode    cr = PIXY2_OK;
00462     
00463     switch (etat) {
00464         case idle :                                                                 // Si la caméra est inactive
00465             wPointer = 0;                                                           // On remonte en haut du buffer
00466             cr = PIXY2::pixy2_sndSetCameraBrightness (brightness);                  // On envoie la trame de règlage de la luminosité
00467             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00468             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00469             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00470             break;
00471             
00472         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00473             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00474                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00475                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00476                 }
00477             }
00478             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00479                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00480                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00481             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00482             etat = idle;                                                            // On annoce que la pixy est libre
00483             break;
00484 
00485         default :                                                                   // Dans tous les autres cas
00486             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00487             break;
00488     }
00489     return cr;
00490 }
00491 
00492 T_pixy2ErrorCode PIXY2::pixy2_setServos (Word s0, Word s1){
00493 
00494     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00495     T_pixy2ErrorCode    cr = PIXY2_OK;
00496     
00497     switch (etat) {
00498         case idle :                                                                 // Si la caméra est inactive
00499             wPointer = 0;                                                           // On remonte en haut du buffer
00500             cr = PIXY2::pixy2_sndSetServo (s0, s1);                                 // On envoie la trame de règlage des servos moteurs
00501             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00502             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00503             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00504             break;
00505             
00506         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00507             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00508                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00509                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00510                 }
00511             }
00512             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00513                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00514                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00515             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00516             etat = idle;                                                            // On annoce que la pixy est libre
00517             break;
00518 
00519         default :                                                                   // Dans tous les autres cas
00520             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00521             break;
00522     }
00523     return cr;
00524 }
00525 
00526 T_pixy2ErrorCode PIXY2::pixy2_setLED (Byte red, Byte green, Byte blue){
00527 
00528     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00529     T_pixy2ErrorCode    cr = PIXY2_OK;
00530     
00531     switch (etat) {
00532         case idle :                                                                 // Si la caméra est inactive
00533             wPointer = 0;                                                           // On remonte en haut du buffer
00534             cr = PIXY2::pixy2_sndSetLED (red, green, blue);                         // On envoie la trame de règlage des composantes de la LED RGB
00535             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00536             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00537             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00538             break;
00539             
00540         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00541             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00542                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00543                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00544                 }
00545             }
00546             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00547                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00548                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00549             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00550             etat = idle;                                                            // On annoce que la pixy est libre
00551             break;
00552 
00553         default :                                                                   // Dans tous les autres cas
00554             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00555             break;
00556     }
00557     return cr;
00558 }
00559 
00560 T_pixy2ErrorCode PIXY2::pixy2_setLamp (Byte upper, Byte lower){
00561 
00562     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00563     T_pixy2ErrorCode    cr = PIXY2_OK;
00564     
00565     switch (etat) {
00566         case idle :                                                                 // Si la caméra est inactive
00567             wPointer = 0;                                                           // On remonte en haut du buffer
00568             cr = PIXY2::pixy2_sndSetLamp (upper, lower);                            // On envoie la trame de règlage d'allumage des lumières de contraste
00569             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00570             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00571             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00572             break;
00573             
00574         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00575             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00576                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00577                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00578                 }
00579             }
00580             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00581                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00582                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00583             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00584             etat = idle;                                                            // On annoce que la pixy est libre
00585             break;
00586 
00587         default :                                                                   // Dans tous les autres cas
00588             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00589             break;
00590     }
00591     return cr;
00592 }
00593 
00594 T_pixy2ErrorCode PIXY2::pixy2_getFPS (T_pixy2ReturnCode **framerate){
00595 
00596     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00597     T_pixy2ErrorCode    cr = PIXY2_OK;
00598     
00599     switch (etat) {
00600         case idle :                                                                 // Si la caméra est inactive
00601             wPointer = 0;                                                           // On remonte en haut du buffer
00602             cr = PIXY2::pixy2_sndGetFPS();                                          // On envoie la trame de demande du Framerate
00603             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00604             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00605             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00606             break;
00607             
00608         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00609             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00610                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00611                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00612                 }
00613             }
00614             if (msg->pixType == PIXY2_REP_FPS) {                                    // On vérifie que la trame est du type convenable (REPONSE FPS)
00615                 *framerate = (T_pixy2ReturnCode*) &Pixy2_buffer[dPointer];           // On mappe le pointeur de structure sur le buffer de réception.
00616             } else {                                                                // Si ce n'est pas le bon type
00617                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00618                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00619                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00620             }
00621             etat = idle;                                                            // On annoce que la pixy est libre
00622             break;
00623 
00624         default :                                                                   // Dans tous les autres cas
00625             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00626             break;
00627     }
00628     return cr;
00629 }
00630 
00631 T_pixy2ErrorCode PIXY2::pixy2_getBlocks (Byte sigmap, Byte maxBloc){
00632 
00633     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00634     T_pixy2ErrorCode    cr = PIXY2_OK;
00635     
00636     switch (etat) {
00637         case idle :                                                                 // Si la caméra est inactive
00638             wPointer = 0;                                                           // On remonte en haut du buffer
00639             cr = PIXY2::pixy2_sndGetBlocks(sigmap, maxBloc);                        // On envoie la trame de demande de blocs de couleur
00640             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00641             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00642             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00643             break;
00644             
00645         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00646             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00647                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00648                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00649                 }
00650             }
00651             if (msg->pixType == PIXY2_REP_BLOC) {                                   // On vérifie que la trame est du type convenable (REPONSE BLOCS)
00652                 Pixy2_blocks = (T_pixy2Bloc*) &Pixy2_buffer[dPointer];              // On mappe le pointeur de structure sur le buffer de réception.
00653                 Pixy2_numBlocks = dataSize / sizeof(T_pixy2Bloc);                   // On indique le nombre de blocs reçus
00654             } else {                                                                // Si ce n'est pas le bon type
00655                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00656                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00657                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00658             }
00659             etat = idle;                                                            // On annoce que la pixy est libre
00660             break;
00661 
00662         default :                                                                   // Dans tous les autres cas
00663             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00664             break;
00665     }
00666     return cr;
00667 }
00668 
00669 T_pixy2ErrorCode PIXY2::pixy2_getFeatures (){
00670 
00671     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00672     T_pixy2ErrorCode    cr = PIXY2_OK;
00673     T_pixy2LineFeature* lineFeature;
00674     int                 fPointer;                                                   // Pointeur sur une feature entière
00675     int                 fdPointer;                                                  // Pointeur sur un élément à l'intérieur d'une feature
00676 
00677     if (frameContainChecksum) {                                                     // Si la trame contient un checksum
00678         if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {                // On lance la validation du checksum
00679             return PIXY2_BAD_CHECKSUM;                                              // Si le checksum est faux on retourne une erreur
00680         }
00681     }
00682     if (msg->pixType == PIXY2_REP_LINE) {                                       // On vérifie que la trame est du type convenable (REPONSE LIGNE)
00683         fPointer = dPointer;                                                        // On pointe sur la premiere feature
00684         do {
00685             lineFeature = (T_pixy2LineFeature*) &Pixy2_buffer[fPointer];            // On mappe le pointeur de structure sur le buffer de réception des features.
00686             if (lineFeature->fType == PIXY2_VECTOR) {                               // On regarde si le type est vecteur
00687                 Pixy2_numVectors = lineFeature->fLength / sizeof(T_pixy2Vector);    // Si oui, on compte combien il y a de vecteurs
00688                 fdPointer = fPointer + 2;                                           // On pointe sur le premier élément de la feature
00689                 Pixy2_vectors = (T_pixy2Vector*) &Pixy2_buffer[fdPointer];          // On mappe le résultat
00690                 fPointer += lineFeature->fLength + 2;                               // On déplace le pointeur de données et on recommence
00691                 cr |= PIXY2_VECTOR;
00692             }
00693             if (lineFeature->fType == PIXY2_INTERSECTION) {                         // On regarde si le type est intersection
00694                 Pixy2_numIntersections = lineFeature->fLength / sizeof(T_pixy2Intersection);
00695                                                                                     // Si oui, on compte combien il y a d'intersections
00696                 fdPointer = fPointer + 2;                                           // On pointe sur le premier élément de la feature                                                                    
00697                 Pixy2_intersections = (T_pixy2Intersection*) &Pixy2_buffer[fdPointer];
00698                                                                                     // On mappe le résultat sur l'entête de l'intersection
00699                 fPointer += lineFeature->fLength + 2;                               // On déplace le pointeur de données et on recommence
00700                 cr |= PIXY2_INTERSECTION;
00701             }
00702             if (lineFeature->fType == PIXY2_BARCODE) {                              // On regarde si le type est codebarre
00703                 Pixy2_numBarcodes = lineFeature->fLength / sizeof(T_pixy2BarCode);
00704                                                                                     // Si oui, on compte combien il y a de codebarre
00705                 fdPointer = fPointer + 2;                                           // On pointe sur le premier élément de la feature
00706                 Pixy2_barcodes = (T_pixy2BarCode*) &Pixy2_buffer[fdPointer];        // On mappe le résultat
00707                 fPointer += lineFeature->fLength + 2;                               // On déplace le pointeur de données et on recommence
00708                 cr |= PIXY2_BARCODE;
00709             }
00710         } while(fPointer < ((dataSize - 1) + dPointer));                            // Tant qu'il y a des données à traiter
00711     } else {                                                                        // Si ce n'est pas le bon type
00712         if (msg->pixType == PIXY2_REP_ERROR) {                                      // Cela pourrait être une trame d'erreur ou quand on ne reçoit rien
00713             cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                      // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00714         } else cr = PIXY2_TYPE_ERROR;                                               // Si le type ne correspond à rien de normal on signale une erreur de type.
00715     }
00716     etat = idle;                                                                    // On annoce que la pixy est libre
00717     return cr;
00718 }
00719 
00720 
00721 T_pixy2ErrorCode PIXY2::pixy2_getMainFeature (Byte features){
00722 
00723     T_pixy2ErrorCode    cr = PIXY2_OK;
00724     
00725     switch (etat) {
00726         case idle :                                                                 // Si la caméra est inactive
00727             wPointer = 0;                                                           // On remonte en haut du buffer
00728             cr = PIXY2::pixy2_sndGetLineFeature(0, features);                      // On envoie la trame de demande de suivi de ligne
00729             if (cr!= PIXY2_OK) return cr;                                          // S'il y a une erreur lors de l'envoi on ejecte !
00730             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00731             cr = PIXY2_BUSY;                                                    // On signale à l'utilisateur que la caméra est maintenant occupée
00732             break;
00733             
00734         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00735             cr = PIXY2::pixy2_getFeatures();                                        // On appelle la fonction de traitement.
00736             break;
00737 
00738         default :                                                                   // Dans tous les autres cas
00739             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00740             break;
00741     }
00742     return cr;
00743 }
00744 
00745 T_pixy2ErrorCode PIXY2::pixy2_getAllFeature (Byte features){
00746     T_pixy2ErrorCode    cr = PIXY2_OK;
00747 
00748     switch (etat) {
00749         case idle :                                                                 // Si la caméra est inactive
00750             wPointer = 0;                                                           // On remonte en haut du buffer
00751             cr = PIXY2::pixy2_sndGetLineFeature(1, features);                       // On envoie la trame de demande de suivi de ligne
00752             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00753             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00754             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00755             break;
00756 
00757         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00758             cr = PIXY2::pixy2_getFeatures();                                        // On appelle la fonction de traitement.
00759             break;
00760 
00761         default :                                                                   // Dans tous les autres cas
00762             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00763             break;
00764     }
00765     return cr;
00766 }
00767 
00768 T_pixy2ErrorCode PIXY2::pixy2_setMode (Byte mode)
00769 {
00770     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00771     T_pixy2ErrorCode    cr = PIXY2_OK;
00772 
00773     switch (etat) {
00774         case idle :                                                                 // Si la caméra est inactive
00775             wPointer = 0;                                                           // On remonte en haut du buffer
00776             cr = PIXY2::pixy2_sndSetMode (mode);                                    // On envoie la trame de règlage du mode de fonctionnement du suivi de ligne
00777             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00778             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00779             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00780             break;
00781 
00782         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00783             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00784                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00785                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00786                 }
00787             }
00788             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00789                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00790                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00791             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00792             etat = idle;                                                            // On annoce que la pixy est libre
00793             break;
00794 
00795         default :                                                                   // Dans tous les autres cas
00796             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00797             break;
00798     }
00799     return cr;
00800 }
00801 
00802 T_pixy2ErrorCode PIXY2::pixy2_setNextTurn (sWord angle)
00803 {
00804     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00805     T_pixy2ErrorCode    cr = PIXY2_OK;
00806 
00807     switch (etat) {
00808         case idle :                                                                 // Si la caméra est inactive
00809             wPointer = 0;                                                           // On remonte en haut du buffer
00810             cr = PIXY2::pixy2_sndSetNextTurn (angle);                               // On envoie la trame de choix de l'angle du prochain virage
00811             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00812             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00813             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00814             break;
00815 
00816         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00817             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00818                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00819                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00820                 }
00821             }
00822             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00823                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00824                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00825             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00826             etat = idle;                                                            // On annoce que la pixy est libre
00827             break;
00828 
00829         default :                                                                   // Dans tous les autres cas
00830             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00831             break;
00832     }
00833     return cr;
00834 }
00835 
00836 T_pixy2ErrorCode PIXY2::pixy2_setDefaultTurn (sWord angle)
00837 {
00838     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00839     T_pixy2ErrorCode    cr = PIXY2_OK;
00840 
00841     switch (etat) {
00842         case idle :                                                                 // Si la caméra est inactive
00843             wPointer = 0;                                                           // On remonte en haut du buffer
00844             cr = PIXY2::pixy2_sndSetDefaultTurn (angle);                            // On envoie la trame de choix de l'angle par défaut des virages
00845             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00846             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00847             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00848             break;
00849 
00850         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00851             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00852                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00853                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00854                 }
00855             }
00856             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00857                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00858                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00859             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00860             etat = idle;                                                            // On annoce que la pixy est libre
00861             break;
00862 
00863         default :                                                                   // Dans tous les autres cas
00864             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00865             break;
00866     }
00867     return cr;
00868 }
00869 
00870 T_pixy2ErrorCode PIXY2::pixy2_setVector (Byte vectorIndex)
00871 {
00872     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00873     T_pixy2ErrorCode    cr = PIXY2_OK;
00874 
00875     switch (etat) {
00876         case idle :                                                                 // Si la caméra est inactive
00877             wPointer = 0;                                                           // On remonte en haut du buffer
00878             cr = PIXY2::pixy2_sndSetVector (vectorIndex);                           // On envoie la trame de choix du vecteur à suivre
00879             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00880             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00881             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00882             break;
00883 
00884         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00885             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00886                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00887                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00888                 }
00889             }
00890             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00891                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00892                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00893             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00894             etat = idle;                                                            // On annoce que la pixy est libre
00895             break;
00896 
00897         default :                                                                   // Dans tous les autres cas
00898             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00899             break;
00900     }
00901     return cr;
00902 }
00903 
00904 
00905 T_pixy2ErrorCode PIXY2::pixy2_ReverseVector (void)
00906 {
00907     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00908     T_pixy2ErrorCode    cr = PIXY2_OK;
00909 
00910     switch (etat) {
00911         case idle :                                                                 // Si la caméra est inactive
00912             wPointer = 0;                                                           // On remonte en haut du buffer
00913             cr = PIXY2::pixy2_sndReverseVector ();                                  // On envoie la trame d'inversion de l'image (haut en bas et bas en haut)
00914             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00915             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00916             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00917             break;
00918 
00919         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00920             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00921                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00922                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00923                 }
00924             }
00925             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00926                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00927                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00928             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00929             etat = idle;                                                            // On annoce que la pixy est libre
00930             break;
00931 
00932         default :                                                                   // Dans tous les autres cas
00933             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00934             break;
00935     }
00936     return cr;
00937 }
00938 
00939 T_pixy2ErrorCode PIXY2::pixy2_getRGB (Word x, Word y, Byte saturate, T_pixy2Pixel **pixel){
00940 
00941     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00942     T_pixy2ErrorCode    cr = PIXY2_OK;
00943     
00944     switch (etat) {
00945         case idle :                                                                 // Si la caméra est inactive
00946             wPointer = 0;                                                           // On remonte en haut du buffer
00947             cr = PIXY2::pixy2_sndGetRGB(x, y, saturate);                            // On envoie la trame de demande de la couleur (RGB) d'un carée de pixel
00948             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00949             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00950             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00951             break;
00952             
00953         case dataReceived :                                                      // Quand on a reçu l'intégralité du message
00954             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00955                 if (pixy2_validateChecksum (&Pixy2_buffer[hPointer]) != 0) {        // On lance la validation du checksum
00956                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00957                 }
00958             }
00959             if (msg->pixType == PIXY2_REP_ACK) {                                    // On vérifie que la trame est du type convenable (REPONSE ACK)
00960                 *pixel = (T_pixy2Pixel*) &Pixy2_buffer[dPointer];                    // On mappe le pointeur de structure sur le buffer de réception.
00961             } else {                                                                // Si ce n'est pas le bon type
00962                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00963                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00964                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00965             }
00966             etat = idle;                                                            // On annoce que la pixy est libre
00967             break;
00968 
00969         default :                                                                   // Dans tous les autres cas
00970             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00971             break;
00972     }
00973     return cr;
00974 }
00975 
00976 
00977 
00978 T_pixy2ErrorCode PIXY2::pixy2_validateChecksum (Byte* tab){
00979     Word    i, sum = 0;
00980     T_Word  *tmp;
00981     
00982     for (i=0; i<*(tab+3);i++)   sum = sum + *(tab + PIXY2_CSHEADERSIZE + i);
00983     tmp = (T_Word*) (tab+4);
00984     
00985     if (tmp->mot == sum) return PIXY2_OK;
00986     else {
00987         if (_DEBUG_) {
00988             sommeDeControle = sum;
00989             sommeRecue = tmp->mot;
00990         }
00991         return PIXY2_BAD_CHECKSUM;
00992     }
00993 }