1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-11-21 23:56:04 +01:00

Motor controller via FPGA

This commit is contained in:
Geoffrey Frogeye 2018-05-01 08:45:02 +02:00
parent 760b950e83
commit 4af0f8c865
21 changed files with 602 additions and 271 deletions

View file

@ -11,7 +11,7 @@ CFLAGS_CUSTOM += -g
## Générateurs de drapeaux pour les bibliothèques ## Générateurs de drapeaux pour les bibliothèques
PKG_CONFIG=pkg-config PKG_CONFIG=pkg-config
## Nom des objets communs ## Nom des objets communs
OBJS=CF debug i2c ihm lcd movement parcours points position OBJS=buttons CF debug i2c ihm lcd movement parcours points position
OBJS_O=$(addprefix obj/,$(addsuffix .o,$(OBJS))) OBJS_O=$(addprefix obj/,$(addsuffix .o,$(OBJS)))
# VARIABLES AUTOMATIQUES # VARIABLES AUTOMATIQUES

View file

@ -58,5 +58,21 @@ struct __attribute__ ((packed)) F2CT_CAPTs {
uint16_t back; uint16_t back;
}; };
// Met à jour la PWM (pour ctrl moteur (EN, IN × 2) × 2)
#define C2FD_PWM 'W'
struct __attribute__ ((packed)) C2FD_PWMs {
uint8_t ena;
uint8_t enb;
uint8_t in;
};
// Met à jour la PWM (pour ctrl moteur (EN × 2) × 2)
#define C2FD_PWM2 'w'
struct __attribute__ ((packed)) C2FD_PWM2s {
uint8_t ena;
uint8_t enc;
uint8_t enb;
uint8_t end;
};
#endif #endif

99
chef/src/buttons.c Normal file
View file

@ -0,0 +1,99 @@
#include <pthread.h>
#include <stdio.h>
#include "buttons.h"
// Globales
pthread_t tStdinButton;
enum boutons stdinbutton = none;
// Fonctions
void configureButtons()
{
pinMode(BUT_PIN_ROUGE, INPUT);
pullUpDnControl(BUT_PIN_ROUGE, PUD_UP);
pinMode(BUT_PIN_JAUNE, INPUT);
pullUpDnControl(BUT_PIN_JAUNE, PUD_UP);
pinMode(BUT_PIN_TIRETTE, INPUT);
pullUpDnControl(BUT_PIN_TIRETTE, PUD_UP);
pthread_create(&tStdinButton, NULL, TaskStdinButton, NULL);
}
bool debunkButton(int pin)
{
int t;
// Press (cancel if wrong)
for (t = BUT_DEBUNK_TIME / 2; t > 0; t--) {
if (digitalRead(pin) != LOW) {
return false;
}
delay(1);
}
// Release (re-wait if wrong)
for (t = BUT_DEBUNK_TIME / 2; t > 0; t--) {
if (digitalRead(pin) != HIGH) {
t = BUT_DEBUNK_TIME / 2;
}
delay(1);
}
return true;
}
void* TaskStdinButton(void* pdata)
{
(void)pdata;
for (;;) {
char c = getchar();
if (c == '1') {
stdinbutton = jaune;
} else if (c == '2') {
stdinbutton = rouge;
}
}
return NULL;
}
enum boutons pressedButton(int timeout)
{
bool block = timeout < 0;
while (timeout > 0 || block) {
if (stdinbutton != none) {
enum boutons bout = stdinbutton;
stdinbutton = none;
return bout;
}
if (debunkButton(BUT_PIN_JAUNE)) {
return jaune;
}
if (debunkButton(BUT_PIN_ROUGE)) {
return rouge;
}
delay(BUT_POLLING_INTERVAL);
timeout -= BUT_POLLING_INTERVAL;
}
return none;
}
bool tirettePresente()
{
int etat, newEtat;
int t;
for (t = 0; t < BUT_DEBUNK_TIME; t++) {
newEtat = digitalRead(BUT_PIN_TIRETTE);
if (etat != newEtat) {
t = 0;
etat = newEtat;
}
delay(1);
}
return etat == LOW;
}

30
chef/src/buttons.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef __BUTTONS_H_
#define __BUTTONS_H_
#include <stdbool.h>
#include <wiringPi.h>
// Constants
#define BUT_PIN_ROUGE 0
#define BUT_PIN_JAUNE 2
#define BUT_PIN_TIRETTE 3
// ms
#define BUT_BLOCK -1
#define BUT_POLLING_INTERVAL 50
#define BUT_DEBUNK_TIME 50
#define BUT_REFRESH_INTERVAL 1000
// Structures
enum boutons {none, jaune, rouge};
// Public
void configureButtons();
enum boutons pressedButton(int timeout); // timeout: ms or -1
bool tirettePresente();
// Private
bool debunkButton(int pin);
void* TaskStdinButton(void *pdata);
#endif

View file

