Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b3453c2f53 | |||
| 7e76fbd088 | |||
| c558152993 | |||
| 3439300b0d | |||
| c724748232 | |||
| e20a8a0a7e | |||
| 11c278e368 | |||
| 6e8c96e7cf | |||
| 94d7c5f8a2 | |||
| 83fa26be6d | |||
| a069a4e8d0 | |||
| 0b492e91af | |||
| 148d53fa86 | |||
| dcc3889845 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
build/
|
build/
|
||||||
|
debug/
|
||||||
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@ -31,4 +31,4 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
}
|
}
|
||||||
|
|||||||
24
.vscode/launch.json
vendored
Normal file
24
.vscode/launch.json
vendored
Normal 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"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
|
"string.h": "c",
|
||||||
|
"messagerie_applicative.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
20
.vscode/tasks.json
vendored
20
.vscode/tasks.json
vendored
@ -1,15 +1,5 @@
|
|||||||
{
|
{
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
|
||||||
"type": "shell",
|
|
||||||
"command": "cd build; cmake ../; make",
|
|
||||||
"label": "CMake in build/",
|
|
||||||
"problemMatcher": [],
|
|
||||||
"group": {
|
|
||||||
"kind": "build",
|
|
||||||
"isDefault": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "cd build; cmake ../; make Flash",
|
"command": "cd build; cmake ../; make Flash",
|
||||||
@ -19,6 +9,16 @@
|
|||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cd debug; cmake -DCMAKE_BUILD_TYPE=Debug ../; make Flash",
|
||||||
|
"label": "Flash Debug",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": "2.0.0"
|
"version": "2.0.0"
|
||||||
|
|||||||
@ -11,13 +11,16 @@ set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})
|
|||||||
pico_sdk_init()
|
pico_sdk_init()
|
||||||
|
|
||||||
add_executable(Modele_RPiPico
|
add_executable(Modele_RPiPico
|
||||||
|
communication.c
|
||||||
main.c
|
main.c
|
||||||
|
messagerie.c
|
||||||
|
messagerie_applicative.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Modele_RPiPico
|
target_link_libraries(Modele_RPiPico
|
||||||
hardware_uart
|
hardware_uart
|
||||||
pico_stdlib
|
pico_stdlib
|
||||||
pico_multicore
|
pico_multicore
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_enable_stdio_usb(Modele_RPiPico 1)
|
pico_enable_stdio_usb(Modele_RPiPico 1)
|
||||||
|
|||||||
125
Readme.md
125
Readme.md
@ -1,4 +1,127 @@
|
|||||||
Projet modèle pour le Rpi Pico (RP2040)
|
Projet modèle pour le Rpi Pico (RP2040)
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
Ce projet est un example pour le RPI Pico, tentant d'être le plus prêt à l'emploi possible.
|
Code pour travailler sur la communication USB, côté device.
|
||||||
|
|
||||||
|
Nous commençons à stocker les données reçues dans des structures pour simplifier l'interprétation des données.
|
||||||
|
|
||||||
|
Méthode de test
|
||||||
|
---------------
|
||||||
|
* Ouvrir un terminal pour lire les données reçues en désactivant l'écho
|
||||||
|
|
||||||
|
`stty -F /dev/ttyACM1 -echo`
|
||||||
|
|
||||||
|
`cat /dev/ttyACM0`
|
||||||
|
* Ouvrir un terminal pour envoyer les données. Contrôle de la LED avec :
|
||||||
|
|
||||||
|
`echo -e "\xFF\xFF\x06rD\x00\x01\x06\x00" > /dev/ttyACM1`
|
||||||
|
|
||||||
|
ou
|
||||||
|
|
||||||
|
`echo -e "\xFF\xFF\x06rD\x00\x01\x36\x00" > /dev/ttyACM1`
|
||||||
|
|
||||||
|
* Tester la réception de la position
|
||||||
|
|
||||||
|
`echo -e "\xFF\xFF\x11rP\x00\x0C\x01\x01\x01\x01\x05\x05\x05\x05\x09\x09\x09\x09\x00" > /dev/ttyACM1`
|
||||||
|
|
||||||
|
Difficultés rencontrées
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
En testant avec Linux, le terminal peut manger certains caractères lorsqu'il les reçoit (0x11, 0x12 et 0x13).
|
||||||
|
|
||||||
|
|
||||||
|
Annexe
|
||||||
|
======
|
||||||
|
|
||||||
|
Table des registres :
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
| Adresse | R/W | Type | Donnée |
|
||||||
|
| ------- | --- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| 0x00 | RW | flottant 32 bits | Position X en mm |
|
||||||
|
| 0x01 | RW | flottant 32 bits | Position X en mm |
|
||||||
|
| 0x02 | RW | flottant 32 bits | Position X en mm |
|
||||||
|
| 0x03 | RW | flottant 32 bits | Position X en mm |
|
||||||
|
| 0x04 | RW | flottant 32 bits | Position Y en mm |
|
||||||
|
| 0x05 | RW | flottant 32 bits | Position Y en mm |
|
||||||
|
| 0x06 | RW | flottant 32 bits | Position Y en mm |
|
||||||
|
| 0x07 | RW | flottant 32 bits | Position Y en mm |
|
||||||
|
| 0x08 | RW | flottant 32 bits | Orientation en radian |
|
||||||
|
| 0x09 | RW | flottant 32 bits | Orientation en radian |
|
||||||
|
| 0x0A | RW | flottant 32 bits | Orientation en radian |
|
||||||
|
| 0x0B | RW | flottant 32 bits | Orientation en radian |
|
||||||
|
| 0x0C | R | Boolean | Mouvement en cours : 1<br>Mouvement terminé : 0 |
|
||||||
|
| 0x0D | RW | uint8_t | Mode<br>0 : arrêt des moteurs<br>1 : pilotage des moteurs PWM<br>2 : pilotage en vitesse des roues<br>3 : pilotage avec la loi de commande<br>4 : Trajectoire |
|
||||||
|
| 0x0E | RW | int_16 | Commande PWM moteur gauche |
|
||||||
|
| 0x0F | RW | int_16 | Commande PWM moteur gauche |
|
||||||
|
| 0x10 | RW | int_16 | Commande PWM moteur droit |
|
||||||
|
| 0x11 | RW | int_16 | Commande PWM moteur droit |
|
||||||
|
| 0x12 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x13 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x14 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x15 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x16 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x17 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x18 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x19 | RW | Flottant 32 bits | Consigne vitesse gauche en mm/s |
|
||||||
|
| 0x1A | RW | Flottant 32 bits | Consigne d’avance du robot |
|
||||||
|
| 0x1B | RW | Flottant 32 bits | Consigne d’avance du robot |
|
||||||
|
| 0x1C | RW | Flottant 32 bits | Consigne d’avance du robot |
|
||||||
|
| 0x1D | RW | Flottant 32 bits | Consigne d’avance du robot |
|
||||||
|
| 0x1E | RW | Flottant 32 bits | Consigne de rotation du robot |
|
||||||
|
| 0x1F | RW | Flottant 32 bits | Consigne de rotation du robot |
|
||||||
|
| 0x20 | RW | Flottant 32 bits | Consigne de rotation du robot |
|
||||||
|
| 0x21 | RW | Flottant 32 bits | Consigne de rotation du robot |
|
||||||
|
| 0x22 | RW | Enum 8 bits | Trajectoire, type :<br>0 : Droite<br>1 : Circulaire<br>2 : Bézier<br>3 : Composée<br>4 : Rotation |
|
||||||
|
| 0x23 | RW | Flottant 32 bits | Point 1, X |
|
||||||
|
| 0x24 | RW | Flottant 32 bits | Point 1, X |
|
||||||
|
| 0x25 | RW | Flottant 32 bits | Point 1, X |
|
||||||
|
| 0x26 | RW | Flottant 32 bits | Point 1, X |
|
||||||
|
| 0x27 | RW | Flottant 32 bits | Point 1, Y |
|
||||||
|
| 0x28 | RW | Flottant 32 bits | Point 1, Y |
|
||||||
|
| 0x29 | RW | Flottant 32 bits | Point 1, Y |
|
||||||
|
| 0x2A | RW | Flottant 32 bits | Point 1, Y |
|
||||||
|
| 0x2B | RW | Flottant 32 bits | Point 2, X |
|
||||||
|
| 0x2C | RW | Flottant 32 bits | Point 2, X |
|
||||||
|
| 0x2D | RW | Flottant 32 bits | Point 2, X |
|
||||||
|
| 0x2E | RW | Flottant 32 bits | Point 2, X |
|
||||||
|
| 0x2F | RW | Flottant 32 bits | Point 2, Y |
|
||||||
|
| 0x30 | RW | Flottant 32 bits | Point 2, Y |
|
||||||
|
| 0x31 | RW | Flottant 32 bits | Point 2, Y |
|
||||||
|
| 0x32 | RW | Flottant 32 bits | Point 2, Y |
|
||||||
|
| 0x33 | RW | Flottant 32 bits | Point 3, X |
|
||||||
|
| 0x34 | RW | Flottant 32 bits | Point 3, X |
|
||||||
|
| 0x35 | RW | Flottant 32 bits | Point 3, X |
|
||||||
|
| 0x36 | RW | Flottant 32 bits | Point 3, X |
|
||||||
|
| 0x37 | RW | Flottant 32 bits | Point 3, Y |
|
||||||
|
| 0x38 | RW | Flottant 32 bits | Point 3, Y |
|
||||||
|
| 0x39 | RW | Flottant 32 bits | Point 3, Y |
|
||||||
|
| 0x3A | RW | Flottant 32 bits | Point 3, Y |
|
||||||
|
| 0x3B | RW | Flottant 32 bits | Point 4, X |
|
||||||
|
| 0x3C | RW | Flottant 32 bits | Point 4, X |
|
||||||
|
| 0x3D | RW | Flottant 32 bits | Point 4, X |
|
||||||
|
| 0x3E | RW | Flottant 32 bits | Point 4, X |
|
||||||
|
| 0x3F | RW | Flottant 32 bits | Point 4, Y |
|
||||||
|
| 0x40 | RW | Flottant 32 bits | Point 4, Y |
|
||||||
|
| 0x41 | RW | Flottant 32 bits | Point 4, Y |
|
||||||
|
| 0x42 | RW | Flottant 32 bits | Point 4, Y |
|
||||||
|
| 0x43 | RW | Flottant 32 bits | orientation_debut_rad |
|
||||||
|
| 0x44 | RW | Flottant 32 bits | orientation_debut_rad |
|
||||||
|
| 0x45 | RW | Flottant 32 bits | orientation_debut_rad |
|
||||||
|
| 0x46 | RW | Flottant 32 bits | orientation_debut_rad |
|
||||||
|
| 0x47 | RW | Flottant 32 bits | orientation_fin_rad |
|
||||||
|
| 0x48 | RW | Flottant 32 bits | orientation_fin_rad |
|
||||||
|
| 0x49 | RW | Flottant 32 bits | orientation_fin_rad |
|
||||||
|
| 0x4A | RW | Flottant 32 bits | orientation_fin_rad |
|
||||||
|
| 0x4B | RW | Flottant 32 bits | rayon mm |
|
||||||
|
| 0x4C | RW | Flottant 32 bits | rayon mm |
|
||||||
|
| 0x4D | RW | Flottant 32 bits | rayon mm |
|
||||||
|
| 0x4E | RW | Flottant 32 bits | rayon mm |
|
||||||
|
| 0x4F | RW | Flottant 32 bits | Angle début rad |
|
||||||
|
| 0x50 | RW | Flottant 32 bits | Angle début rad |
|
||||||
|
| 0x51 | RW | Flottant 32 bits | Angle début rad |
|
||||||
|
| 0x52 | RW | Flottant 32 bits | Angle début rad |
|
||||||
|
| 0x53 | RW | Flottant 32 bits | Angle fin rad |
|
||||||
|
| 0x54 | RW | Flottant 32 bits | Angle fin rad |
|
||||||
|
| 0x55 | RW | Flottant 32 bits | Angle fin rad |
|
||||||
|
| 0x56 | RW | Flottant 32 bits | Angle fin rad |
|
||||||
150
communication.c
Normal file
150
communication.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#include "pico/error.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "communication.h"
|
||||||
|
#include "messagerie.h"
|
||||||
|
|
||||||
|
#define TAMPON_TAILLE 1020
|
||||||
|
|
||||||
|
struct com_reception_buffer_t{
|
||||||
|
char tampon[TAMPON_TAILLE]; // Tampon tournant - 1er niveau de tampon
|
||||||
|
unsigned int index_tampon_ecriture, index_tampon_lecture;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct com_reception_buffer_t com_reception_buffer;
|
||||||
|
|
||||||
|
|
||||||
|
void communication_init(){
|
||||||
|
com_reception_buffer.index_tampon_ecriture=0;
|
||||||
|
com_reception_buffer.index_tampon_lecture=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Vérifie si des caractères ont été reçu par la liaison série
|
||||||
|
/// et analyse si un message valide a été reçu.
|
||||||
|
void communication_reception_message(){
|
||||||
|
int input_char;
|
||||||
|
int chaîne_octets_reçus[TAMPON_TAILLE];
|
||||||
|
unsigned int index_chaine_recue;
|
||||||
|
unsigned int index_tampon;
|
||||||
|
struct message_t message;
|
||||||
|
// Si un caractère est reçu, ajout du caractère au tampon tournant
|
||||||
|
|
||||||
|
/// TODO: Tester le code suivant à la place de while get_char();
|
||||||
|
/*
|
||||||
|
char nb_recu=0;
|
||||||
|
if(tud_cdc_available()){
|
||||||
|
char tampon_usb[128];
|
||||||
|
nb_recu = tud_cdc_read(tampon_usb, 128);
|
||||||
|
// copie dans le tampon tournant
|
||||||
|
for(int i=0; i<nb_recu; i++){
|
||||||
|
input_char = tampon_usb[i];
|
||||||
|
com_reception_buffer.index_tampon_ecriture++;
|
||||||
|
if(com_reception_buffer.index_tampon_ecriture >= TAMPON_TAILLE){
|
||||||
|
com_reception_buffer.index_tampon_ecriture = 0;
|
||||||
|
}
|
||||||
|
com_reception_buffer.tampon[com_reception_buffer.index_tampon_ecriture] = input_char;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
input_char = stdio_getchar_timeout_us(0);
|
||||||
|
while(input_char != PICO_ERROR_TIMEOUT){
|
||||||
|
com_reception_buffer.index_tampon_ecriture++;
|
||||||
|
if(com_reception_buffer.index_tampon_ecriture >= TAMPON_TAILLE){
|
||||||
|
com_reception_buffer.index_tampon_ecriture = 0;
|
||||||
|
}
|
||||||
|
com_reception_buffer.tampon[com_reception_buffer.index_tampon_ecriture] = input_char;
|
||||||
|
|
||||||
|
// Caractère suivant ?
|
||||||
|
input_char = stdio_getchar_timeout_us(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copie du tampon tournant dans une chaine
|
||||||
|
// Parce que c'est plus simple à traiter
|
||||||
|
index_chaine_recue = 0;
|
||||||
|
index_tampon = com_reception_buffer.index_tampon_lecture;
|
||||||
|
if(index_tampon != com_reception_buffer.index_tampon_ecriture){
|
||||||
|
while(index_tampon != com_reception_buffer.index_tampon_ecriture){
|
||||||
|
chaîne_octets_reçus[index_chaine_recue] = com_reception_buffer.tampon[index_tampon];
|
||||||
|
index_chaine_recue++;
|
||||||
|
increment_index(&index_tampon);
|
||||||
|
}
|
||||||
|
chaîne_octets_reçus[index_chaine_recue] = com_reception_buffer.tampon[index_tampon];
|
||||||
|
index_chaine_recue++;
|
||||||
|
increment_index(&index_tampon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traitement
|
||||||
|
// Si on trouve le début du message
|
||||||
|
// Si on trouve la taille du message
|
||||||
|
// Si le caractère de fin est bien à la fin du message
|
||||||
|
int fin_message = 0;
|
||||||
|
for(int i=0; i<index_chaine_recue; i++){
|
||||||
|
int index_fin_message = 0;
|
||||||
|
// Com v2
|
||||||
|
// OxFF OxFF <taille> ... ... <fin (0x00)>
|
||||||
|
if(i + 2 < index_chaine_recue){
|
||||||
|
// Test début message
|
||||||
|
if(chaîne_octets_reçus[i] == 0xFF && chaîne_octets_reçus[i+1] == 0xFF){
|
||||||
|
//printf("Debut message: 0xFF 0xFF\n");
|
||||||
|
// Taille du message (sans l'entête)
|
||||||
|
uint8_t offset = chaîne_octets_reçus[i+2];
|
||||||
|
if(i + 2 + offset < index_chaine_recue){
|
||||||
|
// printf("Message totalement reçu, taille %d\n", offset);
|
||||||
|
// Test fin message
|
||||||
|
if(chaîne_octets_reçus[i + 2 + offset] == 0x00){
|
||||||
|
// printf("Fin message OK\n");
|
||||||
|
// Lecture du message
|
||||||
|
message.type = 'b'; // Message binaire (par opposition à un message Texte)
|
||||||
|
message.taille_donnees = offset - 1;
|
||||||
|
for(int index_donnees = 0; index_donnees < message.taille_donnees; index_donnees++){
|
||||||
|
message.donnees[index_donnees] = chaîne_octets_reçus[index_donnees + i + 3];
|
||||||
|
}
|
||||||
|
fin_message = i + 2 + offset;
|
||||||
|
messagerie_put_message(message);
|
||||||
|
}else{
|
||||||
|
// printf("Fin message NOK, attendu 0x00, recu %x\n", chaîne_octets_reçus[i + 2 + offset]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(chaîne_octets_reçus[i] == '>'){
|
||||||
|
message.type = chaîne_octets_reçus[i];
|
||||||
|
message.taille_donnees=0;
|
||||||
|
while(message.taille_donnees + i < index_chaine_recue){
|
||||||
|
message.donnees[message.taille_donnees] = chaîne_octets_reçus[i+message.taille_donnees];
|
||||||
|
if(message.donnees[message.taille_donnees] == '\n'){
|
||||||
|
i = i + message.taille_donnees;
|
||||||
|
message.taille_donnees++;
|
||||||
|
message.donnees[message.taille_donnees] = '\0';
|
||||||
|
messagerie_put_message (message);
|
||||||
|
fin_message = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
message.taille_donnees++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mettre à jour l'index de lecture du tampon tournant
|
||||||
|
augmente_index(&(com_reception_buffer.index_tampon_lecture), fin_message);
|
||||||
|
|
||||||
|
}
|
||||||
3
communication.h
Normal file
3
communication.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
void communication_reception_message(void);
|
||||||
|
void communication_init(void);
|
||||||
251
main.c
251
main.c
@ -5,50 +5,245 @@
|
|||||||
*/
|
*/
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pico/stdio.h>
|
||||||
|
|
||||||
|
#include "communication.h"
|
||||||
|
#include "messagerie.h"
|
||||||
|
#include "messagerie_applicative.h"
|
||||||
|
|
||||||
|
|
||||||
|
void stdio_usb_out_chars(const char *buf, int length);
|
||||||
|
|
||||||
|
#define NB_MORCEAUX 100
|
||||||
|
|
||||||
absolute_time_t envoie_nb_char(int nb_char);
|
absolute_time_t envoie_nb_char(int nb_char);
|
||||||
|
char chaine_envoie[10000];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void envoie_donnees(char * donnees, uint16_t length){
|
||||||
|
for (int i=0; i<length; i++){
|
||||||
|
putchar(donnees[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Fonction pour envoyer une structure
|
||||||
|
/// @param donnees données à envoyer
|
||||||
|
/// @param size taille des données
|
||||||
|
void envoie_structure(const void * donnees, size_t size){
|
||||||
|
const unsigned char *byte;
|
||||||
|
// Entête du message : debut
|
||||||
|
putchar(0xFF);
|
||||||
|
putchar(0xFF);
|
||||||
|
putchar(size + 1);
|
||||||
|
// Entête du message : fin
|
||||||
|
// Données
|
||||||
|
for ( byte = donnees; size--; ++byte )
|
||||||
|
{
|
||||||
|
putchar(*byte);
|
||||||
|
//printf("%2X ", *byte);
|
||||||
|
}
|
||||||
|
// Caractère de fin
|
||||||
|
putchar(0x00);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
absolute_time_t measured_time_us;
|
absolute_time_t measured_time_us;
|
||||||
absolute_time_t temps_moyen, temps_max;
|
absolute_time_t temps_moyen, temps_max, temps_m[NB_MORCEAUX];
|
||||||
int nb_ech = 10;
|
absolute_time_t current_time_us, start_time_us;
|
||||||
stdio_init_all();
|
absolute_time_t temps_message_detection;
|
||||||
while(1){
|
struct message_t message;
|
||||||
temps_moyen = 0;
|
struct message_requete_t message_requete_detection;
|
||||||
temps_max = 0;
|
unsigned char message_binaire[100];
|
||||||
for(int nb_char = 1; nb_char < 1000; nb_char+= 1){
|
|
||||||
temps_moyen = 0;
|
message_requete_detection.commande = 'd';
|
||||||
temps_max = 0;
|
message_requete_detection.id_carte = 'D';
|
||||||
for(int ech=0; ech<nb_ech; ech ++){
|
message_requete_detection.adresse_registre = 0;
|
||||||
measured_time_us = envoie_nb_char(nb_char);
|
message_requete_detection.taille_donnees = 19;
|
||||||
if(measured_time_us > temps_max){
|
|
||||||
temps_max = measured_time_us;
|
|
||||||
}
|
message_binaire[0]='r';
|
||||||
temps_moyen += measured_time_us;
|
message_binaire[1]='A';
|
||||||
}
|
message_binaire[2]= 0;
|
||||||
temps_moyen = temps_moyen / nb_ech;
|
message_binaire[3]= 5;
|
||||||
printf(">temps:%d:%lld#us\n", nb_char, temps_moyen);
|
|
||||||
printf(">temps_max:%d:%lld#us\n", nb_char, temps_max);
|
message_binaire[4]= 'a';
|
||||||
sleep_ms(5);
|
message_binaire[5]= 'b';
|
||||||
|
message_binaire[6]= 'c';
|
||||||
|
message_binaire[7]= 'd';
|
||||||
|
message_binaire[8]= 'e';
|
||||||
|
|
||||||
|
message_binaire[9]= 0;
|
||||||
|
|
||||||
|
struct message_applicatif_t message_applicatif;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(int i=0; i<10000; i++){
|
||||||
|
/*j++;
|
||||||
|
if(j>25){
|
||||||
|
j=0;
|
||||||
|
}
|
||||||
|
chaine_envoie[i]= j + 'a';*/
|
||||||
|
chaine_envoie[i]= i%26 + 'a';
|
||||||
|
}
|
||||||
|
int nb_ech = 10;
|
||||||
|
int taille_morceau = 60;
|
||||||
|
int nb_message=0;
|
||||||
|
|
||||||
|
stdio_init_all();
|
||||||
|
sleep_ms(5000);
|
||||||
|
|
||||||
|
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||||
|
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN, 0);
|
||||||
|
|
||||||
|
temps_message_detection = get_absolute_time();
|
||||||
|
unsigned int temps_ms;
|
||||||
|
temps_ms = get_absolute_time() / 1000.;
|
||||||
|
|
||||||
|
communication_init();
|
||||||
|
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
/*
|
||||||
|
if(get_absolute_time() - temps_message_detection > MESSAGE_TIMEOUT_US){
|
||||||
|
start_time_us = get_absolute_time();
|
||||||
|
envoie_structure(&message_requete_detection, sizeof(message_requete_detection) );
|
||||||
|
temps_message_detection = get_absolute_time();
|
||||||
|
current_time_us = get_absolute_time();
|
||||||
|
//printf(">temps_emission:%lld\n", current_time_us - start_time_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_time_us = get_absolute_time();*/
|
||||||
|
communication_reception_message();
|
||||||
|
|
||||||
|
if(messagerie_message_disponible()){
|
||||||
|
uint8_t id_carte, registre;
|
||||||
|
while(messagerie_message_disponible()){
|
||||||
|
message = messagerie_get_message();
|
||||||
|
nb_message++;
|
||||||
|
|
||||||
|
if(message.type == 'b'){
|
||||||
|
switch(message.donnees[0]){
|
||||||
|
case 'r': // réception de données
|
||||||
|
// Reception de données
|
||||||
|
// données[0]: commande ('r' ici)
|
||||||
|
// données[1]: id de la carte
|
||||||
|
// données[2]: 1er registre
|
||||||
|
// données[3 à tailles_données -1]: valeurs
|
||||||
|
memcpy(&message_applicatif, message.donnees, message.taille_donnees);
|
||||||
|
printf("id_carte:%c %d\n", message_applicatif.id_carte, message_applicatif.id_carte);
|
||||||
|
|
||||||
|
|
||||||
|
if(message_applicatif.id_carte == 'P'){
|
||||||
|
|
||||||
|
mise_a_jour_position = false;
|
||||||
|
mise_a_jour_mode = false;
|
||||||
|
mise_a_jour_pwm = false;
|
||||||
|
mise_a_jour_vitesse_roues = false;
|
||||||
|
mise_a_jour_vitesse_robot = false;
|
||||||
|
mise_a_jour_trajectoire = false;
|
||||||
|
|
||||||
|
// Copie des données dans la mémoire d'échange
|
||||||
|
// Et actualisation des variables "mise_a_jour_..."
|
||||||
|
for (int num_octet=0; num_octet<message_applicatif.taille_donnees; num_octet++){
|
||||||
|
écriture_données(message_applicatif.adresse_registre + num_octet, message_applicatif.donnees_applicative.donnees[num_octet]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mise_a_jour_position){
|
||||||
|
struct msg_propulsion_position_t msg_propulsion_position;
|
||||||
|
|
||||||
|
get_données_reçues((uint8_t *) &msg_propulsion_position, sizeof(msg_propulsion_position), REG_PROPULSION_POSITION);
|
||||||
|
printf("mise à jour de la position, x:%2.2f, y:%2.2f, orientation: %2.2f\n", msg_propulsion_position.position_x_mm,
|
||||||
|
msg_propulsion_position.position_y_mm, msg_propulsion_position.orientation_rad);
|
||||||
|
}
|
||||||
|
if(mise_a_jour_mode){
|
||||||
|
uint8_t mode;
|
||||||
|
get_données_reçues(&mode, sizeof(mode), REG_PROPULSION_MODE);
|
||||||
|
printf("mode:%d\n", mode);
|
||||||
|
}
|
||||||
|
if(mise_a_jour_pwm){
|
||||||
|
struct msg_propulsion_pwm_t msg_propulsion_pwm;
|
||||||
|
get_données_reçues((uint8_t *) &msg_propulsion_pwm, sizeof(msg_propulsion_pwm), REG_PROPULSION_PWM);
|
||||||
|
printf("pwm_gauche:%d, pwm_droit:%d\n", msg_propulsion_pwm.pwm_gauche, msg_propulsion_pwm.pwm_gauche);
|
||||||
|
}
|
||||||
|
if(mise_a_jour_vitesse_roues){
|
||||||
|
struct msg_propulsion_vitesse_roues_t msg_propulsion_vitesse_roues;
|
||||||
|
get_données_reçues((uint8_t *) &msg_propulsion_vitesse_roues, sizeof(msg_propulsion_vitesse_roues), REG_PROPULSION_VITESSE_ROUES);
|
||||||
|
printf("vitesse_roue_gauche:%f, vitesse_roue_gauche:%d\n", msg_propulsion_vitesse_roues.vitesse_gauche_mm_s, msg_propulsion_vitesse_roues.vitesse_droite_mm_s);
|
||||||
|
}
|
||||||
|
if(mise_a_jour_vitesse_robot){
|
||||||
|
struct msg_propulsion_vitesse_robot_t msg_propulsion_vitesse_robot;
|
||||||
|
get_données_reçues((uint8_t *) &msg_propulsion_vitesse_robot, sizeof(msg_propulsion_vitesse_robot), REG_PROPULSION_VITESSE_ROBOT);
|
||||||
|
printf("avance_robot (mm/s) : %f, rotation (rad/s): %f\n", msg_propulsion_vitesse_robot.avance_mm_s,
|
||||||
|
msg_propulsion_vitesse_robot.rotation_rad_s);
|
||||||
|
|
||||||
|
}
|
||||||
|
if(mise_a_jour_trajectoire){
|
||||||
|
// Oh la la !
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(message_applicatif.id_carte == USB_ID_PROPULSION && message_applicatif.adresse_registre == REG_PROPULSION_POSITION){
|
||||||
|
printf("x:%x, y:%x, rot:%x\n", message_applicatif.donnees_applicative.msg_propulsion_position.position_x_mm,
|
||||||
|
message_applicatif.donnees_applicative.msg_propulsion_position.position_y_mm,
|
||||||
|
message_applicatif.donnees_applicative.msg_propulsion_position.orientation_rad);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
id_carte = message.donnees[1];
|
||||||
|
registre = message.donnees[2];
|
||||||
|
if(id_carte == 'D'){
|
||||||
|
temps_message_detection = get_absolute_time();
|
||||||
|
if(message.donnees[4] > 0 && message.donnees[4] < 30){
|
||||||
|
printf(">LED ON\n");
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||||
|
}else{
|
||||||
|
printf(">LED OFF\n");
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_time_us = get_absolute_time();
|
||||||
|
//printf(">temps_reception:%lld\n", current_time_us - start_time_us);
|
||||||
|
//printf(">nb_message:%u\n",nb_message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(get_absolute_time() / 1000. - temps_ms > 100){
|
||||||
|
temps_ms = get_absolute_time() / 1000.;
|
||||||
|
printf(">nb_message:%u\n", nb_message);
|
||||||
}
|
}
|
||||||
sleep_ms(50);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
absolute_time_t envoie_nb_char(int nb_char) {
|
absolute_time_t envoie_nb_char(int nb_char) {
|
||||||
absolute_time_t current_time_us, start_time_us;
|
absolute_time_t current_time_us, start_time_us;
|
||||||
char message[10000];
|
int j=0;
|
||||||
for(int i=0; i<10000; i++){
|
|
||||||
message[i]= i%26 + 'a';
|
|
||||||
}
|
|
||||||
if (nb_char == 0){
|
if (nb_char == 0){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
message[nb_char - 1] = '\n';
|
chaine_envoie[nb_char - 1] = '\n';
|
||||||
message[nb_char] = '\0';
|
chaine_envoie[nb_char] = '\0';
|
||||||
start_time_us = get_absolute_time();
|
start_time_us = get_absolute_time();
|
||||||
printf("%s", message);
|
printf("%s", chaine_envoie);
|
||||||
|
envoie_donnees(chaine_envoie, strlen(chaine_envoie));
|
||||||
|
|
||||||
current_time_us = get_absolute_time();
|
current_time_us = get_absolute_time();
|
||||||
|
chaine_envoie[nb_char - 1] = 'a';
|
||||||
|
chaine_envoie[nb_char] = 'a';
|
||||||
return current_time_us - start_time_us;
|
return current_time_us - start_time_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
messagerie.c
Normal file
26
messagerie.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "messagerie.h"
|
||||||
|
|
||||||
|
#define NB_MAX_MESSAGE 30
|
||||||
|
|
||||||
|
int index_message=0;
|
||||||
|
struct message_t message_liste[NB_MAX_MESSAGE];
|
||||||
|
|
||||||
|
/// @brief Renvoi 1 si des message sont disponibles
|
||||||
|
/// @return
|
||||||
|
bool messagerie_message_disponible(){
|
||||||
|
return (index_message != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Renvoi un message à traiter, à n'appeler que si message_disponible() renvoie 1
|
||||||
|
/// @return Message
|
||||||
|
struct message_t messagerie_get_message(){
|
||||||
|
index_message = index_message - 1;
|
||||||
|
return message_liste[index_message];
|
||||||
|
}
|
||||||
|
|
||||||
|
void messagerie_put_message(struct message_t message){
|
||||||
|
if(index_message < NB_MAX_MESSAGE-1){
|
||||||
|
message_liste[index_message] = message;
|
||||||
|
index_message = index_message + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
messagerie.h
Normal file
36
messagerie.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "messages_propulsion.h"
|
||||||
|
|
||||||
|
#define MESSAGE_TIMEOUT_US 2000
|
||||||
|
|
||||||
|
struct message_t{
|
||||||
|
uint8_t type; // 'b' pour binaire, '>' pour des logs
|
||||||
|
uint8_t taille_donnees;
|
||||||
|
uint8_t donnees[255];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct message_requete_t{
|
||||||
|
uint8_t commande;
|
||||||
|
uint8_t id_carte; // Identifiant de la carte (on reprend les adresses I2C)
|
||||||
|
uint8_t adresse_registre; // Adresse du registre lu
|
||||||
|
uint8_t taille_donnees;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct message_applicatif_t{
|
||||||
|
uint8_t commande; // 'r' : réception de données, 'd' : demande de données
|
||||||
|
uint8_t id_carte; // Identifiant de la carte (on reprend les adresses I2C)
|
||||||
|
uint8_t adresse_registre; // Adresse du registre lu ou écrit
|
||||||
|
uint8_t taille_donnees;
|
||||||
|
union{
|
||||||
|
uint8_t donnees[100];
|
||||||
|
#ifdef MESSAGE_PROPULSION_H
|
||||||
|
struct msg_propulsion_position_t msg_propulsion_position;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}donnees_applicative;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
bool messagerie_message_disponible();
|
||||||
|
struct message_t messagerie_get_message();
|
||||||
|
void messagerie_put_message(struct message_t message);
|
||||||
50
messagerie_applicative.c
Normal file
50
messagerie_applicative.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "messagerie_applicative.h"
|
||||||
|
|
||||||
|
uint8_t memoire_echange[200];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool mise_a_jour_position = false;
|
||||||
|
bool mise_a_jour_mode = false;
|
||||||
|
bool mise_a_jour_pwm = false;
|
||||||
|
bool mise_a_jour_vitesse_roues = false;
|
||||||
|
bool mise_a_jour_vitesse_robot = false;
|
||||||
|
bool mise_a_jour_trajectoire = false;
|
||||||
|
|
||||||
|
void get_données_reçues(uint8_t * dst, unsigned int taille, unsigned int registre){
|
||||||
|
memcpy(dst, &(memoire_echange[registre]), taille);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void écriture_données(unsigned int adresse, uint8_t donnée){
|
||||||
|
if( adresse <= 11){
|
||||||
|
// Position du robot
|
||||||
|
mise_a_jour_position = true;
|
||||||
|
}else if(adresse <= 12){
|
||||||
|
// Read only
|
||||||
|
|
||||||
|
}else if(adresse <= 13){
|
||||||
|
// Mode
|
||||||
|
mise_a_jour_mode = true;
|
||||||
|
}else if(adresse <= 17){
|
||||||
|
// PWM moteur
|
||||||
|
mise_a_jour_pwm = true;
|
||||||
|
}else if(adresse <= 25){
|
||||||
|
// Vitesse roues
|
||||||
|
mise_a_jour_vitesse_roues = true;
|
||||||
|
}else if(adresse <= 33){
|
||||||
|
// Vitesse robot
|
||||||
|
mise_a_jour_vitesse_robot = true;
|
||||||
|
}else if(adresse <= 86){
|
||||||
|
// Trajectoire
|
||||||
|
mise_a_jour_trajectoire = true;
|
||||||
|
}else if(adresse >86){
|
||||||
|
// Hors mémoire
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memoire_echange[adresse] = donnée;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
12
messagerie_applicative.h
Normal file
12
messagerie_applicative.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void écriture_données(unsigned int adresse, uint8_t donnée);
|
||||||
|
void get_données_reçues(uint8_t * dst, unsigned int taille, unsigned int registre);
|
||||||
|
|
||||||
|
extern bool mise_a_jour_position;
|
||||||
|
extern bool mise_a_jour_mode;
|
||||||
|
extern bool mise_a_jour_pwm;
|
||||||
|
extern bool mise_a_jour_vitesse_roues;
|
||||||
|
extern bool mise_a_jour_vitesse_robot;
|
||||||
|
extern bool mise_a_jour_trajectoire;
|
||||||
27
messages_propulsion.h
Normal file
27
messages_propulsion.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef MESSAGE_PROPULSION_H
|
||||||
|
#define MESSAGE_PROPULSION_H
|
||||||
|
#define USB_ID_PROPULSION 'P'
|
||||||
|
|
||||||
|
#define REG_PROPULSION_POSITION 0x00
|
||||||
|
#define REG_PROPULSION_MODE 0x0D
|
||||||
|
#define REG_PROPULSION_PWM 0x0E
|
||||||
|
#define REG_PROPULSION_VITESSE_ROUES 0x12
|
||||||
|
#define REG_PROPULSION_VITESSE_ROBOT 0x1A
|
||||||
|
|
||||||
|
struct msg_propulsion_position_t{
|
||||||
|
float position_x_mm, position_y_mm, orientation_rad;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_propulsion_pwm_t{
|
||||||
|
uint16_t pwm_gauche, pwm_droit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_propulsion_vitesse_roues_t{
|
||||||
|
float vitesse_gauche_mm_s, vitesse_droite_mm_s;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_propulsion_vitesse_robot_t {
|
||||||
|
float avance_mm_s, rotation_rad_s;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user