programme à analyser pendant le cours théorique

Dependencies:   X_NUCLEO_6180XA1 mbed

Fork of 247-436-M1-S2-LAB-F302R8 by Yves Roy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "XNucleo6180XA1.h"
00003 #include <string.h>
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include <assert.h>
00007 
00008 //BRANCHEMENTS:
00009 // Ni le Nucleo ni le vl6180x n'ont de "pullup" pour supporter le I2C.
00010 // Il faut ajouter des résistances de 4.7k
00011 // Le vl6180x contient un microcontôleur qui doit être remis à zéro au démarrage
00012 // Cette remise à zéro se fait en mettant temporairement la broche gpio à la masse.
00013 // Un schéma de connexion sommaire suit:
00014 //    __________
00015 //   | VL6180X  |                    
00016 //   |          |
00017 //   scl sda  gnd
00018 //   nc  gpio 3.3v
00019 //   |__________|
00020 
00021 //   _______________________
00022 //  |                       |
00023 //  |    NUCLEO f302r8      |
00024 //  | oo                 oo | 
00025 //  | oo             scl-oo |
00026 //  | oo             sda-oo |
00027 //  | oo                 oo |
00028 //  | oo             gnd-oo |
00029 //  | oo                 oo |
00030 //  | oo            gpio-oo |
00031 //  | oo-3.3V            oo |
00032 //             ...
00033 //  | oo                 oo |
00034 //  | cn7              cn10 | 
00035 //  |_______________________|
00036 
00037 // connexions:
00038 // vl6180x.3.3v <------> nucleo.3.3V
00039 // Vl6180x.scl <--------> nucleo.scl <-----> 4.7k <------> 3.3v  (pullup requise)
00040 // Vl6180x.sda <--------> nucleo.sda <-----> 4.7k <------> 3.3v  (pullup requise)
00041 // VL6180X.gpio <-------> nucleo.gpio (requis pour faire un "reset" du vl6180x au début)
00042 
00043 
00044 //options de compilation
00045 //#define TEST
00046 
00047 //intégration
00048 // représentation
00049 // G: gauche, D: droit, H: haut, B: bas
00050 // E: écran, T: touch
00051 // Ecran:
00052 //  (XE_G,YE_H)  ___  (XE_D,YE_H)
00053 //              |   |
00054 //              |   |
00055 //  (XE_G,YE_B) |___| (XE_G,YE_B)
00056 //
00057 // représentation du touch
00058 //  (XT_G,YT_H)  ___  (XT_D,YT_H)
00059 //              |   |
00060 //              |   |
00061 //  (XT_G,YT_B) |___| (XT_G,YT_B)
00062 
00063 // équations pour conversion
00064 // XT: x touch lu, YT: y touch lu, XE: x ecran, YE: y ecran
00065 // XE = (XE_D - XE_G)/(XT_D - XT_G)*(XT - XT_G) + XE_G
00066 // YE = (YE_H - YE_B)/(YT_H - YT_B)*(YT - YT_G) + YE_G
00067 
00068 // l'application présente 3 boutons et une surface de dessin
00069 // bouton noir: effacer
00070 // bouton rouge: dessiner en rouge
00071 // bouton blanc: dessiner en blanc
00072 
00073 //touchscreen
00074 #define IDLE    1
00075 #define ACTIVE  0
00076 #define COMMAND 0
00077 #define DATA    1
00078 
00079 #define YP A3
00080 #define XM A2 
00081 #define YM D9  
00082 #define XP D8 
00083 
00084 #define TOUCH_SEUIL_HAUT    3000
00085 #define TOUCH_SEUIL_BAS     16
00086 
00087 
00088 #define TFTWIDTH  240
00089 #define TFTHEIGHT 320
00090 
00091 #define LCD_CS A3
00092 #define LCD_CD A2
00093 #define LCD_WR A1
00094 #define LCD_RD A0
00095 #define LCD_RESET A4
00096 
00097 #define TFT_NORTH SPFD5408_MADCTL_MY | SPFD5408_MADCTL_BGR
00098 
00099 #define BLACK   0x0000
00100 #define BLUE    0x001F
00101 #define RED     0xF800
00102 #define GREEN   0x07E0
00103 #define CYAN    0x07FF
00104 #define MAGENTA 0xF81F
00105 #define YELLOW  0xFFE0
00106 #define WHITE   0xFFFF
00107 
00108 #define SPFD5408_SOFTRESET          0x01
00109 #define SPFD5408_SLEEPOUT           0x11
00110 
00111 #define SPFD5408_DISPLAYON          0x29
00112 #define SPFD5408_COLADDRSET         0x2A
00113 #define SPFD5408_PAGEADDRSET        0x2B
00114 #define SPFD5408_MEMORYWRITE        0x2C
00115 #define SPFD5408_PIXELFORMAT        0x3A
00116 #define SPFD5408_FRAMECONTROL       0xB1
00117 #define SPFD5408_MEMCONTROL         0x36
00118 #define SPFD5408_MADCTL_MY          0x80
00119 #define SPFD5408_MADCTL_BGR         0x08
00120 
00121 #define IDLE    1
00122 #define ACTIVE  0
00123 #define COMMAND 0
00124 #define DATA    1
00125 
00126 #define TEMPS   40
00127 
00128 //VL6180X
00129 #define VL6180X_I2C_SDA   D14 
00130 #define VL6180X_I2C_SCL   D15 
00131 
00132 #define VL6180X_I2C_SDA_MODE    PullUp
00133 #define VL6180X_I2C_SCL_MODE    PullUp
00134 
00135 
00136 //integration
00137 
00138 #define XE_G    0
00139 #define XE_D    240
00140 #define YE_H    0
00141 #define YE_B    320
00142 #define XT_G    3700
00143 #define XT_D    600
00144 #define YT_H    600
00145 #define YT_B    3700
00146 
00147 #define MODE_COULEUR_CONSTANTE  0
00148 #define MODE_COULEUR_VARIABLE   1
00149 //definitions de variables
00150 //touchscreen
00151 uint16_t x;
00152 uint16_t y;
00153 uint16_t z;
00154 
00155 //tftspfd5408
00156 DigitalOut pinRD(LCD_RD);       //PA_0;
00157 DigitalOut pinWR(LCD_WR);       //PA_1;
00158 DigitalOut pinCD(LCD_CD);       //PA_4;
00159 DigitalOut pinCS(LCD_CS);       //PB_0;
00160 DigitalOut pinReset(LCD_RESET); //PC_1;
00161 
00162 //VL6180X
00163 DigitalOut enableVL6180X(D12);
00164 static XNucleo6180XA1 *board = NULL;
00165 uint32_t dist;
00166 
00167 //integration
00168 #ifdef TEST
00169     Serial pc(USBTX, USBRX, 9600); //SERIAL_TX, SERIAL_RX, 9600);
00170 #endif
00171 
00172 DigitalOut myled(LED1);
00173 uint16_t couleurVariable;
00174 uint16_t tableDeCouleur[]=
00175     {
00176        BLACK, RED, YELLOW, GREEN, CYAN, BLUE, MAGENTA, WHITE
00177     };   
00178 
00179 
00180 //declarations de fonctions
00181 //touchscreen 
00182 void restoreXY(void);
00183 uint16_t readTouchX(void);
00184 uint16_t readTouchY(void);
00185 uint16_t detectTouch(void);
00186 
00187 //tftspfd5408
00188 void WriteCommand(uint8_t c);
00189 void WriteData(uint8_t d);
00190 void begin(void);
00191 void setAddrWindow(int x1, int y1, int x2, int y2);
00192 void fillRect(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h, uint16_t fillcolor);
00193 
00194 //definitions de fonctions
00195 //touchscreen
00196 void restoreXY(void)
00197 {
00198 DigitalOut pinXP(XP);
00199 DigitalOut pinXM(XM);    
00200 DigitalOut pinYP(YP);
00201 DigitalOut pinYM(YM);
00202 
00203     pinXP = 1;
00204     pinXM = 1;
00205     pinYP = 1;
00206     pinYM = 1;
00207     wait_ms(1);
00208 }
00209 
00210 uint16_t readTouchX(void)
00211 {
00212 uint16_t value;
00213 DigitalOut pinXP(XP); 
00214 DigitalOut pinXM(XM);
00215 AnalogIn pinYP(YP);
00216 DigitalIn pinYM(YM);
00217 
00218     pinXP = 0;
00219     pinXM = 1;
00220     pinYM.mode(OpenDrain);
00221     value = pinYP.read_u16() >> 4;
00222     restoreXY();
00223     return value;
00224 }
00225 
00226 uint16_t readTouchY(void)
00227 {
00228 uint16_t value;
00229 DigitalIn pinXP(XP); 
00230 AnalogIn pinXM(XM);
00231 DigitalOut pinYP(YP);
00232 DigitalOut pinYM(YM);
00233 
00234     pinYP = 1;
00235     pinYM = 0;
00236     pinXP.mode(OpenDrain);
00237     value = pinXM.read_u16() >> 4;
00238     restoreXY();    
00239     return value;
00240 }
00241 
00242 uint16_t detectTouch(void)
00243 {
00244 uint16_t firstValue;
00245 uint16_t secondValue;
00246 DigitalOut pinXP(XP); 
00247 DigitalOut pinXM(XM);
00248 AnalogIn pinYP(YP);
00249 DigitalIn pinYM(YM);
00250     
00251     pinYM.mode(OpenDrain);
00252     pinXP = 1;
00253     pinXM = 0;
00254     firstValue = pinYP.read_u16() >> 4;
00255 
00256     pinXP = 0;
00257     pinXM = 1;
00258     secondValue = pinYP.read_u16() >> 4;
00259 
00260     restoreXY();
00261     
00262     if (secondValue > firstValue)
00263     {
00264         return firstValue;
00265     }
00266     return secondValue;
00267 }
00268 
00269 //tftspfd5408
00270 void WriteCommand(uint8_t c)
00271 {
00272 BusInOut portTFT(D8, D9, D2, D3, D4, D5, D6, D7);
00273     portTFT.output();    
00274     pinCD = COMMAND;
00275     pinWR = ACTIVE;
00276     portTFT = c;
00277     pinWR = IDLE;
00278 }
00279 
00280 void WriteData(uint8_t d)
00281 {
00282 BusInOut portTFT(D8, D9, D2, D3, D4, D5, D6, D7);
00283     portTFT.output();    
00284     pinCD = DATA;
00285     pinWR = ACTIVE;
00286     portTFT = d;
00287     pinWR = IDLE;
00288 }
00289 
00290 void begin(void)
00291 {
00292     pinCS = IDLE; 
00293     pinCD = DATA;
00294     pinWR = IDLE;
00295     pinRD = IDLE;
00296 
00297     pinReset = ACTIVE;
00298     wait_ms(100);
00299     pinReset = IDLE;
00300     wait_ms(100);
00301     pinCS = ACTIVE;
00302     
00303     WriteCommand(SPFD5408_SOFTRESET);
00304     WriteData(0);
00305     wait_ms(50);
00306     
00307     WriteCommand(SPFD5408_MEMCONTROL);
00308     WriteData(TFT_NORTH); //(SPFD5408_MADCTL_MY | SPFD5408_MADCTL_BGR);
00309     
00310     WriteCommand(SPFD5408_PIXELFORMAT);
00311     WriteData(0x55);
00312   
00313     WriteCommand(SPFD5408_FRAMECONTROL);
00314     WriteData(0x00);
00315     WriteData(0x1B);
00316   
00317     WriteCommand(SPFD5408_SLEEPOUT);
00318     WriteData(0);
00319   
00320     WriteCommand(SPFD5408_DISPLAYON);
00321     WriteData(0);
00322 }
00323 
00324 void setAddrWindow(int x1, int y1, int x2, int y2) {
00325     pinCS = ACTIVE;
00326     wait_us(TEMPS);
00327     WriteCommand(SPFD5408_COLADDRSET);
00328     WriteData(x1 >> 8);
00329     WriteData(x1);
00330     WriteData(x2 >> 8);
00331     WriteData(x2);
00332     wait_us(TEMPS);
00333     pinCS = IDLE;
00334 
00335     pinCS = ACTIVE;
00336     wait_us(TEMPS);
00337     WriteCommand(SPFD5408_PAGEADDRSET);
00338     WriteData(y1 >> 8);
00339     WriteData(y1);
00340     WriteData(y2 >> 8);
00341     WriteData(y2);
00342     pinCS = IDLE;
00343 }
00344 
00345 void fillRect(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h, uint16_t fillcolor)
00346 {
00347     BusInOut portTFT(D8, D9, D2, D3, D4, D5, D6, D7);
00348     uint8_t hi, lo;
00349     uint16_t  x2, y2;
00350     uint16_t i, j;
00351 
00352     portTFT.output();    
00353 
00354     x2 = x1 + w - 1;
00355     y2 = y1 + h - 1;
00356     setAddrWindow(x1, y1, x2, y2);
00357 
00358     hi = fillcolor >> 8;
00359     lo = fillcolor;
00360 
00361     pinCS = ACTIVE;
00362 
00363     WriteCommand(SPFD5408_MEMORYWRITE);
00364     pinCD = DATA;
00365     for (i = h; i > 0; i--)
00366     {
00367         for (j = w; j > 0; j--)
00368 
00369         {
00370             pinWR = ACTIVE;
00371             portTFT = hi;
00372             pinWR = IDLE; 
00373             pinWR = ACTIVE;
00374             portTFT = lo;
00375             pinWR = IDLE;             
00376         }
00377     }
00378     pinCS = IDLE;
00379 }
00380  
00381 //intégration
00382 
00383 int32_t conversion(int32_t x, int32_t x0, int32_t y0, int32_t x1, int32_t y1)
00384 {
00385     int32_t retour;
00386     int32_t limiteInferieure;
00387     int32_t limiteSuperieure;
00388     if (y0 < y1)
00389     {
00390         limiteInferieure = y0;
00391         limiteSuperieure = y1;
00392     }
00393     else
00394     {
00395         limiteInferieure = y1;
00396         limiteSuperieure = y0;
00397     }
00398     retour = (x - x0) * (y1 -y0) / (x1 -x0) + y0;
00399   
00400     if (retour < limiteInferieure)
00401     {
00402         return limiteInferieure;
00403     }        
00404     if (retour > limiteSuperieure)
00405     {
00406         return limiteSuperieure;
00407     }
00408     return retour;
00409 };
00410 
00411 uint16_t determineLaCouleur(void)
00412 {
00413 
00414     board->sensor_top->get_distance(&dist);
00415     if (dist > 210) //en millimetres
00416     {
00417         dist = 210;
00418     }
00419 //    board->sensor_top->get_lux(&lux);
00420         
00421         return tableDeCouleur[(int)(dist/30)];
00422 }
00423 
00424 int main()
00425 {
00426 //variables locales du touchscreen 
00427 uint16_t couleur;
00428 
00429 //variables locales du tftspfd5408
00430 
00431 //variables locales pour le VL6180X
00432 int status;
00433 uint32_t lux;
00434 
00435 DevI2C *device_i2c = new DevI2C(VL6180X_I2C_SDA, VL6180X_I2C_SCL);
00436 
00437 
00438 //variables locales pour l'integration
00439 uint32_t mode;
00440 
00441 
00442 //initialisation du touchscreen
00443     restoreXY();
00444    
00445 //initialisation du tftspfd5408
00446     begin();
00447 
00448 //initialisation du VL6180X
00449 //    printf ("Initialisation *********\n");  
00450 //yr
00451 //    pin_mode(VL6180X_I2C_SDA, (PinMode)PullUp);
00452 //    pin_mode(VL6180X_I2C_SCL, (PinMode)PullUp);
00453 
00454     enableVL6180X = 1;
00455     wait_ms(1); 
00456     enableVL6180X = 0;
00457     wait_ms(1); 
00458     enableVL6180X = 1;
00459     wait_ms(1);
00460 
00461     /* Creates the 6180XA1 expansion board singleton obj. */
00462     board = XNucleo6180XA1::instance(device_i2c, D11, D10, D13, D2);
00463 
00464     /* Initializes the 6180XA1 expansion board with default values. */
00465     status = board->init_board();
00466     if (status) {
00467         printf("Failed to init board!\n\r");
00468         return 0;
00469     }
00470 
00471 //intégration
00472     mode = MODE_COULEUR_CONSTANTE;
00473     couleur = RED;
00474     couleurVariable = BLUE;
00475     fillRect(0, 0, 240, 280, BLACK); //surface de dessin  
00476 //bouton noir
00477     fillRect(0, 280, 80, 2, WHITE); // ligne horizontale haut
00478     fillRect(0, 282, 2, 38, WHITE); // ligne verticale gauche
00479     fillRect(79, 282, 1, 38, WHITE); // ligne verticale droite
00480     fillRect(2, 318, 77, 2, WHITE); //ligne horizontale bas
00481     fillRect(2, 282, 77, 36, BLACK); // centre noir
00482 //bouton rouge
00483     fillRect(80, 280, 80, 40, WHITE); // moins d'instructions mais plus long
00484     fillRect(81, 282, 78, 36, RED); // bouton rouge
00485 //bouton cyan
00486     fillRect(160, 280, 80, 40, WHITE); // moins d'instructions mais plus long
00487     fillRect(161, 282, 77, 36, BLUE); //bouton bleu
00488 //indicateur
00489     fillRect(81, 282, 10, 10, GREEN); //couleur rouge par défaut
00490 
00491     while(1) {
00492         
00493 #ifdef TEST
00494     printf ("Distance: %d, Lux: %d\n\r", dist, lux);
00495 #endif
00496             
00497 //tâches du touchscreen
00498         myled = !myled;
00499 
00500         x = readTouchX();
00501         y = readTouchY();
00502         z = detectTouch();
00503 //tâches du tftspfd5408
00504 
00505 
00506 //tâches d'intégration
00507         couleurVariable = determineLaCouleur();
00508 //        fillRect(228, 282, 10, 10, couleurVariable); //indicateur de couleur
00509 
00510         if ((z > TOUCH_SEUIL_BAS)&&(z < TOUCH_SEUIL_HAUT))
00511         {
00512 #ifdef TEST
00513             pc.printf("x lu %u\t ", x);
00514             pc.printf("y lu %u\t ", y);
00515             pc.printf("z lu %u\t ", z);
00516 #endif
00517             float u = conversion((float)x, XT_G, XE_G, XT_D, XE_D);
00518             float v = conversion((float)y, YT_B, YE_B, YT_H, YE_H);
00519 
00520 #ifdef TEST
00521             pc.printf("x ecran %f\t ", u);
00522             pc.printf("y ecran %f\r\n", v);
00523 #endif
00524             if (v < 280)
00525             {
00526                 if (mode == MODE_COULEUR_CONSTANTE)
00527                 {
00528                     fillRect(u, v, 3, 3, couleur);    
00529                 }
00530                 else
00531                 {
00532                     fillRect(u, v, 3, 3, couleurVariable);                   
00533                 }
00534             }
00535             else
00536             {
00537                 if (u < 80)
00538                 {
00539                     fillRect(0, 0, 240, 280, BLACK);
00540                 }
00541                 else
00542                 {
00543                     if (u < 160)
00544                     {
00545                         mode = MODE_COULEUR_CONSTANTE;
00546                         //indicateur RED
00547                         fillRect(81, 282, 10, 10, GREEN); //couleur rouge par défaut
00548                         fillRect(161,282, 10, 10, BLUE);
00549 
00550 #ifdef TEST
00551                         pc.printf("couleur: rouge\n\r");
00552 #endif
00553                     }
00554                     else
00555                     {
00556                         mode = MODE_COULEUR_VARIABLE;
00557                         //indicateur AUTRE
00558                         fillRect(81, 282, 10, 10, RED);
00559                         fillRect(161, 282, 77, 36, BLUE);
00560                         fillRect(161, 282, 10, 10, GREEN);
00561                         
00562 #ifdef TEST
00563                         pc.printf("couleur variable\n\r");
00564 #endif
00565                     }
00566                 }
00567             }
00568         }
00569     }
00570 }