Compare commits

..

10 Commits

16 changed files with 967 additions and 184 deletions

View File

@ -6,6 +6,7 @@
"${workspaceFolder}/build/generated/pico_base", "${workspaceFolder}/build/generated/pico_base",
"${env:PICO_SDK_PATH}/src/**/include", "${env:PICO_SDK_PATH}/src/**/include",
"${env:PICO_SDK_PATH}/lib/**/src", "${env:PICO_SDK_PATH}/lib/**/src",
"${env:PICO_SDK_PATH}/lib/tinyusb/hw",
"${workspaceFolder}/lib/FatFs/source", "${workspaceFolder}/lib/FatFs/source",
"${workspaceFolder}/lib/sd_driver" "${workspaceFolder}/lib/sd_driver"

24
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug (Cortex-Debug with external OpenOCD)",
"cwd": "${workspaceRoot}",
"executable": "debug/Modele_RPiPico.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "external",
"gdbTarget": "localhost:3333",
"gdbPath": "gdb-multiarch",
"device": "RP2040",
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/RP2040.svd",
"runToEntryPoint": "main",
// Fix for no_flash binaries, where monitor reset halt doesn't do what is expected
// Also works fine for flash binaries
"overrideLaunchCommands": [
"monitor reset init",
"load debug/Modele_RPiPico.elf"
]
},
]
}

View File

@ -14,6 +14,8 @@
"sd_card.h": "c", "sd_card.h": "c",
"rp2040_sdio.h": "c", "rp2040_sdio.h": "c",
"util.h": "c", "util.h": "c",
"stddef.h": "c" "stddef.h": "c",
"log_usb.h": "c",
"ws2812.h": "c"
} }
} }

View File

