pixy2 smart camera library www.pixycam.com
Pixy2 Library project (using UART interface)
Diff: pixy2.cpp
- 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;}