POUR NUCLEO-F302R8
Dependencies: X_NUCLEO_6180XA1 mbed
Fork of 247-436-M1-S2-LAB-A by
main.cpp
- Committer:
- YROY2004
- Date:
- 2018-02-07
- Revision:
- 4:8c64f7896cbf
- Parent:
- 3:b115775ee641
File content as of revision 4:8c64f7896cbf:
#include "mbed.h"
#include "XNucleo6180XA1.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
//BRANCHEMENTS:
// Ni le Nucleo ni le vl6180x n'ont de "pullup" pour supporter le I2C.
// Il faut ajouter des résistances de 4.7k
// Le vl6180x contient un microcontôleur qui doit être remis à zéro au démarrage
// Cette remise à zéro se fait en mettant temporairement la broche gpio à la masse.
// Un schéma de connexion sommaire suit:
// __________
// | VL6180X |
// | |
// scl sda gnd
// nc gpio 3.3v
// |__________|
// _______________________
// | |
// | NUCLEO f302r8 |
// | oo oo |
// | oo scl-oo |
// | oo sda-oo |
// | oo oo |
// | oo gnd-oo |
// | oo oo |
// | oo gpio-oo |
// | oo-3.3V oo |
// ...
// | oo oo |
// | cn7 cn10 |
// |_______________________|
// connexions:
// vl6180x.3.3v <------> nucleo.3.3V
// Vl6180x.scl <--------> nucleo.scl <-----> 4.7k <------> 3.3v (pullup requise)
// Vl6180x.sda <--------> nucleo.sda <-----> 4.7k <------> 3.3v (pullup requise)
// VL6180X.gpio <-------> nucleo.gpio (requis pour faire un "reset" du vl6180x au début)
//options de compilation
//#define TEST
//intégration
// représentation
// G: gauche, D: droit, H: haut, B: bas
// E: écran, T: touch
// Ecran:
// (XE_G,YE_H) ___ (XE_D,YE_H)
// | |
// | |
// (XE_G,YE_B) |___| (XE_G,YE_B)
//
// représentation du touch
// (XT_G,YT_H) ___ (XT_D,YT_H)
// | |
// | |
// (XT_G,YT_B) |___| (XT_G,YT_B)
// équations pour conversion
// XT: x touch lu, YT: y touch lu, XE: x ecran, YE: y ecran
// XE = (XE_D - XE_G)/(XT_D - XT_G)*(XT - XT_G) + XE_G
// YE = (YE_H - YE_B)/(YT_H - YT_B)*(YT - YT_G) + YE_G
// l'application présente 3 boutons et une surface de dessin
// bouton noir: effacer
// bouton rouge: dessiner en rouge
// bouton blanc: dessiner en blanc
//touchscreen
#define IDLE 1
#define ACTIVE 0
#define COMMAND 0
#define DATA 1
#define YP A3
#define XM A2
#define YM D9
#define XP D8
#define TOUCH_SEUIL_HAUT 3000
#define TOUCH_SEUIL_BAS 16
#define TFTWIDTH 240
#define TFTHEIGHT 320
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
#define TFT_NORTH SPFD5408_MADCTL_MY | SPFD5408_MADCTL_BGR
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define SPFD5408_SOFTRESET 0x01
#define SPFD5408_SLEEPOUT 0x11
#define SPFD5408_DISPLAYON 0x29
#define SPFD5408_COLADDRSET 0x2A
#define SPFD5408_PAGEADDRSET 0x2B
#define SPFD5408_MEMORYWRITE 0x2C
#define SPFD5408_PIXELFORMAT 0x3A
#define SPFD5408_FRAMECONTROL 0xB1
#define SPFD5408_MEMCONTROL 0x36
#define SPFD5408_MADCTL_MY 0x80
#define SPFD5408_MADCTL_BGR 0x08
#define IDLE 1
#define ACTIVE 0
#define COMMAND 0
#define DATA 1
#define TEMPS 40
//VL6180X
#define VL6180X_I2C_SDA D14
#define VL6180X_I2C_SCL D15
#define VL6180X_I2C_SDA_MODE PullUp
#define VL6180X_I2C_SCL_MODE PullUp
//integration
#define XE_G 0
#define XE_D 240
#define YE_H 0
#define YE_B 320
#define XT_G 3700
#define XT_D 600
#define YT_H 600
#define YT_B 3700
#define MODE_COULEUR_CONSTANTE 0
#define MODE_COULEUR_VARIABLE 1
//definitions de variables
//touchscreen
uint16_t x;
uint16_t y;
uint16_t z;
//tftspfd5408
DigitalOut pinRD(LCD_RD); //PA_0;
DigitalOut pinWR(LCD_WR); //PA_1;
DigitalOut pinCD(LCD_CD); //PA_4;
DigitalOut pinCS(LCD_CS); //PB_0;
DigitalOut pinReset(LCD_RESET); //PC_1;
//VL6180X
DigitalOut enableVL6180X(D12);
static XNucleo6180XA1 *board = NULL;
uint32_t dist;
//integration
#ifdef TEST
Serial pc(USBTX, USBRX, 9600); //SERIAL_TX, SERIAL_RX, 9600);
#endif
DigitalOut myled(LED1);
uint16_t couleurVariable;
uint16_t tableDeCouleur[]=
{
BLACK, RED, YELLOW, GREEN, CYAN, BLUE, MAGENTA, WHITE
};
//declarations de fonctions
//touchscreen
void restoreXY(void);
uint16_t readTouchX(void);
uint16_t readTouchY(void);
uint16_t detectTouch(void);
//tftspfd5408
void WriteCommand(uint8_t c);
void WriteData(uint8_t d);
void begin(void);
void setAddrWindow(int x1, int y1, int x2, int y2);
void fillRect(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h, uint16_t fillcolor);
//definitions de fonctions
//touchscreen
void restoreXY(void)
{
DigitalOut pinXP(XP);
DigitalOut pinXM(XM);
DigitalOut pinYP(YP);
DigitalOut pinYM(YM);
pinXP = 1;
pinXM = 1;
pinYP = 1;
pinYM = 1;
wait_ms(1);
}
uint16_t readTouchX(void)
{
uint16_t value;
DigitalOut pinXP(XP);
DigitalOut pinXM(XM);
AnalogIn pinYP(YP);
DigitalIn pinYM(YM);
pinXP = 0;
pinXM = 1;
pinYM.mode(OpenDrain);
value = pinYP.read_u16() >> 4;
restoreXY();
return value;
}
uint16_t readTouchY(void)
{
uint16_t value;
DigitalIn pinXP(XP);
AnalogIn pinXM(XM);
DigitalOut pinYP(YP);
DigitalOut pinYM(YM);
pinYP = 1;
pinYM = 0;
pinXP.mode(OpenDrain);
value = pinXM.read_u16() >> 4;
restoreXY();
return value;
}
uint16_t detectTouch(void)
{
uint16_t firstValue;
uint16_t secondValue;
DigitalOut pinXP(XP);
DigitalOut pinXM(XM);
AnalogIn pinYP(YP);
DigitalIn pinYM(YM);
pinYM.mode(OpenDrain);
pinXP = 1;
pinXM = 0;
firstValue = pinYP.read_u16() >> 4;
pinXP = 0;
pinXM = 1;
secondValue = pinYP.read_u16() >> 4;
restoreXY();
if (secondValue > firstValue)
{
return firstValue;
}
return secondValue;
}
//tftspfd5408
void WriteCommand(uint8_t c)
{
BusInOut portTFT(D8, D9, D2, D3, D4, D5, D6, D7);
portTFT.output();
pinCD = COMMAND;
pinWR = ACTIVE;
portTFT = c;
pinWR = IDLE;
}
void WriteData(uint8_t d)
{
BusInOut portTFT(D8, D9, D2, D3, D4, D5, D6, D7);
portTFT.output();
pinCD = DATA;
pinWR = ACTIVE;
portTFT = d;
pinWR = IDLE;
}
void begin(void)
{
pinCS = IDLE;
pinCD = DATA;
pinWR = IDLE;
pinRD = IDLE;
pinReset = ACTIVE;
wait_ms(100);
pinReset = IDLE;
wait_ms(100);
pinCS = ACTIVE;
WriteCommand(SPFD5408_SOFTRESET);
WriteData(0);
wait_ms(50);
WriteCommand(SPFD5408_MEMCONTROL);
WriteData(TFT_NORTH); //(SPFD5408_MADCTL_MY | SPFD5408_MADCTL_BGR);
WriteCommand(SPFD5408_PIXELFORMAT);
WriteData(0x55);
WriteCommand(SPFD5408_FRAMECONTROL);
WriteData(0x00);
WriteData(0x1B);
WriteCommand(SPFD5408_SLEEPOUT);
WriteData(0);
WriteCommand(SPFD5408_DISPLAYON);
WriteData(0);
}
void setAddrWindow(int x1, int y1, int x2, int y2) {
pinCS = ACTIVE;
wait_us(TEMPS);
WriteCommand(SPFD5408_COLADDRSET);
WriteData(x1 >> 8);
WriteData(x1);
WriteData(x2 >> 8);
WriteData(x2);
wait_us(TEMPS);
pinCS = IDLE;
pinCS = ACTIVE;
wait_us(TEMPS);
WriteCommand(SPFD5408_PAGEADDRSET);
WriteData(y1 >> 8);
WriteData(y1);
WriteData(y2 >> 8);
WriteData(y2);
pinCS = IDLE;
}
void fillRect(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h, uint16_t fillcolor)
{
BusInOut portTFT(D8, D9, D2, D3, D4, D5, D6, D7);
uint8_t hi, lo;
uint16_t x2, y2;
uint16_t i, j;
portTFT.output();
x2 = x1 + w - 1;
y2 = y1 + h - 1;
setAddrWindow(x1, y1, x2, y2);
hi = fillcolor >> 8;
lo = fillcolor;
pinCS = ACTIVE;
WriteCommand(SPFD5408_MEMORYWRITE);
pinCD = DATA;
for (i = h; i > 0; i--)
{
for (j = w; j > 0; j--)
{
pinWR = ACTIVE;
portTFT = hi;
pinWR = IDLE;
pinWR = ACTIVE;
portTFT = lo;
pinWR = IDLE;
}
}
pinCS = IDLE;
}
//intégration
int32_t conversion(int32_t x, int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
int32_t retour;
int32_t limiteInferieure;
int32_t limiteSuperieure;
if (y0 < y1)
{
limiteInferieure = y0;
limiteSuperieure = y1;
}
else
{
limiteInferieure = y1;
limiteSuperieure = y0;
}
retour = (x - x0) * (y1 -y0) / (x1 -x0) + y0;
if (retour < limiteInferieure)
{
return limiteInferieure;
}
if (retour > limiteSuperieure)
{
return limiteSuperieure;
}
return retour;
};
uint16_t determineLaCouleur(void)
{
board->sensor_top->get_distance(&dist);
if (dist > 210) //en millimetres
{
dist = 210;
}
// board->sensor_top->get_lux(&lux);
return tableDeCouleur[(int)(dist/30)];
}
int main()
{
//variables locales du touchscreen
uint16_t couleur;
//variables locales du tftspfd5408
//variables locales pour le VL6180X
int status;
uint32_t lux;
DevI2C *device_i2c = new DevI2C(VL6180X_I2C_SDA, VL6180X_I2C_SCL);
//variables locales pour l'integration
uint32_t mode;
//initialisation du touchscreen
restoreXY();
//initialisation du tftspfd5408
begin();
//initialisation du VL6180X
// printf ("Initialisation *********\n");
//yr
// pin_mode(VL6180X_I2C_SDA, (PinMode)PullUp);
// pin_mode(VL6180X_I2C_SCL, (PinMode)PullUp);
enableVL6180X = 1;
wait_ms(1);
enableVL6180X = 0;
wait_ms(1);
enableVL6180X = 1;
wait_ms(1);
/* Creates the 6180XA1 expansion board singleton obj. */
board = XNucleo6180XA1::instance(device_i2c, D11, D10, D13, D2);
/* Initializes the 6180XA1 expansion board with default values. */
status = board->init_board();
if (status) {
printf("Failed to init board!\n\r");
return 0;
}
//intégration
mode = MODE_COULEUR_CONSTANTE;
couleur = RED;
couleurVariable = BLUE;
fillRect(0, 0, 240, 280, BLACK); //surface de dessin
//bouton noir
fillRect(0, 280, 80, 2, WHITE); // ligne horizontale haut
fillRect(0, 282, 2, 38, WHITE); // ligne verticale gauche
fillRect(79, 282, 1, 38, WHITE); // ligne verticale droite
fillRect(2, 318, 77, 2, WHITE); //ligne horizontale bas
fillRect(2, 282, 77, 36, BLACK); // centre noir
//bouton rouge
fillRect(80, 280, 80, 40, WHITE); // moins d'instructions mais plus long
fillRect(81, 282, 78, 36, RED); // bouton rouge
//bouton cyan
fillRect(160, 280, 80, 40, WHITE); // moins d'instructions mais plus long
fillRect(161, 282, 77, 36, BLUE); //bouton bleu
//indicateur
fillRect(81, 282, 10, 10, GREEN); //couleur rouge par défaut
while(1) {
#ifdef TEST
printf ("Distance: %d, Lux: %d\n\r", dist, lux);
#endif
//tâches du touchscreen
myled = !myled;
x = readTouchX();
y = readTouchY();
z = detectTouch();
//tâches du tftspfd5408
//tâches d'intégration
couleurVariable = determineLaCouleur();
// fillRect(228, 282, 10, 10, couleurVariable); //indicateur de couleur
if ((z > TOUCH_SEUIL_BAS)&&(z < TOUCH_SEUIL_HAUT))
{
#ifdef TEST
pc.printf("x lu %u\t ", x);
pc.printf("y lu %u\t ", y);
pc.printf("z lu %u\t ", z);
#endif
float u = conversion((float)x, XT_G, XE_G, XT_D, XE_D);
float v = conversion((float)y, YT_B, YE_B, YT_H, YE_H);
#ifdef TEST
pc.printf("x ecran %f\t ", u);
pc.printf("y ecran %f\r\n", v);
#endif
if (v < 280)
{
if (mode == MODE_COULEUR_CONSTANTE)
{
fillRect(u, v, 3, 3, couleur);
}
else
{
fillRect(u, v, 3, 3, couleurVariable);
}
}
else
{
if (u < 80)
{
fillRect(0, 0, 240, 280, BLACK);
}
else
{
if (u < 160)
{
mode = MODE_COULEUR_CONSTANTE;
//indicateur RED
fillRect(81, 282, 10, 10, GREEN); //couleur rouge par défaut
fillRect(161,282, 10, 10, BLUE);
#ifdef TEST
pc.printf("couleur: rouge\n\r");
#endif
}
else
{
mode = MODE_COULEUR_VARIABLE;
//indicateur AUTRE
fillRect(81, 282, 10, 10, RED);
fillRect(161, 282, 77, 36, BLUE);
fillRect(161, 282, 10, 10, GREEN);
#ifdef TEST
pc.printf("couleur variable\n\r");
#endif
}
}
}
}
}
}