@ -1,17 +1,16 @@
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <stdio.h>
#include <time.h> #include <time.h>
#include <wiringPi.h>
#include "ihm.h" #include "ihm.h"
#include "movement.h" #include "movement.h"
#include "parcours.h" #include "parcours.h"
#include "points.h" #include "points.h"
#include "lcd.h"
#include "buttons.h"
// Globales // Globales
pthread_t tIHM; pthread_t tIHM;
pthread_t tStdinIHM;
// Fonctions // Fonctions
void configureIHM() void configureIHM()
@ -22,15 +21,8 @@ void configureIHM()
void startIHM() void startIHM()
{ {
pinMode(IHM_PIN_ROUGE, INPUT); configureButtons();
pullUpDnControl(IHM_PIN_ROUGE, PUD_UP);
pinMode(IHM_PIN_JAUNE, INPUT);
pullUpDnControl(IHM_PIN_JAUNE, PUD_UP);
pinMode(IHM_PIN_TIRETTE, INPUT);
pullUpDnControl(IHM_PIN_TIRETTE, PUD_UP);
pthread_create(&tIHM, NULL, TaskIHM, NULL); pthread_create(&tIHM, NULL, TaskIHM, NULL);
pthread_create(&tStdinIHM, NULL, TaskStdinIHM, NULL);
pthread_join(tIHM, NULL); pthread_join(tIHM, NULL);
} }
@ -46,84 +38,6 @@ void diffTimespec(const struct timespec* t1, const struct timespec* t2, struct t
} }
} }
bool debunkButtonIHM(int pin)
{
int t;
// Press (cancel if wrong)
for (t = IHM_DEBUNK_TIME / 2; t > 0; t--) {
if (digitalRead(pin) != LOW) {
return false;
}
delay(1);
}
// Release (re-wait if wrong)
for (t = IHM_DEBUNK_TIME / 2; t > 0; t--) {
if (digitalRead(pin) != HIGH) {
t = IHM_DEBUNK_TIME / 2;
}
delay(1);
}
return true;
}
enum boutons stdinbutton = none;
void* TaskStdinIHM(void* pdata)
{
(void)pdata;
for (;;) {
char c = getchar();
if (c == '1') {
stdinbutton = jaune;
} else if (c == '2') {
stdinbutton = rouge;
}
}
return NULL;
}
enum boutons pressedIHM(int timeout)
{
bool block = timeout < 0;
while (timeout > 0 || block) {
if (stdinbutton != none) {
enum boutons bout = stdinbutton;
stdinbutton = none;
return bout;
}
if (debunkButtonIHM(IHM_PIN_JAUNE)) {
return jaune;
}
if (debunkButtonIHM(IHM_PIN_ROUGE)) {
return rouge;
}
delay(IHM_POLLING_INTERVAL);
timeout -= IHM_POLLING_INTERVAL;
}
return none;
}
bool tirettePresente()
{
int etat, newEtat;
int t;
for (t = 0; t < IHM_DEBUNK_TIME; t++) {
newEtat = digitalRead(IHM_PIN_TIRETTE);
if (etat != newEtat) {
t = 0;
etat = newEtat;
}
delay(1);
}
return etat == LOW;
}
bool isDebug = false; bool isDebug = false;
bool isOrange = true; bool isOrange = true;
bool annuler = false; bool annuler = false;
@ -152,7 +66,7 @@ void* TaskIHM(void* pdata)
if (isDebug) { if (isDebug) {
printToLCD(LCD_LINE_2, "192.168.0.0 TODO"); printToLCD(LCD_LINE_2, "192.168.0.0 TODO");
} }
bout = pressedIHM(IHM_REFRESH_INTERVAL); bout = pressedButton(BUT_REFRESH_INTERVAL);
if (bout == rouge) { if (bout == rouge) {
isDebug = !isDebug; isDebug = !isDebug;
@ -165,7 +79,7 @@ void* TaskIHM(void* pdata)
for (;;) { for (;;) {
clearLCD(); clearLCD();
printfToLCD(LCD_LINE_1, "Couleur : %s", getCouleur()); printfToLCD(LCD_LINE_1, "Couleur : %s", getCouleur());
bout = pressedIHM(IHM_BLOCK); bout = pressedButton(BUT_BLOCK);
if (bout == rouge) { if (bout == rouge) {
isOrange = !isOrange; isOrange = !isOrange;
@ -184,7 +98,7 @@ void* TaskIHM(void* pdata)
printToLCD(LCD_LINE_1, "Calibrer"); printToLCD(LCD_LINE_1, "Calibrer");
printfToLCD(LCD_LINE_2, "(%s)", getCouleur()); printfToLCD(LCD_LINE_2, "(%s)", getCouleur());
} }
bout = pressedIHM(IHM_REFRESH_INTERVAL); bout = pressedButton(BUT_REFRESH_INTERVAL);
if (bout == rouge) { if (bout == rouge) {
clearLCD(); clearLCD();
@ -200,7 +114,7 @@ void* TaskIHM(void* pdata)
for (;;) { for (;;) {
clearLCD(); clearLCD();
printToLCD(LCD_LINE_1, "Diagnostiquer"); printToLCD(LCD_LINE_1, "Diagnostiquer");
bout = pressedIHM(IHM_BLOCK); bout = pressedButton(BUT_BLOCK);
if (bout == rouge) { if (bout == rouge) {
clearLCD(); clearLCD();
@ -216,7 +130,7 @@ void* TaskIHM(void* pdata)
clearLCD(); clearLCD();
printToLCD(LCD_LINE_1, "Lancer parcours"); printToLCD(LCD_LINE_1, "Lancer parcours");
printfToLCD(LCD_LINE_2, "(%s)", getCouleur()); printfToLCD(LCD_LINE_2, "(%s)", getCouleur());
bout = pressedIHM(IHM_BLOCK); bout = pressedButton(BUT_BLOCK);
if (bout == rouge) { if (bout == rouge) {
// No tirette // No tirette
annuler = false; annuler = false;
@ -224,7 +138,7 @@ void* TaskIHM(void* pdata)
clearLCD(); clearLCD();
printToLCD(LCD_LINE_1, "Inserez tirette"); printToLCD(LCD_LINE_1, "Inserez tirette");
printToLCD(LCD_LINE_2, "(ROUGE: ignorer)"); printToLCD(LCD_LINE_2, "(ROUGE: ignorer)");
bout = pressedIHM(IHM_REFRESH_INTERVAL); bout = pressedButton(BUT_REFRESH_INTERVAL);
if (bout == rouge) { if (bout == rouge) {
break; break;
} else if (bout == jaune) { } else if (bout == jaune) {
@ -241,7 +155,7 @@ void* TaskIHM(void* pdata)
prepareParcours(isOrange); prepareParcours(isOrange);
while (tirettePresente()) { while (tirettePresente()) {
bout = pressedIHM(IHM_POLLING_INTERVAL); bout = pressedButton(BUT_POLLING_INTERVAL);
if (bout == jaune) { if (bout == jaune) {
annuler = true; annuler = true;
break; break;
@ -256,15 +170,15 @@ void* TaskIHM(void* pdata)
int toWait; int toWait;
while ((toWait = updateParcours()) >= 0) { while ((toWait = updateParcours()) >= 0) {
if (pressedIHM(toWait) != none) { if (pressedButton(toWait) != none) {
break; break;
} }
} }
stopParcours(); stopParcours();
pressedIHM(IHM_BLOCK); // Nécessite 3 appuis pour éviter d'enlever le score par inadvertance pressedButton(BUT_BLOCK); // Nécessite 3 appuis pour éviter d'enlever le score par inadvertance
pressedIHM(IHM_BLOCK); pressedButton(BUT_BLOCK);
pressedIHM(IHM_BLOCK); pressedButton(BUT_BLOCK);
} else if (bout == jaune) { } else if (bout == jaune) {
break; break;
} }
@ -274,7 +188,7 @@ void* TaskIHM(void* pdata)
for (;;) { for (;;) {
clearLCD(); clearLCD();
printToLCD(LCD_LINE_1, "Remettre a zero"); printToLCD(LCD_LINE_1, "Remettre a zero");
bout = pressedIHM(IHM_BLOCK); bout = pressedButton(BUT_BLOCK);
if (bout == rouge) { if (bout == rouge) {
clearLCD(); clearLCD();

View file

@ -3,20 +3,6 @@
#include <stdbool.h> #include <stdbool.h>
#include "lcd.h"
#define IHM_PIN_ROUGE 0
#define IHM_PIN_JAUNE 2
#define IHM_PIN_TIRETTE 3
// ms
#define IHM_BLOCK -1
#define IHM_POLLING_INTERVAL 50
#define IHM_DEBUNK_TIME 50
#define IHM_REFRESH_INTERVAL 1000
enum boutons {none, jaune, rouge};
// Public // Public
void configureIHM(); void configureIHM();
void startIHM(); void startIHM();
@ -24,8 +10,5 @@ void deconfigureIHM();
// Private // Private
void* TaskIHM(void *pdata); void* TaskIHM(void *pdata);
void* TaskStdinIHM(void *pdata);
enum boutons pressedIHM(int timeout); // timeout: ms or -1
bool debunkButtonIHM(int pin);
#endif #endif

View file

@ -1,85 +1,74 @@
#include "movement.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include "movement.h"
#include "CF.h"
void configureMovement() void configureMovement()
{ {
pinMode(ENA, PWM_OUTPUT); stop();
pinMode(ENB, PWM_OUTPUT);
} }
void aller(struct position* pos); void aller(struct position* pos);
int dbg = 0; int dbg = 0;
int changerMoteurs(float lVit, float rVit) uint8_t tensionToPWM(float V)
{ {
if (V >= PWM_MAX_V) {
return PWM_MAX;
} else if (V <= 0) {
return 0;
} else {
return V * (float) PWM_MAX / (float) PWM_MAX_V;
}
}
// Tension de PWM
// TODO Changer en tension de moteur
int setMoteurTension(float lVolt, float rVolt)
{
static struct C2FD_PWMs msg;
msg.in = 0x00;
// Gauche // Gauche
bool lFor = lVit < 0; bool lFor = lVolt < 0;
float lVolt = fabs(lVit); // TODO Utiliser les vitesses lVolt = fabs(lVolt);
if (lVolt > MOT_MAX_V) { if (lVolt > MOT_MAX_V) {
lVolt = MOT_MAX_V; lVolt = MOT_MAX_V;
} }
if (lVolt < MOT_MIN_V) { msg.in |= 1 << (lFor ? IN1 : IN2);
digitalWrite(IN1, LOW); msg.ena = tensionToPWM(lVolt);
digitalWrite(IN2, LOW);
printf("x");
} else if (lFor) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
printf("");
} else {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
printf("");
}
int lAbs = lVolt * PWM_MAX / PWM_MAX_V;
pwmWrite(ENA, lAbs);
printf("%6d", lAbs);
// Droite // Droite
bool rFor = rVit < 0; bool rFor = rVolt < 0;
float rVolt = fabs(rVit); // TODO Utiriser res vitesses rVolt = fabs(rVolt);
if (rVolt > MOT_MAX_V) { msg.in |= 1 << (rFor ? IN3 : IN4);
rVolt = MOT_MAX_V; msg.enb = tensionToPWM(rVolt);
}
if (rVolt < MOT_MIN_V) {
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
printf("x");
} else if (rFor) { sendCF(C2FD_PWM, &msg, sizeof(struct C2FD_PWMs));
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
printf("");
} else {
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
printf("");
} }
int rAbs = rVolt * PWM_MAX / PWM_MAX_V;
pwmWrite(ENB, rAbs); int changerMoteurs(float lVit, float rVit)
printf("%6d", rAbs); {
printf("\n"); // TODO Conversion en vitesse
setMoteurTension(lVit, rVit);
} }
static struct C2FD_PWMs msgBrake = {0, 0, 0x00};
static struct C2FD_PWMs msgFree = {0, 0, (1 << IN1) | (1 << IN2) | (1 << IN3) | (1 << IN4)};
int brake() int brake()
{ {
digitalWrite(IN1, LOW); sendCF(C2FD_PWM, &msgBrake, sizeof(struct C2FD_PWMs));
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
} }
int freewheel() int freewheel()
{ {
digitalWrite(IN1, HIGH); sendCF(C2FD_PWM, &msgFree, sizeof(struct C2FD_PWMs));
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
} }
void deconfigureMovement() void deconfigureMovement()
@ -90,5 +79,5 @@ void deconfigureMovement()
int stop() int stop()
{ {
brake(); brake();
// TODO // TODO Actionneurs
} }

View file

@ -7,8 +7,7 @@
#include "position.h" #include "position.h"
#include <wiringPi.h> #define PWM_MAX 255
#define PWM_MAX 1023
#define PWM_MAX_V 3.3 #define PWM_MAX_V 3.3
#define TESTINATOR #define TESTINATOR
@ -24,17 +23,10 @@
#define MOT_MAX_V 2.5 #define MOT_MAX_V 2.5
#endif #endif
// Pins definition #define IN1 0
// Left #define IN2 1
#define ENA 26 #define IN3 2
#define IN1 21 #define IN4 3
#define IN2 22
// Right
#define ENB 23
#define IN3 24
#define IN4 25
void configureMovement(); void configureMovement();
void aller(struct position* pos); void aller(struct position* pos);

View file

@ -1,6 +1,7 @@
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <wiringPi.h>
#include "lcd.h" #include "lcd.h"
#include "movement.h" #include "movement.h"
@ -69,7 +70,7 @@ void stopParcours()
} }
#define UP_TIME 1000 #define UP_TIME 1000
#define HIGH_TIME 30000 #define HIGH_TIME 3000
#define DOWN_TIME 1000 #define DOWN_TIME 1000
#define LOW_TIME 2000 #define LOW_TIME 2000
#define MAX_VIT MOT_MAX_V #define MAX_VIT MOT_MAX_V

View file

@ -24,16 +24,16 @@ int main()
srand(time(NULL)); srand(time(NULL));
configureDebug(); configureDebug();
/* configureCF(); */ configureCF();
/* configureMovement(); */ configureMovement();
/* configurePosition(); */ configurePosition();
startDebug(); startDebug();
startIHM(); startIHM();
/* deconfigureMovement(); */ deconfigureMovement();
/* deconfigurePosition(); */ deconfigurePosition();
/* deconfigureCF(); */ deconfigureCF();
deconfigureIHM(); deconfigureIHM();
deconfigureDebug(); deconfigureDebug();
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -4,10 +4,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <wiringPi.h>
#include <wiringPiI2C.h> #include <wiringPiI2C.h>
#include "lcd.h" #include "lcd.h"
#include "CF.h"
#include "movement.h" #include "movement.h"
#include "buttons.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@ -15,17 +18,44 @@ int main(int argc, char* argv[])
(void)argc; (void)argc;
(void)argv; (void)argv;
wiringPiSetup();
initI2C(); initI2C();
initLCD(); initLCD();
clearLCD(); configureCF();
printToLCD(LCD_LINE_1, "Forward"); configureButtons();
configureMovement(); configureMovement();
for (;;) { for (;;) {
changerMoteurs(1.5, 2); clearLCD();
sleep(1); printToLCD(LCD_LINE_1, "Forward");
changerMoteurs(3.3, 3.3);
pressedButton(BUT_BLOCK);
clearLCD();
printToLCD(LCD_LINE_1, "Right");
changerMoteurs(-3.3, 3.3);
pressedButton(BUT_BLOCK);
clearLCD();
printToLCD(LCD_LINE_1, "Left");
changerMoteurs(-3.3, -3.3);
pressedButton(BUT_BLOCK);
clearLCD();
printToLCD(LCD_LINE_1, "Backward");
changerMoteurs(3.3, -3.3);
pressedButton(BUT_BLOCK);
clearLCD();
printToLCD(LCD_LINE_1, "Brake");
brake();
pressedButton(BUT_BLOCK);
clearLCD();
printToLCD(LCD_LINE_1, "Free");
freewheel();
pressedButton(BUT_BLOCK);
} }
} }

View file

@ -163,7 +163,7 @@ isimgui: build/isim_$(TB)$(EXE)
# Testing (using ghdl and gtkwave) # Testing (using ghdl and gtkwave)
########################################################################### ###########################################################################
GHDL_FLAGS=--mb-comments GHDL_FLAGS=--mb-comments --ieee=synopsys
%_syntax: %.vhd %_syntax: %.vhd
ghdl -s $(GHDL_FLAGS) "$<" ghdl -s $(GHDL_FLAGS) "$<"

View file

@ -20,7 +20,13 @@ entity Principal is
FRONTTRIGGER: out std_logic; FRONTTRIGGER: out std_logic;
FRONTECHO: in std_logic; FRONTECHO: in std_logic;
BACKTRIGGER: out std_logic; BACKTRIGGER: out std_logic;
BACKECHO: in std_logic BACKECHO: in std_logic;
ENA: out std_logic;
IN1ENC: out std_logic;
IN2: out std_logic;
ENB: out std_logic;
IN3END: out std_logic;
IN4: out std_logic
); );
end Principal; end Principal;
@ -76,7 +82,22 @@ architecture Behavioral of Principal is
); );
end component; end component;
-- AF -- Motor controller
signal enAd : std_logic_vector(7 downto 0);
signal in1enCd : std_logic_vector(7 downto 0);
signal in2d : std_logic;
signal enBd : std_logic_vector(7 downto 0);
signal in3enDd : std_logic_vector(7 downto 0);
signal in4d : std_logic;
component PWM is
port (
clk : in std_logic;
data : in std_logic_vector (7 downto 0);
pulse : out std_logic
);
end component;
-- CF
component uart is component uart is
generic ( generic (
baud : positive := fBaud; baud : positive := fBaud;
@ -116,7 +137,13 @@ architecture Behavioral of Principal is
txStb : out std_logic; txStb : out std_logic;
txAck : in std_logic; txAck : in std_logic;
rxData : in std_logic_vector(7 downto 0); rxData : in std_logic_vector(7 downto 0);
rxStb : in std_logic rxStb : in std_logic;
enA : out std_logic_vector(7 downto 0);
in1enC : out std_logic_vector(7 downto 0);
in2 : out std_logic;
enB : out std_logic_vector(7 downto 0);
in3enD : out std_logic_vector(7 downto 0);
in4 : out std_logic
); );
end component; end component;
@ -177,7 +204,31 @@ begin
start => backFinished start => backFinished
-- done => done -- done => done
); );
enAp : PWM port map (
clk => CLK,
data => enAd,
pulse => ENA
);
in1enCp : PWM port map (
clk => CLK,
data => in1enCd,
pulse => IN1ENC
);
IN2 <= in2d;
enBp : PWM port map (
clk => CLK,
data => enBd,
pulse => ENB
);
in3enDp : PWM port map (
clk => CLK,
data => in3enDd,
pulse => IN3END
);
IN4 <= in4d;
FA: uart port map( FA: uart port map(
@ -204,7 +255,13 @@ begin
txStb => txStb, txStb => txStb,
txAck => txAck, txAck => txAck,
rxData => rxData, rxData => rxData,
rxStb => rxStb rxStb => rxStb,
enA => enAd,
in1enC => in1enCd,
in2 => in2d,
enB => enBd,
in3enD => in3enDd,
in4 => in4d
); );
end Behavioral; end Behavioral;

View file

@ -1,20 +1,22 @@
[*] [*]
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI [*] GTKWave Analyzer v3.3.89 (w)1999-2018 BSI
[*] Tue Feb 27 18:30:48 2018 [*] Tue May 1 05:22:50 2018
[*] [*]
[dumpfile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/Principal_tb.ghw" [dumpfile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/Principal_tb.ghw"
[dumpfile_mtime] "Tue Feb 27 18:29:45 2018" [dumpfile_mtime] "Tue May 1 05:18:35 2018"
[dumpfile_size] 4891772 [dumpfile_size] 6534540
[savefile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/Principal_tb.gtkw" [savefile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/Principal_tb.gtkw"
[timestart] 0 [timestart] 0
[size] 1600 862 [size] 1600 862
[pos] -1 -1 [pos] -1 -1
*-43.418156 1760000000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 *-43.492355 11010000000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] top. [treeopen] top.
[treeopen] top.principal_tb. [treeopen] top.principal_tb.
[treeopen] top.principal_tb.dut. [treeopen] top.principal_tb.dut.
[treeopen] top.principal_tb.dut.in1encp.
[treeopen] top.principal_tb.dut.in3endp.
[sst_width] 213 [sst_width] 213
[signals_width] 198 [signals_width] 255
[sst_expanded] 1 [sst_expanded] 1
[sst_vpaned_height] 296 [sst_vpaned_height] 296
@28 @28
@ -95,11 +97,43 @@ top.principal_tb.dut.backcapt.start
top.principal_tb.dut.backcapt.trigger top.principal_tb.dut.backcapt.trigger
[color] 3 [color] 3
top.principal_tb.dut.backcapt.echo top.principal_tb.dut.backcapt.echo
@8421 @8420
[color] 3 [color] 3
top.principal_tb.dut.backcapt.distancecounter top.principal_tb.dut.backcapt.distancecounter
@420 @420
[color] 3 [color] 3
top.principal_tb.dut.back top.principal_tb.dut.back
@22
[color] 5
#{top.principal_tb.dut.enad[7:0]} top.principal_tb.dut.enad[7] top.principal_tb.dut.enad[6] top.principal_tb.dut.enad[5] top.principal_tb.dut.enad[4] top.principal_tb.dut.enad[3] top.principal_tb.dut.enad[2] top.principal_tb.dut.enad[1] top.principal_tb.dut.enad[0]
@28
[color] 5
top.principal_tb.dut.ena
@22
[color] 5
#{top.principal_tb.dut.in1encd[7:0]} top.principal_tb.dut.in1encd[7] top.principal_tb.dut.in1encd[6] top.principal_tb.dut.in1encd[5] top.principal_tb.dut.in1encd[4] top.principal_tb.dut.in1encd[3] top.principal_tb.dut.in1encd[2] top.principal_tb.dut.in1encd[1] top.principal_tb.dut.in1encd[0]
@28
[color] 5
top.principal_tb.dut.in1enc
[color] 5
top.principal_tb.dut.in2d
[color] 5
top.principal_tb.dut.in2
@22
[color] 5
#{top.principal_tb.dut.enbd[7:0]} top.principal_tb.dut.enbd[7] top.principal_tb.dut.enbd[6] top.principal_tb.dut.enbd[5] top.principal_tb.dut.enbd[4] top.principal_tb.dut.enbd[3] top.principal_tb.dut.enbd[2] top.principal_tb.dut.enbd[1] top.principal_tb.dut.enbd[0]
@28
[color] 5
top.principal_tb.dut.enb
@22
[color] 5
#{top.principal_tb.dut.in3endd[7:0]} top.principal_tb.dut.in3endd[7] top.principal_tb.dut.in3endd[6] top.principal_tb.dut.in3endd[5] top.principal_tb.dut.in3endd[4] top.principal_tb.dut.in3endd[3] top.principal_tb.dut.in3endd[2] top.principal_tb.dut.in3endd[1] top.principal_tb.dut.in3endd[0]
@28
[color] 5
top.principal_tb.dut.in3end
[color] 5
top.principal_tb.dut.in4d
[color] 5
top.principal_tb.dut.in4
[pattern_trace] 1 [pattern_trace] 1
[pattern_trace] 0 [pattern_trace] 0

View file

@ -30,7 +30,13 @@ architecture tb of Principal_tb is
FRONTTRIGGER: out std_logic; FRONTTRIGGER: out std_logic;
FRONTECHO: in std_logic; FRONTECHO: in std_logic;
BACKTRIGGER: out std_logic; BACKTRIGGER: out std_logic;
BACKECHO: in std_logic BACKECHO: in std_logic;
ENA: out std_logic;
IN1ENC: out std_logic;
IN2: out std_logic;
ENB: out std_logic;
IN3END: out std_logic;
IN4: out std_logic
); );
end component; end component;
@ -46,6 +52,12 @@ architecture tb of Principal_tb is
signal FRONTECHO : std_logic; signal FRONTECHO : std_logic;
signal BACKTRIGGER : std_logic; signal BACKTRIGGER : std_logic;
signal BACKECHO : std_logic; signal BACKECHO : std_logic;
signal ENA : std_logic;
signal IN1ENC : std_logic;
signal IN2 : std_logic;
signal ENB : std_logic;
signal IN3END : std_logic;
signal IN4 : std_logic;
constant TbPeriod : time := 500 ns; constant TbPeriod : time := 500 ns;
signal TbClock : std_logic := '0'; signal TbClock : std_logic := '0';
@ -71,7 +83,14 @@ begin
FRONTTRIGGER => FRONTTRIGGER, FRONTTRIGGER => FRONTTRIGGER,
FRONTECHO => FRONTECHO, FRONTECHO => FRONTECHO,
BACKTRIGGER => BACKTRIGGER, BACKTRIGGER => BACKTRIGGER,
BACKECHO => BACKECHO); BACKECHO => BACKECHO,
ENA => ENA,
IN1ENC => IN1ENC,
IN2 => IN2,
ENB => ENB,
IN3END => IN3END,
IN4 => IN4
);
-- Clock generation -- Clock generation
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0'; TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';

View file

@ -16,31 +16,39 @@ entity communication is
txStb : out std_logic := '0'; txStb : out std_logic := '0';
txAck : in std_logic; txAck : in std_logic;
rxData : in std_logic_vector(7 downto 0); rxData : in std_logic_vector(7 downto 0);
rxStb : in std_logic rxStb : in std_logic;
enA : out std_logic_vector(7 downto 0) := x"00";
in1enC : out std_logic_vector(7 downto 0) := x"00";
in2 : out std_logic := '0';
enB : out std_logic_vector(7 downto 0) := x"00";
in3enD : out std_logic_vector(7 downto 0) := x"00";
in4 : out std_logic := '0'
); );
end communication; end communication;
architecture Behavioral of communication is architecture Behavioral of communication is
constant A2FD_PING : std_logic_vector(7 downto 0) := x"50"; -- 'P' constant C2FD_PING : std_logic_vector(7 downto 0) := x"50"; -- 'P'
constant A2FD_RESETCODER : std_logic_vector(7 downto 0) := x"52"; -- 'R' constant C2FD_RESETCODER : std_logic_vector(7 downto 0) := x"52"; -- 'R'
constant F2AD_ERR : std_logic_vector(7 downto 0) := x"45"; -- 'E' constant F2CD_ERR : std_logic_vector(7 downto 0) := x"45"; -- 'E'
constant ERR_UNKNOWN_CODE : std_logic_vector(7 downto 0) := x"43"; -- 'C' constant ERR_UNKNOWN_CODE : std_logic_vector(7 downto 0) := x"43"; -- 'C'
constant F2AI_CODER : std_logic_vector(7 downto 0) := x"44"; -- 'D' constant F2CI_CODER : std_logic_vector(7 downto 0) := x"44"; -- 'D'
constant F2AI_CAPT : std_logic_vector(7 downto 0) := x"43"; -- 'C' constant F2CI_CAPT : std_logic_vector(7 downto 0) := x"43"; -- 'C'
constant F2AT_CAPT : std_logic_vector(7 downto 0) := x"63"; -- 'c' constant F2CT_CAPT : std_logic_vector(7 downto 0) := x"63"; -- 'c'
constant C2FD_PWM : std_logic_vector(7 downto 0) := x"57"; -- 'W'
constant C2FD_PWM2 : std_logic_vector(7 downto 0) := x"77"; -- 'w'
signal frontTrigger : integer := 0; signal frontTrigger : integer := 0;
signal backTrigger : integer := 0; signal backTrigger : integer := 0;
signal triggerSet : std_logic := '0'; signal triggerSet : std_logic := '0';
type readMessages is (F2AT_CAPTs); type readMessages is (F2CT_CAPTs, C2FD_PWMs, C2FD_PWM2s);
signal readMessage : readMessages; signal readMessage : readMessages;
signal readSize : integer := 0; signal readSize : integer := 0;
signal readOffset : integer := 0; signal readOffset : integer := 0;
signal readData : std_logic_vector(63 downto 0) := (others => '0'); -- Max message size (will be trimmed down by the synthetizer) signal readData : std_logic_vector(63 downto 0) := (others => '0'); -- Max message size (will be trimmed down by the synthetizer)
type sendMessages is (A2FD_PINGs, F2AI_CODERs, F2AI_CAPTs, F2AD_ERR_UNKNOWN_CODEs); type sendMessages is (C2FD_PINGs, F2CI_CODERs, F2CI_CAPTs, F2CD_ERR_UNKNOWN_CODEs);
constant SENDQUEUE_SIZE : integer := 16; constant SENDQUEUE_SIZE : integer := 16;
type sendQueueMemorya is array (0 to SENDQUEUE_SIZE - 1) of sendMessages; type sendQueueMemorya is array (0 to SENDQUEUE_SIZE - 1) of sendMessages;
signal sendQueueMemory : sendQueueMemorya; signal sendQueueMemory : sendQueueMemorya;
@ -98,17 +106,23 @@ begin
if readSize = 0 then -- Beginning of message if readSize = 0 then -- Beginning of message
readSize <= 0; readSize <= 0;
case rxData is case rxData is
when A2FD_PING => when C2FD_PING =>
pushSend(A2FD_PINGs); pushSend(C2FD_PINGs);
when F2AI_CODER => when F2CI_CODER =>
pushSend(F2AI_CODERs); pushSend(F2CI_CODERs);
when F2AI_CAPT => when F2CI_CAPT =>
pushSend(F2AI_CAPTs); pushSend(F2CI_CAPTs);
when F2AT_CAPT => when F2CT_CAPT =>
readMessage <= F2AT_CAPTs; readMessage <= F2CT_CAPTs;
readSize <= 4;
when C2FD_PWM =>
readMessage <= C2FD_PWMs;
readSize <= 3;
when C2FD_PWM2 =>
readMessage <= C2FD_PWM2s;
readSize <= 4; readSize <= 4;
when others => when others =>
pushSend(F2AD_ERR_UNKNOWN_CODEs); pushSend(F2CD_ERR_UNKNOWN_CODEs);
end case; end case;
else -- Rest of message else -- Rest of message
if readOffset < readSize then if readOffset < readSize then
@ -118,17 +132,39 @@ begin
end if; end if;
elsif readSize > 0 and readOffset = readSize then -- Rest of message ended elsif readSize > 0 and readOffset = readSize then -- Rest of message ended
case readMessage is case readMessage is
when F2AT_CAPTs => when F2CT_CAPTs =>
frontTrigger <= to_integer(unsigned(readData(15 downto 0))); frontTrigger <= to_integer(unsigned(readData(15 downto 0)));
backTrigger <= to_integer(unsigned(readData(31 downto 16))); backTrigger <= to_integer(unsigned(readData(31 downto 16)));
triggerSet <= '1'; triggerSet <= '1';
when C2FD_PWMs =>
enA <= readData(7 downto 0);
enB <= readData(15 downto 8);
if readData(16) = '1' then
in1enC <= x"FF";
else
in1enC <= x"00";
end if;
in2 <= readData(17);
if readData(18) = '1' then
in3enD <= x"FF";
else
in3enD <= x"00";
end if;
in4 <= readData(19);
when C2FD_PWM2s =>
enA <= readData(7 downto 0);
in1enC <= readData(15 downto 8);
enB <= readData(23 downto 16);
in3enD <= readData(31 downto 24);
in2 <= '0';
in4 <= '0';
when others => when others =>
pushSend(F2AD_ERR_UNKNOWN_CODEs); pushSend(F2CD_ERR_UNKNOWN_CODEs);
end case; end case;
readOffset <= 0; readOffset <= 0;
readSize <= 0; readSize <= 0;
elsif (triggerSet = '1' and ((front > frontTrigger) or (back > backTrigger))) then elsif (triggerSet = '1' and ((front > frontTrigger) or (back > backTrigger))) then
pushSend(F2AI_CAPTs); pushSend(F2CI_CAPTs);
triggerSet <= '0'; triggerSet <= '0';
end if; end if;
@ -146,22 +182,22 @@ begin
sendAvailable <= '1'; sendAvailable <= '1';
case sendQueueMemory(sendTail) is case sendQueueMemory(sendTail) is
when A2FD_PINGs => when C2FD_PINGs =>
sendData(7 downto 0) <= A2FD_PING; sendData(7 downto 0) <= C2FD_PING;
sendSize <= 1; sendSize <= 1;
when F2AI_CAPTs => when F2CI_CAPTs =>
sendData(7 downto 0) <= F2AI_CAPT; sendData(7 downto 0) <= F2CI_CAPT;
sendData(23 downto 8) <= std_logic_vector(to_signed(front, 16)); sendData(23 downto 8) <= std_logic_vector(to_signed(front, 16));
sendData(39 downto 24) <= std_logic_vector(to_unsigned(back, 16)); sendData(39 downto 24) <= std_logic_vector(to_unsigned(back, 16));
sendSize <= 5; sendSize <= 5;
when F2AI_CODERs => when F2CI_CODERs =>
zerocoder <= '1'; zerocoder <= '1';
sendData(7 downto 0) <= F2AI_CODER; sendData(7 downto 0) <= F2CI_CODER;
sendData(23 downto 8) <= std_logic_vector(to_signed(left, 16)); sendData(23 downto 8) <= std_logic_vector(to_signed(left, 16));
sendData(39 downto 24) <= std_logic_vector(to_signed(right, 16)); sendData(39 downto 24) <= std_logic_vector(to_signed(right, 16));
sendSize <= 5; sendSize <= 5;
when others => -- Including F2AD_ERR_UNKNOWN_CODEs when others => -- Including F2CD_ERR_UNKNOWN_CODEs
sendData(7 downto 0) <= F2AD_ERR; sendData(7 downto 0) <= F2CD_ERR;
sendData(15 downto 8) <= ERR_UNKNOWN_CODE; sendData(15 downto 8) <= ERR_UNKNOWN_CODE;
sendSize <= 2; sendSize <= 2;
end case; end case;

View file

@ -1,15 +1,15 @@
[*] [*]
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI [*] GTKWave Analyzer v3.3.89 (w)1999-2018 BSI
[*] Wed Feb 28 14:53:10 2018 [*] Tue May 1 04:06:11 2018
[*] [*]
[dumpfile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/communication_tb.ghw" [dumpfile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/communication_tb.ghw"
[dumpfile_mtime] "Wed Feb 28 14:51:41 2018" [dumpfile_mtime] "Tue May 1 04:02:41 2018"
[dumpfile_size] 7845 [dumpfile_size] 8903
[savefile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/communication_tb.gtkw" [savefile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/communication_tb.gtkw"
[timestart] 0 [timestart] 0
[size] 1600 862 [size] 1600 862
[pos] -1 -1 [pos] -1 -1
*-30.009827 1783000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 *-30.189280 1783000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] top. [treeopen] top.
[treeopen] top.communication_tb. [treeopen] top.communication_tb.
[treeopen] top.communication_tb.dut. [treeopen] top.communication_tb.dut.
@ -66,5 +66,22 @@ top.communication_tb.dut.backtrigger
top.communication_tb.dut.front top.communication_tb.dut.front
[color] 2 [color] 2
top.communication_tb.dut.back top.communication_tb.dut.back
@22
[color] 6
#{top.communication_tb.ena[7:0]} top.communication_tb.ena[7] top.communication_tb.ena[6] top.communication_tb.ena[5] top.communication_tb.ena[4] top.communication_tb.ena[3] top.communication_tb.ena[2] top.communication_tb.ena[1] top.communication_tb.ena[0]
[color] 6
#{top.communication_tb.in1enc[7:0]} top.communication_tb.in1enc[7] top.communication_tb.in1enc[6] top.communication_tb.in1enc[5] top.communication_tb.in1enc[4] top.communication_tb.in1enc[3] top.communication_tb.in1enc[2] top.communication_tb.in1enc[1] top.communication_tb.in1enc[0]
@28
[color] 6
top.communication_tb.dut.in2
@22
[color] 6
#{top.communication_tb.enb[7:0]} top.communication_tb.enb[7] top.communication_tb.enb[6] top.communication_tb.enb[5] top.communication_tb.enb[4] top.communication_tb.enb[3] top.communication_tb.enb[2] top.communication_tb.enb[1] top.communication_tb.enb[0]
@80023
[color] 6
#{top.communication_tb.in3end[7:0]} top.communication_tb.in3end[7] top.communication_tb.in3end[6] top.communication_tb.in3end[5] top.communication_tb.in3end[4] top.communication_tb.in3end[3] top.communication_tb.in3end[2] top.communication_tb.in3end[1] top.communication_tb.in3end[0]
@28
[color] 6
top.communication_tb.dut.in4
[pattern_trace] 1 [pattern_trace] 1
[pattern_trace] 0 [pattern_trace] 0

View file

@ -23,7 +23,14 @@ architecture tb of communication_tb is
txStb : out std_logic; txStb : out std_logic;
txAck : in std_logic; txAck : in std_logic;
rxData : in std_logic_vector (7 downto 0); rxData : in std_logic_vector (7 downto 0);
rxStb : in std_logic); rxStb : in std_logic;
enA : out std_logic_vector(7 downto 0);
in1enC : out std_logic_vector(7 downto 0);
in2 : out std_logic;
enB : out std_logic_vector(7 downto 0);
in3enD : out std_logic_vector(7 downto 0);
in4 : out std_logic
);
end component; end component;
signal clock : std_logic; signal clock : std_logic;
@ -38,6 +45,12 @@ architecture tb of communication_tb is
signal txAck : std_logic; signal txAck : std_logic;
signal rxData : std_logic_vector (7 downto 0); signal rxData : std_logic_vector (7 downto 0);
signal rxStb : std_logic; signal rxStb : std_logic;
signal enA : std_logic_vector(7 downto 0);
signal in1enC : std_logic_vector(7 downto 0);
signal in2 : std_logic;
signal enB : std_logic_vector(7 downto 0);
signal in3enD : std_logic_vector(7 downto 0);
signal in4 : std_logic;
constant TbPeriod : time := 20 ns; constant TbPeriod : time := 20 ns;
signal TbClock : std_logic := '0'; signal TbClock : std_logic := '0';
@ -59,7 +72,14 @@ begin
zerocoder => zerocoder, zerocoder => zerocoder,
txAck => txAck, txAck => txAck,
rxData => rxData, rxData => rxData,
rxStb => rxStb); rxStb => rxStb,
enA => enA,
in1enC => in1enC,
in2 => in2,
enB => enB,
in3enD => in3enD,
in4 => in4
);
-- Clock generation -- Clock generation
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0'; TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
@ -245,6 +265,46 @@ begin
wait for 100 ns; wait for 100 ns;
-- Test PWM1
report "TEST Receiving 'W'" severity note;
tampon(0 to 3) := (x"57", x"CC", x"77", x"03");
for I in 0 to 3 loop
rxData <= tampon(I);
rxStb <= '1';
wait for TbPeriod;
rxStb <= '0';
wait for TbPeriod;
end loop;
assert enA = x"CC" report "ENA not at correct value" severity error;
assert enB = x"77" report "ENB not at correct value" severity error;
assert in1enC = x"FF" report "IN1 not at correct value" severity error;
assert in2 = '1' report "IN1 not at correct value" severity error;
assert in3enD = x"00" report "IN3 not at correct value" severity error;
assert in4 = '0' report "IN4 not at correct value" severity error;
wait for 100 ns;
-- Test PWM2
report "TEST Receiving 'w'" severity note;
tampon(0 to 4) := (x"77", x"11", x"22", x"33", x"44");
for I in 0 to 4 loop
rxData <= tampon(I);
rxStb <= '1';
wait for TbPeriod;
rxStb <= '0';
wait for TbPeriod;
end loop;
assert enA = x"11" report "ENA not at correct value" severity error;
assert in1enC = x"22" report "ENC not at correct value" severity error;
assert enB = x"33" report "ENB not at correct value" severity error;
assert in3enD = x"44" report "END not at correct value" severity error;
wait for 100 ns;
TbSimEnded <= '1'; TbSimEnded <= '1';
wait; wait;

View file

@ -7,32 +7,56 @@ TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %;
# BTN # BTN
NET "BTN" LOC = "P41" | IOSTANDARD = LVTTL ; NET "BTN" LOC = "P41" | IOSTANDARD = LVTTL ;
# IO<0> # IO<10>
NET "RX" LOC = "P59" | IOSTANDARD = LVTTL ; NET "RX" LOC = "P85" | IOSTANDARD = LVTTL ;
# IO<1> # IO<11>
NET "TX" LOC = "P60" | IOSTANDARD = LVTTL ; NET "TX" LOC = "P84" | IOSTANDARD = LVTTL ;
# IO<2> # IO<12>
NET "LEFTCHA" LOC = "P61" | IOSTANDARD = LVTTL ; NET "LEFTCHA" LOC = "P83" | IOSTANDARD = LVTTL ;
# IO<3> # IO<13>
NET "LEFTCHB" LOC = "P62" | IOSTANDARD = LVTTL ; NET "LEFTCHB" LOC = "P78" | IOSTANDARD = LVTTL ;
# IO<4> # IO<14>
NET "RIGHTCHA" LOC = "P64" | IOSTANDARD = LVTTL ; NET "RIGHTCHA" LOC = "P77" | IOSTANDARD = LVTTL ;
# IO<5> # IO<15>
NET "RIGHTCHB" LOC = "P57" | IOSTANDARD = LVTTL ; NET "RIGHTCHB" LOC = "P65" | IOSTANDARD = LVTTL ;
# IO<6> # IO<16>
NET "FRONTTRIGGER" LOC = "P56" | IOSTANDARD = LVTTL ; NET "FRONTTRIGGER" LOC = "P70" | IOSTANDARD = LVTTL ;
# IO<7> # IO<17>
NET "FRONTECHO" LOC = "P52" | IOSTANDARD = LVTTL ; NET "FRONTECHO" LOC = "P71" | IOSTANDARD = LVTTL ;
# IO<8> # IO<18>
NET "BACKTRIGGER" LOC = "P50" | IOSTANDARD = LVTTL ; NET "BACKTRIGGER" LOC = "P72" | IOSTANDARD = LVTTL ;
# IO<9> # IO<19>
NET "BACKECHO" LOC = "P49" | IOSTANDARD = LVTTL ; NET "BACKECHO" LOC = "P73" | IOSTANDARD = LVTTL ;
# IO<20>
NET "ENA" LOC = "P5" | IOSTANDARD = LVTTL ;
# IO<21>
NET "IN1ENC" LOC = "P4" | IOSTANDARD = LVTTL ;
# IO<22>
NET "IN2" LOC = "P6" | IOSTANDARD = LVTTL ;
# IO<23>
NET "ENB" LOC = "P98" | IOSTANDARD = LVTTL ;
# IO<24>
NET "IN3END" LOC = "P94" | IOSTANDARD = LVTTL ;
# IO<25>
NET "IN4" LOC = "P93" | IOSTANDARD = LVTTL ;
# NET "IO<26>" LOC = "P90" | IOSTANDARD = LVTTL ;
# NET "IO<27>" LOC = "P89" | IOSTANDARD = LVTTL ;
# NET "IO<28>" LOC = "P88" | IOSTANDARD = LVTTL ;
# NET "IO<29>" LOC = "P86" | IOSTANDARD = LVTTL ;

View file

@ -5,5 +5,5 @@ PROGRAMMER = mercpcl
TOPLEVEL = Principal TOPLEVEL = Principal
# Prod # Prod
VHDSOURCE = $(TOPLEVEL).vhd communication.vhd uart.vhd hedm.vhd hcsr04.vhd fir.vhd VHDSOURCE = $(TOPLEVEL).vhd communication.vhd uart.vhd hedm.vhd hcsr04.vhd fir.vhd pwm.vhd
CONSTRAINTS = principal.ucf CONSTRAINTS = principal.ucf

30
fpga/pwm.vhd Normal file
View file

@ -0,0 +1,30 @@
-- Inspiré de http://www.fpga4fun.com/PWM_DAC_2.html
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
entity PWM is
port (
clk : in std_logic;
data : in std_logic_vector (7 downto 0) := "00000000";
pulse : out std_logic
);
end PWM;
architecture Behavioral of PWM is
signal accuI : integer;
signal dataI : integer;
begin
dataI <= to_integer(unsigned(data));
process(clk, data)
begin
if rising_edge(clk) then
accuI <= accuI mod 256 + dataI + 1;
end if;
end process;
pulse <= '1' when accuI >= 256 else '0';
end Behavioral;