mirror of
https://github.com/yoboujon/dumber.git
synced 2025-06-09 06:10:49 +02:00
475 lines
12 KiB
C
475 lines
12 KiB
C
/**
|
|
******************************************************************************
|
|
* @file cmdManager.c
|
|
* @author Lucien Senaneuch
|
|
* @version V1.0
|
|
* @date 16-mai-2016
|
|
* @brief Gestion de commande reçu via l'uart
|
|
* Traite les chaine de caractére reçu par l'uart.
|
|
* Permet de verifier les erreurs de checksum,
|
|
* de traiter les valeurs retour.
|
|
*
|
|
*@attention Utilise les variables global - receiptString - sendString
|
|
*
|
|
******************************************************************************
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include <stm32f10x.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "cmdManager.h"
|
|
#include "battery.h"
|
|
#include "motor.h"
|
|
#include "system_dumby.h"
|
|
#include "usart.h"
|
|
|
|
/** @addtogroup Projects
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup cmdManager
|
|
* @{
|
|
*/
|
|
|
|
/* Definition des commandes */
|
|
|
|
#define PingCMD 'p'
|
|
#define ResetCMD 'r'
|
|
#define SetMotorCMD 'm'
|
|
#define StartWWatchDogCMD 'W'
|
|
#define ResetWatchdogCMD 'w'
|
|
#define GetBatteryVoltageCMD 'v'
|
|
#define GetVersionCMD 'V'
|
|
#define StartWithoutWatchCMD 'u'
|
|
#define MoveCMD 'M'
|
|
#define TurnCMD 'T'
|
|
#define BusyStateCMD 'b'
|
|
#define TestCMD 't'
|
|
#define DebugCMD 'a'
|
|
#define PowerOffCMD 'z'
|
|
|
|
#define OK_ANS "O\r"
|
|
#define ERR_ANS "E\r"
|
|
#define UNKNOW_ANS "C\r"
|
|
#define BAT_OK "2\r"
|
|
#define BAT_LOW "1\r"
|
|
#define BAT_EMPTY "0\r"
|
|
|
|
/* Prototype des fonctions */
|
|
|
|
char cmdVerifyChecksum(void);
|
|
void cmdAddChecksum(void);
|
|
void cmdResetAction(void);
|
|
void cmdBusyStateAction(void);
|
|
void cmdPingAction(void);
|
|
void cmdVersionAction(void);
|
|
void cmdStartWithoutWatchdogAction(void);
|
|
void cmdMoveAction(void);
|
|
void cmdTurnAction(void);
|
|
void cmdBatteryVoltageAction(void);
|
|
void cmdStartWithWatchdogAction(void);
|
|
void cmdResetWatchdogAction(void);
|
|
void cmdDebugAction(void);
|
|
void cmdPowerOffAction(void);
|
|
|
|
/** @addtogroup Checksum
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Inclut le checksum à sendString
|
|
*
|
|
* Parcours sendString pour y calculer le checksum ( xor sur chaque caractére)
|
|
* et inclut le resultat en fin de chaine.
|
|
*
|
|
* @param None
|
|
* @retval 0 ou 1
|
|
*
|
|
*/
|
|
void cmdAddChecksum(void) {
|
|
uint16_t j;
|
|
unsigned char checksum=0;
|
|
|
|
for (j = 0; sendString[j] != '\r'; j++)
|
|
checksum ^= sendString[j];
|
|
if (checksum == '\r')
|
|
checksum++;
|
|
sendString[j] = checksum;
|
|
sendString[j + 1] = '\r';
|
|
}
|
|
|
|
/**
|
|
* @brief Verifie le checksum de la variable global recepitString
|
|
*
|
|
* Vérifie le dernier carctére de receiptString sensé être le checksum.
|
|
* Si celui-ci est bon, ll retournera 0 et supprimera le checksum du tableau receiptString
|
|
* sinon il retournera 1 sans faire de modification.
|
|
* @param None
|
|
* @retval 0 ou 1
|
|
*
|
|
*/
|
|
char cmdVerifyChecksum(void) {
|
|
uint16_t j;
|
|
uint16_t length;
|
|
unsigned char checksum=0;
|
|
|
|
length = strlen(receiptString);
|
|
for (j = 0; j < length - 2; j++) {
|
|
checksum ^= receiptString[j];
|
|
}
|
|
if (checksum == '\r')
|
|
checksum++;
|
|
|
|
if (receiptString[j] == checksum) {
|
|
receiptString[length - 2] = 13;
|
|
receiptString[length - 1] = 0;
|
|
receiptString[length] = 0;
|
|
|
|
return 0;
|
|
} else
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @addtogroup TestCmd
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Traite la commande de reception
|
|
*
|
|
* Gére le premier caractére de la chaine de reception pour en déduire la
|
|
* commande à appliqué.
|
|
* Copie E dans sendString si une erreur s'est produite.
|
|
* Copie C dans sendString si la commande n'a pas abouti.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
|
|
void cmdManage(void) {
|
|
if (cmdVerifyChecksum() != 0) {
|
|
strcpy(sendString, UNKNOW_ANS);
|
|
} else { // Checksum valide
|
|
if (Dumber.StateSystem==STATE_DISABLE) { // SI la batterie est trop faible, impossible d'accepter une commande sauf poweroff: on reste dans ce mode
|
|
if (receiptString[0]==PowerOffCMD)
|
|
cmdPowerOffAction();
|
|
else
|
|
strcpy(sendString, ERR_ANS);
|
|
} else {
|
|
switch (receiptString[0]) {
|
|
case PingCMD:
|
|
cmdPingAction();
|
|
break;
|
|
|
|
case ResetCMD:
|
|
cmdResetAction();
|
|
break;
|
|
|
|
case StartWWatchDogCMD:
|
|
cmdStartWithWatchdogAction();
|
|
break;
|
|
|
|
case ResetWatchdogCMD:
|
|
cmdResetWatchdogAction();
|
|
break;
|
|
|
|
case GetBatteryVoltageCMD:
|
|
cmdBatteryVoltageAction();
|
|
break;
|
|
|
|
case GetVersionCMD:
|
|
cmdVersionAction();
|
|
break;
|
|
|
|
case StartWithoutWatchCMD:
|
|
cmdStartWithoutWatchdogAction();
|
|
break;
|
|
|
|
case MoveCMD:
|
|
cmdMoveAction();
|
|
break;
|
|
|
|
case TurnCMD:
|
|
cmdTurnAction();
|
|
break;
|
|
|
|
case BusyStateCMD:
|
|
cmdBusyStateAction();
|
|
break;
|
|
|
|
case DebugCMD:
|
|
cmdDebugAction();
|
|
break;
|
|
|
|
case PowerOffCMD:
|
|
cmdPowerOffAction();
|
|
break;
|
|
default:
|
|
strcpy(sendString, UNKNOW_ANS);
|
|
}
|
|
}
|
|
}
|
|
|
|
Dumber.cpt_inactivity=0; // remise a zéro du compteur d'inativité
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @addtogroup Traitement_Cmd
|
|
* @{
|
|
*/
|
|
/**
|
|
* @brief Commande Ping
|
|
* Retourne OK_ANS si success dans sendString. Sinon return ERR_ANS.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
|
|
void cmdPingAction(void) {
|
|
if (receiptString[1] == '\r')
|
|
strcpy(sendString, OK_ANS);
|
|
else
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
|
|
/**
|
|
* @brief Execute la commande reset.
|
|
* Remet l'état de dumby à "idle".
|
|
* Retourne OK_ANS si success dans sendString. Sinon return ERR_ANS.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdResetAction(void) {
|
|
systemChangeState(STATE_IDLE);
|
|
strcpy(sendString, OK_ANS);
|
|
}
|
|
|
|
/**
|
|
* @brief Execute la commande Version.
|
|
* Retourne la version du soft dans sendString.
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdVersionAction(void) {
|
|
if (receiptString[1] == '\r')
|
|
strcpy(sendString, VERSION);
|
|
else
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
|
|
/**
|
|
* @brief Effectue une action BusyState.
|
|
* Retourne si le robot est en mouvement ou non.
|
|
* La variable est passé dans sendString - O ou 1.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdBusyStateAction(void) {
|
|
if ((Dumber.StateSystem == STATE_RUN) || (Dumber.StateSystem == STATE_LOW)) {
|
|
if (Dumber.busyState == TRUE)
|
|
strcpy(sendString, "1\r");
|
|
else
|
|
strcpy(sendString, "0\r");
|
|
} else {
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Effectue une remise à zéro du watchdog.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdResetWatchdogAction(void) {
|
|
if (systemResetWatchdog()!=0) { // Réussite
|
|
strcpy(sendString, OK_ANS);
|
|
} else strcpy(sendString, ERR_ANS);
|
|
}
|
|
|
|
/**
|
|
* @brief Passe le robot en mode RUN.
|
|
* Necessite que le robot soit en mode IDLE au préalable.
|
|
* Le passage en mode run activera également les timers du watchdog.
|
|
* Qu'il faut remettre à zero entre 950ms et 1050ms.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdStartWithWatchdogAction(void) {
|
|
if (Dumber.StateSystem == STATE_IDLE && receiptString[1] == '\r') {
|
|
Dumber.WatchDogStartEnable = TRUE;
|
|
systemChangeState(STATE_RUN);
|
|
strcpy(sendString, OK_ANS);
|
|
} else
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
|
|
/**
|
|
* @brief Passe le robot en mode RUN mais sans watchdog.
|
|
* Necessite que dumby soit en mode IDLE au prealable.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdStartWithoutWatchdogAction(void) {
|
|
if (Dumber.StateSystem == STATE_IDLE && receiptString[1] == '\r') {
|
|
Dumber.WatchDogStartEnable = FALSE;
|
|
systemChangeState(STATE_RUN);
|
|
strcpy(sendString, OK_ANS);
|
|
} else
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Demande un mouvement en ligne droite.
|
|
* Les paramétres sont inclus dans receiptString.
|
|
* Le type de commande à envoyer est :"M=val\r". Ou val
|
|
* peut être positif ou negatif.
|
|
*
|
|
* @param NSTART_WITH_WDone
|
|
* @retval None
|
|
*/
|
|
void cmdMoveAction(void) {
|
|
if (Dumber.StateSystem == STATE_RUN || Dumber.StateSystem == STATE_LOW) {
|
|
int laps;
|
|
uint16_t testReception = sscanf(receiptString, "M=%i\r", &laps);
|
|
unsigned char mod = 0;
|
|
tourPositionG = 0;
|
|
tourPositionD = 0;
|
|
|
|
if (testReception == 1) {
|
|
Dumber.cpt_inactivity = 0;
|
|
Dumber.busyState = TRUE;
|
|
if (laps < 0) {
|
|
laps = laps * -1;
|
|
mod = REVERSE;
|
|
} else
|
|
mod = FORWARD;
|
|
|
|
laps = laps * 2;
|
|
|
|
motorRegulation(mod, mod, (unsigned) laps, (unsigned) laps,
|
|
COMMONSPEED, COMMONSPEED);
|
|
|
|
strcpy(sendString, OK_ANS);
|
|
} else
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Execute une action tourne avec les paramètres dans receitpString.
|
|
* Type de commande à envoyer : "T=val\r". Ou val peut être positif
|
|
* ou negatif.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdTurnAction(void) {
|
|
if (Dumber.StateSystem == STATE_RUN || Dumber.StateSystem == STATE_LOW) {
|
|
int degree;
|
|
uint16_t testReception = sscanf(receiptString, "T=%i\r", °ree);
|
|
tourPositionG = 0;
|
|
tourPositionD = 0;
|
|
|
|
if (testReception == 1) {
|
|
degree = degree * 1.40;
|
|
Dumber.cpt_inactivity = 0;
|
|
Dumber.busyState = TRUE;
|
|
|
|
if (degree < 0) {
|
|
degree = degree * -1;
|
|
motorRegulation(FORWARD, REVERSE, (unsigned) degree,
|
|
(unsigned) degree, LOWSPEED, LOWSPEED);
|
|
} else {
|
|
motorRegulation(REVERSE, FORWARD, (unsigned) degree,
|
|
(unsigned) degree, LOWSPEED, LOWSPEED);
|
|
}
|
|
strcpy(sendString, OK_ANS);
|
|
} else
|
|
strcpy(sendString, ERR_ANS);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief retourne une valeur de batterie.
|
|
* La valeur de la batterie peut être - 0 - 1 - 2.
|
|
* Lorsque la batterie est pleine, la valeur retournée est 2.
|
|
* Lorque la batterie est intermediaire, la valeur retournée est 1.
|
|
* Lorsque la batterie est vide, la valeur retournée est 0.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdBatteryVoltageAction(void) {
|
|
char battery[2];
|
|
battery[0] = Dumber.stateBattery + '0';
|
|
battery[1] = '\r';
|
|
strcpy(sendString, battery);
|
|
}
|
|
|
|
/**
|
|
* @brief Envoie le nombre de tour théorique à effectuer.
|
|
* Et le nombre de tour effectué au moment de reception de la commande.
|
|
* Th- Consigne de commande en nombre de tour.
|
|
* Re- Nombre de tour reel effectué.
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdDebugAction(void) {
|
|
uint8_t j;
|
|
|
|
sprintf(sendString, "Th-D=%u G=%u\r", tourPositionD, tourPositionG);
|
|
usartSendData();
|
|
|
|
for (j = 0; j < 200; j++);
|
|
sprintf(sendString, "Re-D=%u G=%u\r", G_lapsRight, G_lapsLeft);
|
|
usartSendData();
|
|
}
|
|
|
|
/**
|
|
* @brief Eteint le robot
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void cmdPowerOffAction(void) {
|
|
volatile int i;
|
|
|
|
systemChangeState(STATE_DISABLE);
|
|
strcpy(sendString, OK_ANS);
|
|
|
|
cmdAddChecksum();
|
|
usartSendData();
|
|
/* Attente d'un certain temps (100 ms), pour que la reponse parte */
|
|
for (i=0; i<100000; i++);
|
|
|
|
systemShutDown(); // Ne ressort jamais de cette fonction
|
|
}
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|