2018-04-04 16:17:13 +02:00
|
|
|
#include "CF.h"
|
2018-02-16 15:44:45 +01:00
|
|
|
#include <fcntl.h> // O_*
|
|
|
|
#include <stdio.h> // printf...
|
|
|
|
#include <stdlib.h> // stuff
|
|
|
|
#include <string.h> // memcpy
|
|
|
|
#include <strings.h> // bzero
|
|
|
|
#include <unistd.h> // read(), write()...
|
|
|
|
|
2018-05-08 00:45:08 +02:00
|
|
|
int fpga;
|
|
|
|
pthread_mutex_t sSendCF;
|
|
|
|
pthread_t tReaderAF;
|
|
|
|
|
|
|
|
rxHandler rxHandlersAF[256];
|
|
|
|
bool pret;
|
|
|
|
|
|
|
|
|
|
|
|
void printDataCF(void* data, size_t size)
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
|
|
|
printf(" ");
|
|
|
|
unsigned char* p = data;
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
|
|
|
if (*p >= ' ' && *p <= '~') {
|
|
|
|
printf(" %c", *p);
|
|
|
|
} else {
|
|
|
|
printf(" %02x", *p);
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void configureFpga()
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
|
|
|
// Connection au port série
|
2018-04-04 16:17:13 +02:00
|
|
|
printf("Connexion à %s... ", FPGA_PORTNAME);
|
2018-02-16 21:35:05 +01:00
|
|
|
fflush(stdout);
|
2018-05-01 14:51:41 +02:00
|
|
|
fpga = open(FPGA_PORTNAME, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
|
2018-04-04 16:17:13 +02:00
|
|
|
if (fpga < 0) {
|
2018-02-16 15:44:45 +01:00
|
|
|
printf("Échec !\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Configuration du port série
|
2018-05-01 14:51:41 +02:00
|
|
|
fcntl(fpga, F_SETFL, O_RDWR);
|
|
|
|
|
2018-02-16 15:44:45 +01:00
|
|
|
struct termios cfg;
|
2018-05-01 14:51:41 +02:00
|
|
|
|
|
|
|
tcgetattr(fpga, &cfg);
|
|
|
|
|
|
|
|
cfmakeraw(&cfg);
|
|
|
|
cfsetispeed(&cfg, CF_BAUDRATE);
|
|
|
|
cfsetospeed(&cfg, CF_BAUDRATE);
|
|
|
|
|
|
|
|
cfg.c_cflag |= (CLOCAL | CREAD);
|
|
|
|
cfg.c_cflag &= ~PARENB;
|
|
|
|
cfg.c_cflag &= ~CSTOPB;
|
|
|
|
cfg.c_cflag &= ~CSIZE;
|
|
|
|
cfg.c_cflag |= CS8;
|
|
|
|
cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
|
|
|
cfg.c_oflag &= ~OPOST;
|
|
|
|
|
|
|
|
cfg.c_cc[VMIN] = 0;
|
|
|
|
cfg.c_cc[VTIME] = 10;
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
if (tcsetattr(fpga, TCSANOW, &cfg) < 0) {
|
2018-02-16 15:44:45 +01:00
|
|
|
perror("serialConfig.tcsetattr");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2018-05-01 14:51:41 +02:00
|
|
|
int status;
|
|
|
|
ioctl(fpga, TIOCMGET, &status);
|
|
|
|
|
|
|
|
status |= TIOCM_DTR;
|
|
|
|
status |= TIOCM_RTS;
|
|
|
|
|
|
|
|
ioctl(fpga, TIOCMSET, &status);
|
|
|
|
|
|
|
|
usleep(10 * 1000);
|
2018-02-16 15:44:45 +01:00
|
|
|
|
|
|
|
// Flush
|
|
|
|
unsigned char trash[1024];
|
2018-04-04 16:17:13 +02:00
|
|
|
read(fpga, &trash, sizeof(trash));
|
2018-02-16 15:44:45 +01:00
|
|
|
|
|
|
|
printf("OK!\n");
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void deconfigureFpga()
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-04-04 16:17:13 +02:00
|
|
|
close(fpga);
|
2018-02-16 15:44:45 +01:00
|
|
|
printf("Déconnecté\n");
|
|
|
|
}
|
|
|
|
|
2018-05-08 00:45:08 +02:00
|
|
|
void registerRxHandlerCF(unsigned char code, rxHandler handler)
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-05-08 00:45:08 +02:00
|
|
|
rxHandlersAF[code] = handler;
|
2018-02-16 15:44:45 +01:00
|
|
|
}
|
|
|
|
|
2018-05-08 00:45:08 +02:00
|
|
|
void* TaskReaderAF(void* pdata)
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
|
|
|
(void)pdata;
|
|
|
|
unsigned char code;
|
|
|
|
for (;;) {
|
2018-04-04 16:17:13 +02:00
|
|
|
code = readByteCF();
|
2018-02-16 15:44:45 +01:00
|
|
|
|
|
|
|
#ifdef PRINTRAWDATA
|
|
|
|
printf("↓");
|
2018-05-08 00:45:08 +02:00
|
|
|
printDataCF(&code, sizeof(code));
|
2018-02-16 15:44:45 +01:00
|
|
|
#endif
|
2018-05-08 00:45:08 +02:00
|
|
|
rxHandler handler = rxHandlersAF[code];
|
2018-02-16 15:44:45 +01:00
|
|
|
if (handler != NULL) {
|
|
|
|
handler();
|
|
|
|
} else {
|
|
|
|
printf("Code inconnu: %x (%c)\n", code, code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void onF2CD_ERR()
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-04-04 16:17:13 +02:00
|
|
|
struct F2CD_ERRs s;
|
|
|
|
readCF(&s, sizeof(struct F2CD_ERRs));
|
2018-02-16 15:44:45 +01:00
|
|
|
printf("Erreur reçue : %c (%2x)\n", s.code, s.code);
|
|
|
|
}
|
|
|
|
|
2018-05-08 00:45:08 +02:00
|
|
|
void setPretCF()
|
2018-02-16 21:35:05 +01:00
|
|
|
{
|
|
|
|
pret = true;
|
|
|
|
}
|
|
|
|
|
2018-05-08 00:45:08 +02:00
|
|
|
void doNothingCF()
|
2018-02-16 21:35:05 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void configureCF()
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-04-04 16:17:13 +02:00
|
|
|
configureFpga();
|
2018-02-16 15:44:45 +01:00
|
|
|
for (int i = 0; i < 256; i++) {
|
2018-05-08 00:45:08 +02:00
|
|
|
rxHandlersAF[i] = NULL;
|
2018-02-16 15:44:45 +01:00
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
pthread_mutex_init(&sSendCF, NULL);
|
2018-05-08 00:45:08 +02:00
|
|
|
pthread_create(&tReaderAF, NULL, TaskReaderAF, NULL);
|
2018-02-16 21:35:05 +01:00
|
|
|
|
2018-04-30 22:40:20 +02:00
|
|
|
printf("Attente de réponse du Fpga... ");
|
2018-02-16 21:35:05 +01:00
|
|
|
fflush(stdout);
|
2018-04-04 16:17:13 +02:00
|
|
|
// Dans le cas où on aurait laissé l'Fpga en attente de donnée,
|
2018-02-16 21:35:05 +01:00
|
|
|
// on envoie des pings en boucle jusqu'à ce qu'il nous réponde.
|
|
|
|
pret = false;
|
2018-05-08 00:45:08 +02:00
|
|
|
registerRxHandlerCF(C2FD_PING, setPretCF);
|
2018-02-16 21:35:05 +01:00
|
|
|
while (!pret) {
|
2018-04-04 16:17:13 +02:00
|
|
|
sendCF(C2FD_PING, NULL, 0);
|
2018-05-01 14:51:41 +02:00
|
|
|
usleep(100 * 1000);
|
2018-02-16 21:35:05 +01:00
|
|
|
}
|
2018-05-08 00:45:08 +02:00
|
|
|
registerRxHandlerCF(C2FD_PING, doNothingCF); // TODO
|
|
|
|
registerRxHandlerCF(C2FD_PING, NULL);
|
2018-02-16 21:35:05 +01:00
|
|
|
printf("OK !\n");
|
|
|
|
|
2018-05-08 00:45:08 +02:00
|
|
|
registerRxHandlerCF(F2CD_ERR, onF2CD_ERR);
|
2018-02-16 15:44:45 +01:00
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void deconfigureCF()
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-04-04 16:17:13 +02:00
|
|
|
deconfigureFpga();
|
2018-02-16 15:44:45 +01:00
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void sendByteCF(unsigned char data)
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-04-04 16:17:13 +02:00
|
|
|
write(fpga, &data, sizeof(data));
|
2018-02-16 15:44:45 +01:00
|
|
|
|
|
|
|
#ifdef PRINTRAWDATA
|
|
|
|
printf("↑");
|
2018-05-08 00:45:08 +02:00
|
|
|
printDataCF(&data, sizeof(data));
|
2018-02-16 15:44:45 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void sendCF(unsigned char code, void* data, size_t size)
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
2018-04-04 16:17:13 +02:00
|
|
|
pthread_mutex_lock(&sSendCF);
|
2018-02-16 15:44:45 +01:00
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
sendByteCF(code);
|
2018-02-16 15:44:45 +01:00
|
|
|
if (size > 0) {
|
|
|
|
unsigned char* p = data;
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
2018-04-04 16:17:13 +02:00
|
|
|
write(fpga, p, sizeof(unsigned char));
|
2018-02-16 15:44:45 +01:00
|
|
|
p++;
|
|
|
|
}
|
|
|
|
// Envoyer plus d'un octet d'un coup curieusement il aime pas ça du tout
|
|
|
|
}
|
2018-04-04 16:17:13 +02:00
|
|
|
pthread_mutex_unlock(&sSendCF);
|
2018-02-16 15:44:45 +01:00
|
|
|
|
|
|
|
#ifdef PRINTRAWDATA
|
|
|
|
if (size > 0) {
|
|
|
|
printf("↑");
|
2018-05-08 00:45:08 +02:00
|
|
|
printDataCF(data, size);
|
2018-02-16 15:44:45 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
unsigned char readByteCF()
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
|
|
|
unsigned char c;
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
while (read(fpga, &c, sizeof(c)) < 1) {
|
2018-02-16 15:44:45 +01:00
|
|
|
sleep(0);
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
|
|
|
|
#ifdef PRINTRAWDATA
|
|
|
|
printf("↓");
|
2018-05-08 00:45:08 +02:00
|
|
|
printDataCF(&c, sizeof(c));
|
2018-02-16 15:44:45 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-04-04 16:17:13 +02:00
|
|
|
void readCF(void* data, size_t size)
|
2018-02-16 15:44:45 +01:00
|
|
|
{
|
|
|
|
size_t remaining = size;
|
|
|
|
int justRead;
|
|
|
|
char* p = data;
|
|
|
|
do {
|
2018-04-04 16:17:13 +02:00
|
|
|
justRead = read(fpga, p, remaining);
|
2018-02-16 15:44:45 +01:00
|
|
|
if (justRead > 0) {
|
|
|
|
p += justRead;
|
|
|
|
remaining -= justRead;
|
|
|
|
}
|
|
|
|
} while (remaining > 0);
|
|
|
|
|
|
|
|
#ifdef PRINTRAWDATA
|
|
|
|
printf("↓");
|
2018-05-08 00:45:08 +02:00
|
|
|
printDataCF(data, size);
|
2018-02-16 15:44:45 +01:00
|
|
|
#endif
|
|
|
|
}
|