Няма описание
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /**
  2. ******************************************************************************
  3. * @file cmdManager.c
  4. * @author Lucien Senaneuch
  5. * @version V1.0
  6. * @date 16-mai-2016
  7. * @brief Gestion de commande reçu via l'uart
  8. * Traite les chaine de caractére reçu par l'uart.
  9. * Permet de verifier les erreurs de checksum,
  10. * de traiter les valeurs retour.
  11. *
  12. *@attention Utilise les variables global - receiptString - sendString
  13. *
  14. ******************************************************************************
  15. ******************************************************************************
  16. */
  17. #include <stm32f10x.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "cmdManager.h"
  22. #include "battery.h"
  23. #include "motor.h"
  24. #include "system_dumby.h"
  25. #include "usart.h"
  26. /** @addtogroup Projects
  27. * @{
  28. */
  29. /** @addtogroup cmdManager
  30. * @{
  31. */
  32. /* Definition des commandes */
  33. #define PingCMD 'p'
  34. #define ResetCMD 'r'
  35. #define SetMotorCMD 'm'
  36. #define StartWWatchDogCMD 'W'
  37. #define ResetWatchdogCMD 'w'
  38. #define GetBatteryVoltageCMD 'v'
  39. #define GetVersionCMD 'V'
  40. #define StartWithoutWatchCMD 'u'
  41. #define MoveCMD 'M'
  42. #define TurnCMD 'T'
  43. #define BusyStateCMD 'b'
  44. #define TestCMD 't'
  45. #define DebugCMD 'a'
  46. #define PowerOffCMD 'z'
  47. #define OK_ANS "O\r"
  48. #define ERR_ANS "E\r"
  49. #define UNKNOW_ANS "C\r"
  50. #define BAT_OK "2\r"
  51. #define BAT_LOW "1\r"
  52. #define BAT_EMPTY "0\r"
  53. /* Prototype des fonctions */
  54. char cmdVerifyChecksum(void);
  55. void cmdAddChecksum(void);
  56. void cmdResetAction(void);
  57. void cmdBusyStateAction(void);
  58. void cmdPingAction(void);
  59. void cmdVersionAction(void);
  60. void cmdStartWithoutWatchdogAction(void);
  61. void cmdMoveAction(void);
  62. void cmdTurnAction(void);
  63. void cmdBatteryVoltageAction(void);
  64. void cmdStartWithWatchdogAction(void);
  65. void cmdResetWatchdogAction(void);
  66. void cmdDebugAction(void);
  67. void cmdPowerOffAction(void);
  68. /** @addtogroup Checksum
  69. * @{
  70. */
  71. /**
  72. * @brief Inclut le checksum à sendString
  73. *
  74. * Parcours sendString pour y calculer le checksum ( xor sur chaque caractére)
  75. * et inclut le resultat en fin de chaine.
  76. *
  77. * @param None
  78. * @retval 0 ou 1
  79. *
  80. */
  81. void cmdAddChecksum(void) {
  82. uint16_t j;
  83. unsigned char checksum=0;
  84. for (j = 0; sendString[j] != '\r'; j++)
  85. checksum ^= sendString[j];
  86. if (checksum == '\r')
  87. checksum++;
  88. sendString[j] = checksum;
  89. sendString[j + 1] = '\r';
  90. }
  91. /**
  92. * @brief Verifie le checksum de la variable global recepitString
  93. *
  94. * Vérifie le dernier carctére de receiptString sensé être le checksum.
  95. * Si celui-ci est bon, ll retournera 0 et supprimera le checksum du tableau receiptString
  96. * sinon il retournera 1 sans faire de modification.
  97. * @param None
  98. * @retval 0 ou 1
  99. *
  100. */
  101. char cmdVerifyChecksum(void) {
  102. uint16_t j;
  103. uint16_t length;
  104. unsigned char checksum=0;
  105. length = strlen(receiptString);
  106. for (j = 0; j < length - 2; j++) {
  107. checksum ^= receiptString[j];
  108. }
  109. if (checksum == '\r')
  110. checksum++;
  111. if (receiptString[j] == checksum) {
  112. receiptString[length - 2] = 13;
  113. receiptString[length - 1] = 0;
  114. receiptString[length] = 0;
  115. return 0;
  116. } else
  117. return 1;
  118. }
  119. /**
  120. * @}
  121. */
  122. /** @addtogroup TestCmd
  123. * @{
  124. */
  125. /**
  126. * @brief Traite la commande de reception
  127. *
  128. * Gére le premier caractére de la chaine de reception pour en déduire la
  129. * commande à appliqué.
  130. * Copie E dans sendString si une erreur s'est produite.
  131. * Copie C dans sendString si la commande n'a pas abouti.
  132. *
  133. * @param None
  134. * @retval None
  135. */
  136. void cmdManage(void) {
  137. if (cmdVerifyChecksum() != 0) {
  138. strcpy(sendString, UNKNOW_ANS);
  139. } else { // Checksum valide
  140. if (Dumber.StateSystem==STATE_DISABLE) { // SI la batterie est trop faible, impossible d'accepter une commande sauf poweroff: on reste dans ce mode
  141. if (receiptString[0]==PowerOffCMD)
  142. cmdPowerOffAction();
  143. else
  144. strcpy(sendString, ERR_ANS);
  145. } else {
  146. switch (receiptString[0]) {
  147. case PingCMD:
  148. cmdPingAction();
  149. break;
  150. case ResetCMD:
  151. cmdResetAction();
  152. break;
  153. case StartWWatchDogCMD:
  154. cmdStartWithWatchdogAction();
  155. break;
  156. case ResetWatchdogCMD:
  157. cmdResetWatchdogAction();
  158. break;
  159. case GetBatteryVoltageCMD:
  160. cmdBatteryVoltageAction();
  161. break;
  162. case GetVersionCMD:
  163. cmdVersionAction();
  164. break;
  165. case StartWithoutWatchCMD:
  166. cmdStartWithoutWatchdogAction();
  167. break;
  168. case MoveCMD:
  169. cmdMoveAction();
  170. break;
  171. case TurnCMD:
  172. cmdTurnAction();
  173. break;
  174. case BusyStateCMD:
  175. cmdBusyStateAction();
  176. break;
  177. case DebugCMD:
  178. cmdDebugAction();
  179. break;
  180. case PowerOffCMD:
  181. cmdPowerOffAction();
  182. break;
  183. default:
  184. strcpy(sendString, UNKNOW_ANS);
  185. }
  186. }
  187. }
  188. Dumber.cpt_inactivity=0; // remise a zéro du compteur d'inativité
  189. }
  190. /**
  191. * @}
  192. */
  193. /** @addtogroup Traitement_Cmd
  194. * @{
  195. */
  196. /**
  197. * @brief Commande Ping
  198. * Retourne OK_ANS si success dans sendString. Sinon return ERR_ANS.
  199. *
  200. * @param None
  201. * @retval None
  202. */
  203. void cmdPingAction(void) {
  204. if (receiptString[1] == '\r')
  205. strcpy(sendString, OK_ANS);
  206. else
  207. strcpy(sendString, ERR_ANS);
  208. }
  209. /**
  210. * @brief Execute la commande reset.
  211. * Remet l'état de dumby à "idle".
  212. * Retourne OK_ANS si success dans sendString. Sinon return ERR_ANS.
  213. *
  214. * @param None
  215. * @retval None
  216. */
  217. void cmdResetAction(void) {
  218. systemChangeState(STATE_IDLE);
  219. strcpy(sendString, OK_ANS);
  220. }
  221. /**
  222. * @brief Execute la commande Version.
  223. * Retourne la version du soft dans sendString.
  224. * @param None
  225. * @retval None
  226. */
  227. void cmdVersionAction(void) {
  228. if (receiptString[1] == '\r')
  229. strcpy(sendString, VERSION);
  230. else
  231. strcpy(sendString, ERR_ANS);
  232. }
  233. /**
  234. * @brief Effectue une action BusyState.
  235. * Retourne si le robot est en mouvement ou non.
  236. * La variable est passé dans sendString - O ou 1.
  237. *
  238. * @param None
  239. * @retval None
  240. */
  241. void cmdBusyStateAction(void) {
  242. if ((Dumber.StateSystem == STATE_RUN) || (Dumber.StateSystem == STATE_LOW)) {
  243. if (Dumber.busyState == TRUE)
  244. strcpy(sendString, "1\r");
  245. else
  246. strcpy(sendString, "0\r");
  247. } else {
  248. strcpy(sendString, ERR_ANS);
  249. }
  250. }
  251. /**
  252. * @brief Effectue une remise à zéro du watchdog.
  253. *
  254. * @param None
  255. * @retval None
  256. */
  257. void cmdResetWatchdogAction(void) {
  258. if (systemResetWatchdog()!=0) { // Réussite
  259. strcpy(sendString, OK_ANS);
  260. } else strcpy(sendString, ERR_ANS);
  261. }
  262. /**
  263. * @brief Passe le robot en mode RUN.
  264. * Necessite que le robot soit en mode IDLE au préalable.
  265. * Le passage en mode run activera également les timers du watchdog.
  266. * Qu'il faut remettre à zero entre 950ms et 1050ms.
  267. *
  268. * @param None
  269. * @retval None
  270. */
  271. void cmdStartWithWatchdogAction(void) {
  272. if (Dumber.StateSystem == STATE_IDLE && receiptString[1] == '\r') {
  273. Dumber.WatchDogStartEnable = TRUE;
  274. systemChangeState(STATE_RUN);
  275. strcpy(sendString, OK_ANS);
  276. } else
  277. strcpy(sendString, ERR_ANS);
  278. }
  279. /**
  280. * @brief Passe le robot en mode RUN mais sans watchdog.
  281. * Necessite que dumby soit en mode IDLE au prealable.
  282. *
  283. * @param None
  284. * @retval None
  285. */
  286. void cmdStartWithoutWatchdogAction(void) {
  287. if (Dumber.StateSystem == STATE_IDLE && receiptString[1] == '\r') {
  288. Dumber.WatchDogStartEnable = FALSE;
  289. systemChangeState(STATE_RUN);
  290. strcpy(sendString, OK_ANS);
  291. } else
  292. strcpy(sendString, ERR_ANS);
  293. }
  294. /**
  295. * @brief Demande un mouvement en ligne droite.
  296. * Les paramétres sont inclus dans receiptString.
  297. * Le type de commande à envoyer est :"M=val\r". Ou val
  298. * peut être positif ou negatif.
  299. *
  300. * @param None
  301. * @retval None
  302. */
  303. void cmdMoveAction(void) {
  304. if (Dumber.StateSystem == STATE_RUN || Dumber.StateSystem == STATE_LOW) {
  305. int laps;
  306. uint16_t testReception = sscanf(receiptString, "M=%i\r", &laps);
  307. unsigned char mod = 0;
  308. tourPositionG = 0;
  309. tourPositionD = 0;
  310. if (testReception == 1) {
  311. Dumber.cpt_inactivity = 0;
  312. Dumber.busyState = TRUE;
  313. if (laps < 0) {
  314. laps = laps * -1;
  315. mod = REVERSE;
  316. } else
  317. mod = FORWARD;
  318. laps = laps * 2;
  319. motorRegulation(mod, mod, (unsigned) laps, (unsigned) laps,
  320. COMMONSPEED, COMMONSPEED);
  321. strcpy(sendString, OK_ANS);
  322. } else
  323. strcpy(sendString, ERR_ANS);
  324. }
  325. }
  326. /**
  327. * @brief Execute une action tourne avec les paramètres dans receitpString.
  328. * Type de commande à envoyer : "T=val\r". Ou val peut être positif
  329. * ou negatif.
  330. *
  331. * @param None
  332. * @retval None
  333. */
  334. void cmdTurnAction(void) {
  335. if (Dumber.StateSystem == STATE_RUN || Dumber.StateSystem == STATE_LOW) {
  336. int degree;
  337. uint16_t testReception = sscanf(receiptString, "T=%i\r", &degree);
  338. tourPositionG = 0;
  339. tourPositionD = 0;
  340. if (testReception == 1) {
  341. degree = degree * 1.40;
  342. Dumber.cpt_inactivity = 0;
  343. Dumber.busyState = TRUE;
  344. if (degree < 0) {
  345. degree = degree * -1;
  346. motorRegulation(FORWARD, REVERSE, (unsigned) degree,
  347. (unsigned) degree, LOWSPEED, LOWSPEED);
  348. } else {
  349. motorRegulation(REVERSE, FORWARD, (unsigned) degree,
  350. (unsigned) degree, LOWSPEED, LOWSPEED);
  351. }
  352. strcpy(sendString, OK_ANS);
  353. } else
  354. strcpy(sendString, ERR_ANS);
  355. }
  356. }
  357. /**
  358. * @brief retourne une valeur de batterie.
  359. * La valeur de la batterie peut être - 0 - 1 - 2.
  360. * Lorsque la batterie est pleine, la valeur retournée est 2.
  361. * Lorque la batterie est intermediaire, la valeur retournée est 1.
  362. * Lorsque la batterie est vide, la valeur retournée est 0.
  363. *
  364. * @param None
  365. * @retval None
  366. */
  367. void cmdBatteryVoltageAction(void) {
  368. char battery[2];
  369. battery[0] = Dumber.stateBattery + '0';
  370. battery[1] = '\r';
  371. strcpy(sendString, battery);
  372. }
  373. /**
  374. * @brief Envoie le nombre de tour théorique à effectuer.
  375. * Et le nombre de tour effectué au moment de reception de la commande.
  376. * Th- Consigne de commande en nombre de tour.
  377. * Re- Nombre de tour reel effectué.
  378. *
  379. * @param None
  380. * @retval None
  381. */
  382. void cmdDebugAction(void) {
  383. uint8_t j;
  384. sprintf(sendString, "Th-D=%u G=%u\r", tourPositionD, tourPositionG);
  385. usartSendData();
  386. for (j = 0; j < 200; j++);
  387. sprintf(sendString, "Re-D=%u G=%u\r", G_lapsRight, G_lapsLeft);
  388. usartSendData();
  389. }
  390. /**
  391. * @brief Eteint le robot
  392. *
  393. * @param None
  394. * @retval None
  395. */
  396. void cmdPowerOffAction(void) {
  397. volatile int i;
  398. systemChangeState(STATE_DISABLE);
  399. strcpy(sendString, OK_ANS);
  400. cmdAddChecksum();
  401. usartSendData();
  402. /* Attente d'un certain temps (100 ms), pour que la reponse parte */
  403. for (i=0; i<100000; i++);
  404. systemShutDown(); // Ne ressort jamais de cette fonction
  405. }
  406. /**
  407. * @}
  408. */
  409. /**
  410. * @}
  411. */
  412. /**
  413. * @}
  414. */