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:
parent
760b950e83
commit
4af0f8c865
|
@ -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
|
||||||
|
|
|
@ -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
99
chef/src/buttons.c
Normal 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
30
chef/src/buttons.h
Normal 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
|
116
chef/src/ihm.c
116
chef/src/ihm.c
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
printf("%6d", rAbs);
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int changerMoteurs(float lVit, float rVit)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) "$<"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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
30
fpga/pwm.vhd
Normal 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;
|
Loading…
Reference in a new issue