Nav apraksta
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

cmdManager.c 11KB

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