@ -22,7 +22,8 @@ target_sources(host_cdc_msc_hid PUBLIC
cdc_app.c cdc_app.c
diskio_USB.c diskio_USB.c
diskio_SDIO.c diskio_SDIO.c
log_usb.c com_usb.c
log.c
messagerie.c messagerie.c
lib/FatFs/source/ff.c lib/FatFs/source/ff.c
lib/FatFs/source/ffsystem.c lib/FatFs/source/ffsystem.c
@ -40,8 +41,13 @@ target_sources(host_cdc_msc_hid PUBLIC
lib/sd_driver/SPI/my_spi.c lib/sd_driver/SPI/my_spi.c
lib/sd_driver/SPI/sd_card_spi.c lib/sd_driver/SPI/sd_card_spi.c
lib/sd_driver/SPI/sd_spi.c lib/sd_driver/SPI/sd_spi.c
ws2812.c
) )
# generate the header file into the source tree as it is included in the RP2040 datasheet
pico_generate_pio_header(host_cdc_msc_hid ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
# Make sure TinyUSB can find tusb_config.h # Make sure TinyUSB can find tusb_config.h
target_include_directories(host_cdc_msc_hid PUBLIC target_include_directories(host_cdc_msc_hid PUBLIC
${CMAKE_CURRENT_LIST_DIR}/ ${CMAKE_CURRENT_LIST_DIR}/
@ -66,6 +72,7 @@ target_link_libraries( host_cdc_msc_hid PUBLIC
hardware_sync hardware_sync
pico_aon_timer pico_aon_timer
pico_stdlib pico_stdlib
pico_multicore
${HWDEP_LIBS} ${HWDEP_LIBS}
) )

View File

@ -27,21 +27,12 @@
#include "tusb.h" #include "tusb.h"
#include "bsp/board_api.h" #include "bsp/board_api.h"
#include "messagerie.h" #include "messagerie.h"
#include "log_usb.h" #include "com_usb.h"
#include "log.h"
#include <stdio.h> #include <stdio.h>
#define TAMPON_TOURNANT_TAILLE 255
#define TAMPON_TOURNANT_NB 10
volatile bool in_transfert_cb = 0; volatile bool in_transfert_cb = 0;
struct tampon_tournant_t{
uint8_t id;
uint8_t donnees[TAMPON_TOURNANT_TAILLE];
uint16_t index_ecriture, index_lecture;
} tampons_tournant[TAMPON_TOURNANT_NB];
size_t get_console_inputs(uint8_t* buf, size_t bufsize) { size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
size_t count = 0; size_t count = 0;
while (count < bufsize) { while (count < bufsize) {
@ -55,6 +46,58 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
return count; return count;
} }
void traiter_les_messages(uint8_t idx, struct message_t message){
// Debug
char message_en_clair[1024];
message_to_string(message, message_en_clair);
log_event(message_en_clair);
if(message.type == '>'){
char message_en_clair[1024];
message_to_string(message, message_en_clair);
printf("%s\n", message_en_clair);
}
if(message.type == 'r'){
// Reception de données
set_carte_id(idx, message.id_carte);
struct log_buffer_t * log_buffer = get_buffer(idx);
for(int i=0; i<message.taille_donnees; i++){
log_buffer->tampon_echange[message.adresse_registre + i] = message.donnees[i];
}
/*char message_en_clair[1024];
message_to_string(message, message_en_clair);
log_event(message_en_clair);*/
//printf(">d:%d\n",log_buffer->tampon_echange[0]);
}
if(message.type == 'd'){
struct message_t message_emis;
char message_binaire[64];
uint32_t taille_message;
// Demande de données
uint8_t idx_lecture = get_carte_idx(message.id_carte);
if(idx_lecture == INVALID_ID){
printf("Erreur, no idx found\n");
return;
}
struct log_buffer_t * log_buffer = get_buffer(idx_lecture);
message_emis.type = 'r';
message_emis.id_carte = message.id_carte;
message_emis.adresse_registre = message.adresse_registre;
message_emis.taille_donnees = message.taille_donnees;
memcpy(message_emis.donnees, &(log_buffer->tampon_echange[message.adresse_registre]), message.taille_donnees);
taille_message = message_prepare_for_usb(message_emis, message_binaire);
tuh_cdc_write(idx, message_binaire, taille_message);
}
}
void cdc_app_task(void) { void cdc_app_task(void) {
uint8_t buf[64 + 1]; // +1 for extra null character uint8_t buf[64 + 1]; // +1 for extra null character
uint32_t const bufsize = sizeof(buf) - 1; uint32_t const bufsize = sizeof(buf) - 1;
@ -78,16 +121,13 @@ void cdc_app_task(void) {
if (tuh_cdc_mounted(idx)) { if (tuh_cdc_mounted(idx)) {
struct message_t message; struct message_t message;
char chaine[1024]; char chaine[1024];
char message_en_clair[1024];
char texte_log[255]; char texte_log[255];
unsigned int position_chaine = 0, position_sous_chaine; unsigned int position_chaine = 0, position_sous_chaine;
log_analyse(idx); com_analyse(idx);
while(message_disponible()){ while(message_disponible()){
message = get_message(); message = get_message();
// Debug traiter_les_messages(idx, message);
message_to_string(message, message_en_clair);
printf("%s\n", message_en_clair);
} }
} }
@ -113,7 +153,7 @@ void tuh_cdc_rx_cb(uint8_t idx) {
uint32_t count = tuh_cdc_read(idx, buf, bufsize); uint32_t count = tuh_cdc_read(idx, buf, bufsize);
buf[count] = 0; buf[count] = 0;
log_add(idx, buf, count); com_add(idx, buf, count);
in_transfert_cb = 0; in_transfert_cb = 0;
} }
@ -124,9 +164,9 @@ void tuh_cdc_mount_cb(uint8_t idx) {
tuh_itf_info_t itf_info = {0}; tuh_itf_info_t itf_info = {0};
tuh_cdc_itf_get_info(idx, &itf_info); tuh_cdc_itf_get_info(idx, &itf_info);
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, printf("CDC Interface is mounted: address = %u, itf_num = %u, idx = %u\r\n", itf_info.daddr,
itf_info.desc.bInterfaceNumber); itf_info.desc.bInterfaceNumber, idx);
log_create(idx); com_create(idx);
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
// If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack // If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack
@ -151,5 +191,5 @@ void tuh_cdc_umount_cb(uint8_t idx) {
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr,
itf_info.desc.bInterfaceNumber); itf_info.desc.bInterfaceNumber);
log_destroy(idx); com_destroy(idx);
} }

View File

@ -2,24 +2,37 @@
#include "pico/platform/panic.h" #include "pico/platform/panic.h"
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "messagerie.h" #include "messagerie.h"
#include "com_usb.h"
#include <stdio.h> #include <stdio.h>
#define NB_MAX_CDC_CONNEXION 10
#define TAMPON_TAILLE 1020 #define TAMPON_TAILLE 1020
#define INVALID_ID ((char)-1)
struct log_buffer_t{ struct log_buffer_t log_buffer[NB_MAX_CDC_CONNEXION];
char idx;
char copy_active;
char tampon[TAMPON_TAILLE]; // Tampon tournant - 1er niveau de tampon
char log_dispo[TAMPON_TAILLE]; //
unsigned int index_tampon;
unsigned int index_tampon_ecriture, index_tampon_lecture;
}log_buffer[10];
static struct log_buffer_t * get_buffer(const char idx); /// @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;
}
static struct log_buffer_t * get_buffer(const char idx){ /// @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++){ for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){
if(log_buffer[i].idx == idx){ if(log_buffer[i].idx == idx){
return &(log_buffer[i]); return &(log_buffer[i]);
@ -31,13 +44,10 @@ static struct log_buffer_t * get_buffer(const char idx){
} }
/// @brief Initialisation des structure de reception des données USB-CDC /// @brief Initialisation des structure de reception des données USB-CDC
void log_init(){ void com_init(){
for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){ for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){
log_buffer[i].log_dispo[0] = '\0';
log_buffer[i].index_tampon = 0;
log_buffer[i].copy_active = 0;
log_buffer[i].idx = INVALID_ID; log_buffer[i].idx = INVALID_ID;
log_buffer[i].index_tampon = 0; log_buffer[i].carte_id = INVALID_ID;
log_buffer[i].index_tampon_ecriture = 0; log_buffer[i].index_tampon_ecriture = 0;
log_buffer[i].index_tampon_lecture = 0; log_buffer[i].index_tampon_lecture = 0;
} }
@ -45,14 +55,11 @@ void log_init(){
/// @brief Affectation des tampons de reception à une liaison USB-CDC /// @brief Affectation des tampons de reception à une liaison USB-CDC
/// @param idx : /// @param idx :
void log_create(const char idx){ void com_create(const char idx){
for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){ for (int i=0; i<NB_MAX_CDC_CONNEXION; i++){
if(log_buffer[i].idx == INVALID_ID){ if(log_buffer[i].idx == INVALID_ID){
log_buffer[i].idx = idx; log_buffer[i].idx = idx;
log_buffer[i].log_dispo[0] = '\0'; log_buffer[i].carte_id = INVALID_ID;
log_buffer[i].index_tampon = 0;
log_buffer[i].copy_active = 0;
log_buffer[i].index_tampon = 0;
log_buffer[i].index_tampon_ecriture = 0; log_buffer[i].index_tampon_ecriture = 0;
log_buffer[i].index_tampon_lecture = 0; log_buffer[i].index_tampon_lecture = 0;
return; return;
@ -61,19 +68,18 @@ void log_create(const char idx){
panic("Creation impossible: idx: %d\n", idx); panic("Creation impossible: idx: %d\n", idx);
} }
void log_destroy(const char idx){ void com_destroy(const char idx){
struct log_buffer_t * p_log_bufffer; struct log_buffer_t * p_log_bufffer;
p_log_bufffer = get_buffer(idx); p_log_bufffer = get_buffer(idx);
p_log_bufffer->idx = INVALID_ID; p_log_bufffer->idx = INVALID_ID;
printf("Destruction: idx: %d\n", idx); printf("Destruction: idx: %d\n", idx);
sleep_ms(1500);
} }
/// @brief Ajoute les données reçu au tampon tournant /// @brief Ajoute les données reçu au tampon tournant
/// @param idx Numéro de la liaison CDC /// @param idx Numéro de la liaison CDC
/// @param buffer Pointeur vers les données /// @param buffer Pointeur vers les données
/// @param buffer_size Taille des données /// @param buffer_size Taille des données
void log_add(const char idx, const char * buffer, uint16_t buffer_size){ void com_add(const char idx, const char * buffer, uint16_t buffer_size){
struct log_buffer_t * log_buffer; struct log_buffer_t * log_buffer;
log_buffer = get_buffer(idx); log_buffer = get_buffer(idx);
@ -106,10 +112,13 @@ void augmente_index(unsigned int *index, unsigned int offset){
} }
} }
void com_analyse(const char idx){
//printf("com_analyse %d\n", idx);
static absolute_time_t current_time_us, start_time_us=0;
current_time_us = get_absolute_time();
//printf(">a:%lld\n", current_time_us-start_time_us);
start_time_us = current_time_us;
void log_analyse(const char idx){
// Les données sont dans le tampon tournant // Les données sont dans le tampon tournant
// Nous les copions dans une seconde mémoire pour les analyser. // Nous les copions dans une seconde mémoire pour les analyser.
// Si un message est trouvé : // Si un message est trouvé :
@ -134,18 +143,23 @@ void log_analyse(const char idx){
index_chaine = 0; index_chaine = 0;
// Copie des données // Copie des données
do{ if(index != p_log_bufffer->index_tampon_ecriture){
while(index != p_log_bufffer->index_tampon_ecriture){
chaine[index_chaine] = p_log_bufffer->tampon[index];
index_chaine++;
increment_index(&index);
}
chaine[index_chaine] = p_log_bufffer->tampon[index]; chaine[index_chaine] = p_log_bufffer->tampon[index];
index_chaine++; index_chaine++;
increment_index(&index); increment_index(&index);
}while(index != log_buffer->index_tampon_ecriture); }
// Lecture du message // Lecture du message
message.type = 0; message.type = 0;
message.idx = idx; message.idx = idx;
unsigned int fin_message = 0; unsigned int fin_message = 0;
for(int i=0; i< index_chaine; i++){ for(int i=0; i< index_chaine; i++){
char index_fin_message; unsigned int index_fin_message;
switch(etat_message){ switch(etat_message){
case ETAT_MESSAGE_DEBUT: case ETAT_MESSAGE_DEBUT:
if(chaine[i] == '>'){ if(chaine[i] == '>'){
@ -170,18 +184,19 @@ void log_analyse(const char idx){
} }
if(chaine[i] == 'r'){ if(chaine[i] == 'r'){
// Est-ce que nous avons reçu l'entête du message ? // Est-ce que nous avons reçu l'entête du message ?
if(i + 3 < index_chaine){ if(i + 4 < index_chaine){
message.type = 'r'; message.type = 'r';
message.adresse_registre = chaine[i+1]; message.id_carte = chaine[i+1];
message.taille_donnees = chaine[i+2]; message.adresse_registre = chaine[i+2];
index_fin_message = i+ message.taille_donnees + 3; message.taille_donnees = chaine[i+3];
index_fin_message = i + message.taille_donnees + 4;
if(index_fin_message < index_chaine){ if(index_fin_message < index_chaine){
if(chaine[index_fin_message] == 0){ if(chaine[index_fin_message] == 0){
// Message valide // Message valide
for(int j=i+3; j<index_fin_message; j++){ for(int index_donnees=0; index_donnees<message.taille_donnees; index_donnees++){
message.donnees[j - (i+3)] = chaine[j]; message.donnees[index_donnees] = chaine[index_donnees + i + 4];
} }
i = i + index_fin_message; // On se met à la fin du message i = index_fin_message; // On se met à la fin du message
fin_message = index_fin_message; fin_message = index_fin_message;
etat_message = ETAT_MESSAGE_DEBUT; etat_message = ETAT_MESSAGE_DEBUT;
@ -209,43 +224,5 @@ void log_analyse(const char idx){
} }
augmente_index(&(p_log_bufffer->index_tampon_lecture), fin_message); augmente_index(&(p_log_bufffer->index_tampon_lecture), fin_message);
//printf("Fin com_analyse %d\n", idx);
} }
void log_analyse_input_string(const char idx, const char * input_data, unsigned int str_len){
// On charge les données dans le tampon
// Si on a un message complet, on charge dans log dispo (s'il y a la place)
struct log_buffer_t * p_log_bufffer;
p_log_bufffer = get_buffer(idx);
for(int i=0; i< str_len; i++){
if(input_data[i] == '>'){
p_log_bufffer->copy_active = 1;
}
if(p_log_bufffer->copy_active == 1){
p_log_bufffer->tampon[p_log_bufffer->index_tampon] = input_data[i];
p_log_bufffer->index_tampon++;
if(input_data[i] == '\n'){
p_log_bufffer->copy_active = 0;
p_log_bufffer->tampon[p_log_bufffer->index_tampon] = '\0';
strcat(p_log_bufffer->log_dispo, p_log_bufffer->tampon);
p_log_bufffer->index_tampon=0;
}
}
}
}
// On renvoi la chaine et on remet log_dispo à 0;
void log_get(const char idx, char * chaine){
struct log_buffer_t * p_log_bufffer;
p_log_bufffer = get_buffer(idx);
if(p_log_bufffer == NULL){
chaine[0] = '\0';
return;
}
strcpy(chaine, p_log_bufffer->log_dispo);
p_log_bufffer->log_dispo[0] = '\0';
}

21
com_usb.h Normal file
View File

@ -0,0 +1,21 @@
#define TAMPON_TAILLE 1020
#define NB_MAX_CDC_CONNEXION 10
#define INVALID_ID ((char)-1)
struct log_buffer_t{
char idx;
char carte_id;
char tampon[TAMPON_TAILLE]; // Tampon tournant - 1er niveau de tampon
char tampon_echange[TAMPON_TAILLE]; // Tampon contenant l'état de la carte
unsigned int index_tampon_ecriture, index_tampon_lecture;
};
void com_init(void);
void com_create(const char idx);
void com_destroy(const char idx);
void com_analyse(const char idx);
void com_add(const char idx, const char * buffer, uint16_t buffer_size);
struct log_buffer_t * get_buffer(const char idx);
void set_carte_id(uint8_t idx, uint8_t carte_id);
uint8_t get_carte_idx(uint8_t id_carte);

203
log.c Normal file
View File

@ -0,0 +1,203 @@
#include <string.h>
#include <stdio.h>
#include "pico/stdlib.h"
#include "ff.h"
#define TAILLE_TAMPON_LECTURE 10
#define TAILLE_TAMPON_ECRITURE 0x8000
struct tampon_ecriture_t{
char tampon0[TAILLE_TAMPON_ECRITURE], tampon1[TAILLE_TAMPON_ECRITURE];
char * tampon_a_ecrire, *tampon_actif;
unsigned int index_tampon, taille_tampon_a_ecrire;
FIL fp;
} tampon_event, tampon_telemetrie;
void ecrit_tampon_dans_sd(struct tampon_ecriture_t * tampon_ecriture){
if(tampon_ecriture->tampon_a_ecrire != NULL){
absolute_time_t current_time, start_time;
unsigned int nb_ecrit;
start_time = get_absolute_time();
f_write(&tampon_ecriture->fp, tampon_ecriture->tampon_a_ecrire, tampon_ecriture->taille_tampon_a_ecrire, &nb_ecrit);
f_sync(&tampon_ecriture->fp);
current_time = get_absolute_time();
printf(">sd(Mo/s):%d:%.3f\n", (int)(current_time/1000), (float)(nb_ecrit) / (float)(current_time - start_time));
//printf(">Octets:%d:%d\n", (int)(current_time/1000), nb_ecrit);
//printf(">temps_sd:%d:%lld\n", (int)(current_time/1000), current_time - start_time);
tampon_ecriture->tampon_a_ecrire = NULL;
}
}
void routine_log_sd(void){
while(1){
ecrit_tampon_dans_sd(&tampon_event);
ecrit_tampon_dans_sd(&tampon_telemetrie);
sleep_ms(10);
}
};
void ajout_texte_a_tampon(const char *chaine, struct tampon_ecriture_t * tampon_ecriture){
if(tampon_ecriture->index_tampon + strlen(chaine) > TAILLE_TAMPON_ECRITURE){
tampon_ecriture->tampon_a_ecrire = tampon_ecriture->tampon_actif;
// permutation du tampon actif
// indication du tampon à écrire
// remise à 0 de l'index du tampon
if(tampon_ecriture->tampon_actif == tampon_ecriture->tampon0){
tampon_ecriture->tampon_actif = tampon_ecriture->tampon1;
tampon_ecriture->tampon_a_ecrire = tampon_ecriture->tampon0;
}else{
tampon_ecriture->tampon_actif = tampon_ecriture->tampon0;
tampon_ecriture->tampon_a_ecrire = tampon_ecriture->tampon1;
}
tampon_ecriture->taille_tampon_a_ecrire = tampon_ecriture->index_tampon;
tampon_ecriture->index_tampon = 0;
tampon_ecriture->tampon_actif[0] = 0;
}
strcat(tampon_ecriture->tampon_actif, chaine);
tampon_ecriture->index_tampon += strlen(chaine);
ecrit_tampon_dans_sd(tampon_ecriture);
}
void init_tampon_ecriture( struct tampon_ecriture_t * tampon_ecriture ){
tampon_ecriture->tampon_actif = tampon_ecriture->tampon0;
tampon_ecriture->index_tampon = 0;
tampon_ecriture->tampon_a_ecrire = NULL;
tampon_ecriture->tampon0[0];
tampon_ecriture->tampon1[0];
}
char * get_tampon_inactif(struct tampon_ecriture_t * tampon_ecriture){
if(tampon_ecriture->index_tampon){
return tampon_ecriture->tampon0;
}
return tampon_ecriture->tampon1;
}
char * get_tampon_actif(struct tampon_ecriture_t * tampon_ecriture){
if(tampon_ecriture->index_tampon){
return tampon_ecriture->tampon0;
}
return tampon_ecriture->tampon1;
}
void log_message(const char * message, struct tampon_ecriture_t * tampon_ecriture);
int log_running = 0;
void erreur(char * message){
while(1){
puts(message);
sleep_ms(100);
}
}
void log_init(const char * drive_path){
FIL fp;
FRESULT result;
uint16_t num_log;
unsigned int nb_lu;
char message_erreur[150];
char tampon[TAILLE_TAMPON_LECTURE];
// Ouverture de num_log.txt
char path_num_log[20], path[30];
strcpy(path_num_log, drive_path);
strcat(path_num_log, "/num_log.txt");
result = f_open(&fp, path_num_log, FA_OPEN_EXISTING | FA_READ);
num_log = 0;
if(!result){
// le fichier existe, lisons-le
result = f_read (&fp, tampon, TAILLE_TAMPON_LECTURE, &nb_lu);
if(!result){
// lisons le nombre dans le tampon
for(int index = 0; index < TAILLE_TAMPON_LECTURE; index++){
if(tampon[index] >= '0' && tampon[index] <= '9'){
num_log = num_log * 10 + tampon[index] - '0';
}else{
break;
}
}
num_log++;
}else{
sprintf(message_erreur, "Échec à la lecture du fichier %s: %d", path_num_log, result);
erreur(message_erreur);
}
}
f_close(&fp);
// Écriture de num_log dans num_log.txt
sprintf(tampon, "%d\n", num_log);
printf("%s", tampon);
result = f_open(&fp, path_num_log, FA_CREATE_ALWAYS | FA_WRITE);
if(!result){
result = f_write(&fp, tampon, strlen(tampon), &nb_lu);
if(result){
sprintf(message_erreur, "Échec à l'écriture du fichier %s: %d", path_num_log, result);
erreur(message_erreur);
}
}else{
sprintf(message_erreur, "Échec à l'ouverture du fichier %s: %d", path_num_log, result);
erreur(message_erreur);
}
f_close(&fp);
printf("num_log:%d\n", num_log);
init_tampon_ecriture(&tampon_event);
init_tampon_ecriture(&tampon_telemetrie);
// Ouverture du fichier de log
sprintf(path, "%s%s%03d.txt", drive_path, "data", num_log);
printf("path: %s\n", path);
result = f_open(&(tampon_telemetrie.fp), path, FA_CREATE_ALWAYS | FA_WRITE);
if(result){
sprintf(message_erreur, "Échec à l'ouverture du fichier %s: %d", path, result);
erreur(message_erreur);
}
result = f_write(&(tampon_telemetrie.fp), "Début du fichier\n", strlen("Début du fichier"), &nb_lu);
f_sync(&(tampon_telemetrie.fp));
printf("Fichier créé: %s\n", path);
// Ouverture du fichier de telemetrie
sprintf(path, "%s%s%03d.txt", drive_path, "event", num_log);
result = f_open(&(tampon_event.fp), path, FA_CREATE_ALWAYS | FA_WRITE);
result |= f_write(&(tampon_event.fp), "Début du fichier\n", strlen("Début du fichier"), &nb_lu);
if(result){
sprintf(message_erreur, "Échec à l'ouverture du fichier %s: %d", path, result);
erreur(message_erreur);
}
printf("Fichier créé: %s\n", path);
log_running = 1;
}
void log_telemetrie(char * message){
log_message(message, &tampon_telemetrie);
}
void log_event(char * message){
log_message(message, &tampon_event);
}
void log_message(const char * message, struct tampon_ecriture_t * tampon_ecriture){
if(log_running){
absolute_time_t current_time;
char temps[20];
current_time = get_absolute_time();
sprintf(temps, "%lld:", current_time);
ajout_texte_a_tampon(temps, tampon_ecriture);
ajout_texte_a_tampon(message, tampon_ecriture);
}
}

4
log.h Normal file
View File

@ -0,0 +1,4 @@
void log_init(const char * drive_path);
void log_telemetrie(char * message);
void log_event(char * message);
void routine_log_sd(void);

View File

@ -1,8 +0,0 @@
void log_init(void);
void log_create(const char idx);
void log_destroy(const char idx);
void log_analyse_input_string(const char idx, char * input_data, unsigned int str_len);
void log_get(const char idx, char * chaine);
void log_analyse(const char idx);
void log_add(const char idx, const char * buffer, uint16_t buffer_size);

128
main.c
View File

@ -32,7 +32,10 @@
#include "tusb.h" #include "tusb.h"
#include "ff.h" #include "ff.h"
#include "f_util.h" #include "f_util.h"
#include "log_usb.h" #include "log.h"
#include "com_usb.h"
#include "pico/multicore.h"
#include "ws2812.h"
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES // MACRO CONSTANT TYPEDEF PROTYPES
@ -102,16 +105,133 @@ sd_card_t* sd_get_by_num(size_t num) {
} }
} }
void sd_card_gestion(){
if(gpio_get(1) == 1){
ws2812_set_buffer_rgb(OFF_24BITS, 0);
// Unmount FS + de-init log SD
}else{
ws2812_set_buffer_rgb(BLEU_24BITS, 0);
}
// Init SD Card for log
FATFS fs;
char drive_path[3] = "0:";
drive_path[0] += DEV_SDIO_MIN;
FRESULT fr;
do{
fr = f_mount(&fs, drive_path, 1);
if(FR_OK != fr){
printf("f_mount error: %s (%d)\n", FRESULT_str(fr), fr);
printf(">f_mount:0\n");
sleep_ms(50);
}else{
printf(">f_mount:1\n");
f_unmount(drive_path);
sleep_ms(50);
}
}while(1);
}
void core1_functions(){
while(1){
ws2812_gestion();
ws2812_affiche_buffer();
sleep_ms(2);
}
}
/*------------- MAIN -------------*/ /*------------- MAIN -------------*/
int main(void) { int main(void) {
gpio_set_function(12, UART_FUNCSEL_NUM(uart0, 12));
gpio_set_function(13, UART_FUNCSEL_NUM(uart0, 13));
printf("TinyUSB Host CDC MSC HID - Logs\r\n");
multicore_launch_core1(core1_functions);
board_init(); board_init();
ws2812_init();
printf("TinyUSB Host CDC MSC HID Example - test comparatif\r\n"); ws2812_set_buffer_rgb(2,2,2,0);
ws2812_set_buffer_rgb(2,2,2,3);
// Init detection carte SD
gpio_init(1);
gpio_set_dir(1, GPIO_IN);
gpio_pull_up(1);
float f;
absolute_time_t current_time, start_time;
start_time = get_absolute_time() / 1000.;
uint32_t couleur[13];
couleur[0]=0x000800;
couleur[1]=0x040800;
couleur[2]=0x080800;
couleur[3]=0x080400;
couleur[4]=0x080000;
couleur[5]=0x080004;
couleur[6]=0x080008;
couleur[7]=0x040008;
couleur[8]=0x000008;
couleur[9]=0x000408;
couleur[10]=0x000808;
couleur[11]=0x000804;
couleur[12]=0x000800;
uint8_t index_couleur=0;
ws2812_set_mode(LED_ID_SD_CARD, LED_CLI_RAPIDE, 0x000004);
ws2812_set_mode(LED_ID_USB, LED_CLI_NORMAL, 0x000004);
ws2812_set_mode(LED_ID_ASSERV, LED_CLI_PANIQUE_1, 0x000004);
ws2812_set_mode(LED_ID_DETECTION, LED_PULSE_RAPIDE, 0x000004);
while(1){
f = get_absolute_time() / 1000. - start_time;
f = f / 1000.;
if(f > 1){
f=1;
start_time = get_absolute_time() / 1000.;
f = 0;
index_couleur++;
if(index_couleur > 11){
index_couleur = 0;
}
}
//ws2812_set_buffer(ws2812_mix_color(couleur[index_couleur], couleur[index_couleur+1],f), 4);
ws2812_set_mode(LED_ID_SD_CARD, LED_CLI_RAPIDE, 0x000004);
ws2812_set_mode(LED_ID_USB, LED_CLI_NORMAL, 0x000004);
ws2812_set_mode(LED_ID_ASSERV, LED_CLI_PANIQUE_1, 0x000004);
ws2812_set_mode(LED_ID_DETECTION, LED_PULSE_RAPIDE, 0x000004);
ws2812_set_mode(LED_ID_DIVERS, LED_STABLE, 0x000004);
sleep_ms(3000);
ws2812_set_mode(LED_ID_SD_CARD, LED_CLI_RAPIDE, 0x000404);
ws2812_set_mode(LED_ID_USB, LED_CLI_NORMAL, 0x000404);
ws2812_set_mode(LED_ID_ASSERV, LED_CLI_LENT, 0x000404);
ws2812_set_mode(LED_ID_DETECTION, LED_CLI_PANIQUE_1, 0x000404);
ws2812_set_mode(LED_ID_DIVERS, LED_CLI_PANIQUE_2, 0x000404);
sleep_ms(3000);
ws2812_set_mode(LED_ID_SD_CARD, LED_CLI_PANIQUE_3, 0x040000);
ws2812_set_mode(LED_ID_USB, LED_PULSE_RAPIDE, 0x040000);
ws2812_set_mode(LED_ID_ASSERV, LED_PULSE_NORMAL, 0x040000);
ws2812_set_mode(LED_ID_DETECTION, LED_PULSE_LENT, 0x040000);
ws2812_set_mode(LED_ID_DIVERS, LED_STABLE, 0x040000);
sleep_ms(3000);
sleep_ms(1);
}
// init host stack on configured roothub port // init host stack on configured roothub port
// à mettre avant tuh_init // à mettre avant tuh_init
log_init(); com_init();
tuh_init(BOARD_TUH_RHPORT); tuh_init(BOARD_TUH_RHPORT);
if (board_init_after_tusb) { if (board_init_after_tusb) {
@ -144,7 +264,9 @@ int main(void) {
return -1; return -1;
} }
log_init(drive_path);
//multicore_launch_core1(routine_log_sd);
const char buffer[]= "Ceci est le test de Poivron Robotique\n"; const char buffer[]= "Ceci est le test de Poivron Robotique\n";

View File

@ -33,13 +33,7 @@ void put_message(struct message_t message){
/// @return 0 si tout s'est bien passé, 1 sinon /// @return 0 si tout s'est bien passé, 1 sinon
char message_to_string(struct message_t message, char * chaine_texte){ char message_to_string(struct message_t message, char * chaine_texte){
if(message.type == 'r' || message.type == 'w' || message.type == 'd'){ if(message.type == 'r' || message.type == 'w' || message.type == 'd'){
if(message.type == 'd' || message.type == 'w' ){ sprintf(chaine_texte, "%c: id_carte: %d, registre: %d, taille: %d", message.type, message.id_carte, message.adresse_registre, message.taille_donnees);
sprintf(chaine_texte, "%c: registre: %d, id_carte: %d, taille: %d", message.type, message.id_carte, message.taille_donnees);
}else if(message.type == 'r'){
sprintf(chaine_texte, "%c: registre: %d, taille: %d", message.type, message.adresse_registre, message.taille_donnees);
}else{
return 1;
}
if(message.type == 'r' || message.type == 'w' ){ if(message.type == 'r' || message.type == 'w' ){
char value[5]; char value[5];
@ -53,6 +47,7 @@ char message_to_string(struct message_t message, char * chaine_texte){
strcat(chaine_texte, "\n"); strcat(chaine_texte, "\n");
return 0; return 0;
} }
if(message.type == '>'){ if(message.type == '>'){
chaine_texte[0] = '>'; chaine_texte[0] = '>';
chaine_texte[1] = '\0'; chaine_texte[1] = '\0';
@ -64,73 +59,48 @@ char message_to_string(struct message_t message, char * chaine_texte){
} }
/// @brief remplit la mémoire message_binaire pour les données du message en usb
/// @param message
/// @param message_binaire
/// @return nombre d'octet à envoyer
uint16_t message_prepare_for_usb(struct message_t message, uint8_t * message_binaire){
switch (message.type)
{
case 'r':
message_binaire[0] = message.type;
message_binaire[1] = message.id_carte;
message_binaire[2] = message.adresse_registre;
message_binaire[3] = message.taille_donnees;
for(int i=0; i < message.taille_donnees; i++){
message_binaire[4+i] = message.donnees[i];
}
message_binaire[4+message.taille_donnees] = 0;
struct message_t messagerie_read_message(const char * chaine, unsigned int * position_chaine){ return (4 + message.taille_donnees + 1);
struct message_t message; break;
unsigned int position_sous_chaine;
message.type = 0;
switch(chaine[*position_chaine]){ case 'd':
case '>': message_binaire[0] = message.type;
// copier les données tant qu'on ne trouve pas un retour à la ligne ou de fin de chaine message_binaire[1] = message.id_carte;
position_sous_chaine = 0; message_binaire[2] = message.adresse_registre;
message.type = '>'; message_binaire[3] = message.taille_donnees;
while(*position_chaine + position_sous_chaine < 1024 && position_sous_chaine < 254){ message_binaire[4] = 0;
message.donnees[position_sous_chaine] = chaine[*position_chaine + position_sous_chaine]; return 5;
if(message.donnees[position_sous_chaine] == '\n' || message.donnees[position_sous_chaine] == '\0'){
break;
}
position_sous_chaine++;
}
if(message.donnees[position_sous_chaine-1] != '\0'){
message.donnees[position_sous_chaine] == '\0';
}
*position_chaine = *position_chaine + position_sous_chaine;
break;
case 'd': case 'w':
if(*position_chaine + 4 < 1024){ message_binaire[0] = message.type;
if(chaine[*position_chaine + 4] == '\0'){ message_binaire[1] = message.id_carte;
message.type = chaine[*position_chaine]; message_binaire[2] = message.adresse_registre;
message.id_carte = chaine[*position_chaine + 1]; message_binaire[3] = message.taille_donnees;
message.adresse_registre = chaine[*position_chaine + 2]; for(int i=0; i < message.taille_donnees; i++){
message.taille_donnees = chaine[*position_chaine + 3]; message_binaire[4+i] = message.donnees[i];
} }
message_binaire[4+message.taille_donnees] = 0;
} return (4 + message.taille_donnees);
default:
break;
}
}
case 'r':
if(*position_chaine + 2 < 1024){
// Read size
message.taille_donnees = chaine[*position_chaine + 2];
position_sous_chaine = 2 + message.taille_donnees + 1;
if(*position_chaine + position_sous_chaine < 1024){
if(chaine[*position_chaine + position_sous_chaine] == '\0'){
message.type = chaine[*position_chaine];
message.adresse_registre = chaine[*position_chaine + 1];
message.taille_donnees = chaine[*position_chaine + 2]; // déjà fait plus haut
memcpy(message.donnees, &(chaine[*position_chaine + 3]), message.taille_donnees);
}
}
}
break;
case 'w':
if(*position_chaine + 3 < 1024){
// Read size
message.taille_donnees = chaine[*position_chaine + 3];
position_sous_chaine = 3 + message.taille_donnees + 1;
if(*position_chaine + position_sous_chaine < 1024){
if(chaine[*position_chaine + position_sous_chaine] == '\0'){
message.type = chaine[*position_chaine];
message.id_carte = chaine[*position_chaine + 1];
message.adresse_registre = chaine[*position_chaine + 2];
message.taille_donnees = chaine[*position_chaine + 3]; // déjà fait plus haut
memcpy(message.donnees, &(chaine[*position_chaine + 4]), message.taille_donnees);
}
}
}
default:
}
}

View File

@ -11,6 +11,7 @@ struct message_t{
struct message_t messagerie_read_message(const char * chaine, unsigned int * position_chaine); struct message_t messagerie_read_message(const char * chaine, unsigned int * position_chaine);
char message_to_string(struct message_t message, char * chaine_texte); char message_to_string(struct message_t message, char * chaine_texte);
uint16_t message_prepare_for_usb(struct message_t message, uint8_t * message_binaire);
bool message_disponible(void); bool message_disponible(void);
void put_message(struct message_t message); void put_message(struct message_t message);

295
ws2812.c Normal file
View File

@ -0,0 +1,295 @@
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "ws2812.h"
#include "ws2812.pio.h"
#include <stdio.h>
#define WS2812_PIN 15
#define IS_RGBW false
#define NB_WS2812 5
uint32_t couleur[13];
uint32_t buffer_couleur[12];
struct ws2812_type_gestion_t
{
enum led_type_gestion_t led_type_gestion;
uint32_t couleur;
} ws2812_type_gestion[NB_WS2812];
void ws2812_set_buffer(uint32_t couleur, uint8_t index_led);
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b);
void ws2812_init(){
couleur[0]=0x000200;
couleur[1]=0x010200;
couleur[2]=0x020200;
couleur[3]=0x020100;
couleur[4]=0x020000;
couleur[5]=0x020001;
couleur[6]=0x020002;
couleur[7]=0x010002;
couleur[8]=0x000002;
couleur[9]=0x000102;
couleur[10]=0x000202;
couleur[11]=0x000201;
couleur[12]=0x000200;
/*couleur[0]=0x002000;
couleur[1]=0x102000;
couleur[2]=0x202000;
couleur[3]=0x201000;
couleur[4]=0x200000;
couleur[5]=0x200010;
couleur[6]=0x200020;
couleur[7]=0x100020;
couleur[8]=0x000020;
couleur[9]=0x001020;
couleur[10]=0x002020;
couleur[11]=0x002010;
couleur[12]=0x002000;*/
/*couleur[0]=0x00FF00;
couleur[1]=0x80FF00;
couleur[2]=0xFFFF00;
couleur[3]=0xFF8000;
couleur[4]=0xFF0000;
couleur[5]=0xFF0080;
couleur[6]=0xFF00FF;
couleur[7]=0x8000FF;
couleur[8]=0x0000FF;
couleur[9]=0x0080FF;
couleur[10]=0x00FFFF;
couleur[11]=0x00FF80;
couleur[12]=0x00FF00;*/
// initialisation du PIO
PIO pio = pio0;
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_program);
ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);
// Tout rouge !
for(uint32_t i = 0; i<12; i++){
ws2812_set_buffer_rgb(ORANGE_24BITS, i);
ws2812_type_gestion[NB_WS2812].couleur = urgb_u32(ORANGE_24BITS);
ws2812_type_gestion[NB_WS2812].led_type_gestion = PAS_DE_GESTION;
}
ws2812_affiche_buffer();
}
void ws2812_arc_en_ciel(){
while(1){
uint32_t i;
sleep_ms(50);
// Affichage
for(i = 0; i<12; i++){
ws2812_set_buffer(couleur[i], i);
}
ws2812_affiche_buffer();
// Décalage des couleurs
for(i = 0; i<12; i++){
couleur[i] = couleur[i+1];
}
couleur[12]=couleur[0];
}
}
static inline void put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
}
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
return
((uint32_t) (r) << 8) |
((uint32_t) (g) << 16) |
(uint32_t) (b);
}
void ws2812_affiche_buffer(){
for(uint32_t i = 0; i<12; i++){
put_pixel(buffer_couleur[i]);
}
}
void ws2812_set_buffer_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led){
ws2812_set_buffer(urgb_u32(rouge, vert,bleu), index_led);
}
void ws2812_set_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led){
ws2812_set_buffer(urgb_u32(rouge, vert,bleu), index_led);
ws2812_affiche_buffer();
sleep_us(500);
}
//Bit 7 6 5 4 3 2 1 0
//Data R R R G G G B B
void ws2812_set_buffer_8bits(uint8_t couleur, uint8_t index_led){
ws2812_set_buffer(urgb_u32(couleur >> 5, (couleur >> 2) & 0x07, couleur & 0x03), index_led);
}
/// @brief Rempli le buffer à envoyer au LED, necessite d'appeler la fonction ws2812_affiche_buffer() ensuite
/// @param couleur : couleur en RVB
/// @param index_led : index entre 0 et 11
void ws2812_set_buffer(uint32_t couleur, uint8_t index_led){
if(index_led <12){
buffer_couleur[index_led] = couleur;
}
}
void ws2812_set_led(uint8_t led, uint32_t couleur){
ws2812_set_buffer(couleur, led);
ws2812_affiche_buffer();
}
uint32_t ws2812_mix_color(uint32_t couleur1, uint32_t couleur2, float facteur){
uint8_t r, g, b;
b = (couleur1 & 0xFF) * (1 - facteur) + (couleur2 & 0xFF) * facteur;
r = ((couleur1 & 0xFF00)>> 8) * (1 - facteur) + ((couleur2 & 0xFF00)>> 8) * facteur;
g = ((couleur1 & 0xFF0000)>> 16) * (1 - facteur) + ((couleur2 & 0xFF0000)>> 16) * facteur;
return urgb_u32(r, g, b);
}
void ws2812_set_mode(uint8_t led_id, enum led_type_gestion_t led_type_gestion, uint32_t couleur){
if(led_id < NB_WS2812){
ws2812_type_gestion[led_id].couleur = couleur;
ws2812_type_gestion[led_id].led_type_gestion = led_type_gestion;
}
}
void ws2812_gestion(void){
uint32_t temps_ref;
uint8_t nb_cli;
uint8_t phase_led;
float f;
for(int led_id = 0; led_id < NB_WS2812; led_id++){
switch (ws2812_type_gestion[led_id].led_type_gestion)
{
case PAS_DE_GESTION:
break;
case LED_STABLE:
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
break;
case LED_CLI_RAPIDE:
if((get_absolute_time() / 50000) % 2){
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
}else{
ws2812_set_buffer(0x000000, led_id);
}
break;
case LED_CLI_NORMAL:
if((get_absolute_time() / 200000) % 2){
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
}else{
ws2812_set_buffer(0x000000, led_id);
}
break;
case LED_CLI_LENT:
if((get_absolute_time() / 1000000) % 2){
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
}else{
ws2812_set_buffer(0x000000, led_id);
}
break;
case LED_CLI_PANIQUE_1:
temps_ref =100000;
nb_cli = 1;
phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ;
printf(">l:%d\n", phase_led);
if(phase_led >= nb_cli*2){
ws2812_set_buffer(0x000000, led_id);
}else{
printf(">l1:%d\n",phase_led );
if(phase_led % 2){
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
}else{
ws2812_set_buffer(0x000000, led_id);
}
}
break;
case LED_CLI_PANIQUE_2:
temps_ref =100000;
nb_cli = 2;
phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ;
if(phase_led >= nb_cli*2){
ws2812_set_buffer(0x000000, led_id);
}else{
if(phase_led % 2){
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
}else{
ws2812_set_buffer(0x000000, led_id);
}
}
break;
case LED_CLI_PANIQUE_3:
temps_ref =100000;
nb_cli = 3;
phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ;
if(phase_led >= nb_cli*2){
ws2812_set_buffer(0x000000, led_id);
}else{
if(phase_led % 2){
ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id);
}else{
ws2812_set_buffer(0x000000, led_id);
}
}
break;
case LED_PULSE_LENT:
temps_ref = 3000000;
if((get_absolute_time() / temps_ref) % 2){
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id);
}else{
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id);
}
break;
case LED_PULSE_NORMAL:
temps_ref = 1000000;
if((get_absolute_time() / temps_ref) % 2){
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id);
}else{
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id);
}
break;
case LED_PULSE_RAPIDE:
temps_ref = 200000;
if((get_absolute_time() / temps_ref) % 2){
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id);
}else{
f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref;
ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id);
}
break;
default:
break;
}
}
}

39
ws2812.h Normal file
View File

@ -0,0 +1,39 @@
#include "pico/stdlib.h"
enum led_type_gestion_t{
PAS_DE_GESTION,
LED_STABLE,
LED_CLI_RAPIDE,
LED_CLI_NORMAL,
LED_CLI_LENT,
LED_CLI_PANIQUE_1,
LED_CLI_PANIQUE_2,
LED_CLI_PANIQUE_3,
LED_PULSE_RAPIDE,
LED_PULSE_NORMAL,
LED_PULSE_LENT
};
void ws2812_init(void);
void ws2812_affiche_buffer(void);
void ws2812_set_buffer_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led);
void ws2812_set_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led);
void ws2812_set_buffer_8bits(uint8_t couleur, uint8_t index_led);
void ws2812_set_buffer(uint32_t couleur, uint8_t index_led);
void ws2812_arc_en_ciel(void);
void ws2812_set_led(uint8_t led, uint32_t couleur);
void ws2812_set_mode(uint8_t led_id, enum led_type_gestion_t led_type_gestion, uint32_t couleur);
void ws2812_gestion(void);
uint32_t ws2812_mix_color(uint32_t couleur1, uint32_t couleur2, float facteur);
#define LED_ID_SD_CARD 0
#define LED_ID_USB 1
#define LED_ID_ASSERV 2
#define LED_ID_DETECTION 3
#define LED_ID_DIVERS 4
#define OFF_24BITS 0, 0, 0
#define ORANGE_24BITS 4, 1, 0
#define BLEU_24BITS 0, 0, 4
#define VERT_24BITS 0, 4, 1

85
ws2812.pio Normal file
View File

@ -0,0 +1,85 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;
.program ws2812
.side_set 1
.define public T1 2
.define public T2 5
.define public T3 3
.lang_opt python sideset_init = pico.PIO.OUT_HIGH
.lang_opt python out_init = pico.PIO.OUT_HIGH
.lang_opt python out_shiftdir = 1
.wrap_target
bitloop:
out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls
jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse
do_one:
jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse
do_zero:
nop side 0 [T2 - 1] ; Or drive low, for a short pulse
.wrap
% c-sdk {
#include "hardware/clocks.h"
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = ws2812_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}
.program ws2812_parallel
.define public T1 2
.define public T2 5
.define public T3 3
.wrap_target
out x, 32
mov pins, !null [T1-1]
mov pins, x [T2-1]
mov pins, null [T3-2]
.wrap
% c-sdk {
#include "hardware/clocks.h"
static inline void ws2812_parallel_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
for(uint i=pin_base; i<pin_base+pin_count; i++) {
pio_gpio_init(pio, i);
}
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true);
pio_sm_config c = ws2812_parallel_program_get_default_config(offset);
sm_config_set_out_shift(&c, true, true, 32);
sm_config_set_out_pins(&c, pin_base, pin_count);
sm_config_set_set_pins(&c, pin_base, pin_count);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_parallel_T1 + ws2812_parallel_T2 + ws2812_parallel_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}