2026-USB-Maitre/log_usb.c

217 lines
7.3 KiB
C

#include <string.h>
#include "pico/platform/panic.h"
#include "pico/stdlib.h"
#include "messagerie.h"
#include "log_usb.h"
#include <stdio.h>
#define TAMPON_TAILLE 1020
struct log_buffer_t log_buffer[NB_MAX_CDC_CONNEXION];
/// @brief Affecte l'id de la carte à une connexion CDC.
/// @param idx
/// @param carte_id
void set_carte_id(uint8_t idx, uint8_t carte_id){
struct log_buffer_t * p_log_bufffer;
p_log_bufffer = get_buffer(idx);
p_log_bufffer->carte_id = carte_id;
}
/// @brief Obtient la connexion CDC à partir de l'id de la carte.
/// @param id_carte
/// @return idx pour établir la connexion CDC, INVALID_ID si non trouvé.
uint8_t get_carte_idx(uint8_t id_carte){
for(int i=0; i<NB_MAX_CDC_CONNEXION; i++){
if(log_buffer[i].carte_id == id_carte){
return log_buffer[i].idx;
}
}
printf("IDX not found - carte_id: %d\n", id_carte);
return INVALID_ID;
}
struct log_buffer_t * get_buffer(const char idx){
for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){
if(log_buffer[i].idx == idx){
return &(log_buffer[i]);
}
}
/// TODO: panic ?
panic("Buffer IDX not found: %d\n", idx);
return NULL;
}
/// @brief Initialisation des structure de reception des données USB-CDC
void log_init(){
for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){
log_buffer[i].idx = INVALID_ID;
log_buffer[i].carte_id = INVALID_ID;
log_buffer[i].index_tampon_ecriture = 0;
log_buffer[i].index_tampon_lecture = 0;
}
}
/// @brief Affectation des tampons de reception à une liaison USB-CDC
/// @param idx :
void log_create(const char idx){
for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){
if(log_buffer[i].idx == INVALID_ID){
log_buffer[i].idx = idx;
log_buffer[i].carte_id = INVALID_ID;
log_buffer[i].index_tampon_ecriture = 0;
log_buffer[i].index_tampon_lecture = 0;
return;
}
}
panic("Creation impossible: idx: %d\n", idx);
}
void log_destroy(const char idx){
struct log_buffer_t * p_log_bufffer;
p_log_bufffer = get_buffer(idx);
p_log_bufffer->idx = INVALID_ID;
printf("Destruction: idx: %d\n", idx);
}
/// @brief Ajoute les données reçu au tampon tournant
/// @param idx Numéro de la liaison CDC
/// @param buffer Pointeur vers les données
/// @param buffer_size Taille des données
void log_add(const char idx, const char * buffer, uint16_t buffer_size){
struct log_buffer_t * log_buffer;
log_buffer = get_buffer(idx);
for(int i=0; i<buffer_size; i++){
log_buffer->index_tampon_ecriture = log_buffer->index_tampon_ecriture+1;
if(log_buffer->index_tampon_ecriture >= TAMPON_TAILLE){
log_buffer->index_tampon_ecriture = 0;
}
log_buffer->tampon[log_buffer->index_tampon_ecriture] = buffer[i];
}
}
/// @brief Incrémente l'index du tampon tournant
/// @param index
/// @return
void increment_index(unsigned int *index){
*index = 1 + *index ;
if((*index) >= TAMPON_TAILLE){
*index = 0;
}
}
/// @brief augmente la position l'index du tampon tournant
/// @param index
/// @return
void augmente_index(unsigned int *index, unsigned int offset){
*index = offset + *index ;
if((*index) >= TAMPON_TAILLE){
*index -= TAMPON_TAILLE;
}
}
void log_analyse(const char idx){
// Les données sont dans le tampon tournant
// Nous les copions dans une seconde mémoire pour les analyser.
// Si un message est trouvé :
// - Celui-ci est ajouté à la liste des message à traiter
// - Nous avançons l'index de lecture du tampon cyclique
// Si nous arrivons à la fin du tampon cyclique, il n'y a plus rien à récupérer.
enum etat_message_t{
ETAT_MESSAGE_DEBUT,
ETAT_MESSAGE_TEXTE,
ETAT_MESSAGE_VALIDE
}etat_message;
struct log_buffer_t * p_log_bufffer;
char chaine[TAMPON_TAILLE];
char affiche_message[TAMPON_TAILLE];
struct message_t message;
unsigned int index, index_chaine;
p_log_bufffer = get_buffer(idx);
index = p_log_bufffer->index_tampon_lecture;
index_chaine = 0;
// Copie des données
while(index != p_log_bufffer->index_tampon_ecriture){
chaine[index_chaine] = p_log_bufffer->tampon[index];
index_chaine++;
increment_index(&index);
}
// Lecture du message
message.type = 0;
message.idx = idx;
unsigned int fin_message = 0;
for(int i=0; i< index_chaine; i++){
unsigned int index_fin_message;
switch(etat_message){
case ETAT_MESSAGE_DEBUT:
if(chaine[i] == '>'){
message.type = '>';
message.taille_donnees = 0;
etat_message = ETAT_MESSAGE_TEXTE;
}
if(chaine[i] == 'd'){
// Est-ce que nous avons reçu le message en entier ?
if(i + 4 < index_chaine){
if(chaine[i+4] == 0){
// Message valide
message.type = 'd';
message.id_carte = chaine[i+1];
message.adresse_registre = chaine[i+2];
message.taille_donnees = chaine[i+3];
i = i + 4; // On se met à la fin du message
fin_message = i;
put_message(message);
}
}
}
if(chaine[i] == 'r'){
// Est-ce que nous avons reçu l'entête du message ?
if(i + 4 < index_chaine){
message.type = 'r';
message.id_carte = chaine[i+1];
message.adresse_registre = chaine[i+2];
message.taille_donnees = chaine[i+3];
index_fin_message = i + message.taille_donnees + 4;
if(index_fin_message < index_chaine){
if(chaine[index_fin_message] == 0){
// Message valide
for(int index_donnees=0; index_donnees<message.taille_donnees; index_donnees++){
message.donnees[index_donnees] = chaine[index_donnees + i + 4];
}
i = index_fin_message; // On se met à la fin du message
fin_message = index_fin_message;
etat_message = ETAT_MESSAGE_DEBUT;
put_message(message);
}
}
}
}
break;
case ETAT_MESSAGE_TEXTE:
message.donnees[message.taille_donnees] = chaine[i];
message.taille_donnees++;
if(chaine[i] == '\n'){
// message valide.
message.donnees[message.taille_donnees] = '\0';
fin_message = i;
put_message(message);
etat_message = ETAT_MESSAGE_DEBUT;
}
break;
}
}
augmente_index(&(p_log_bufffer->index_tampon_lecture), fin_message);
}