Siphon Regulator 1.0
Nanosattelite attitude determination and control system.
Loading...
Searching...
No Matches
cmd_processing.c
Go to the documentation of this file.
1/*
2 * cmd_processing library
3 * (c) Antonin Putala 2026
4 *
5 * Developed using STM32CubeIDE
6 * Tested on BluePill board and STM32F103C8T6, 32 MHz.
7 */
8
9/* Includes -----------------------------------------------*/
10#include "cmd_processing.h"
11#include "cmd_processing_def.h"
12#include "main.h"
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
17/* Global functions ---------------------------------------*/
18/*
19 * Function: uart_byte_available
20 * Purpose: Recognizes commands in the received characters and
21 * sets the cmd register accordingly.
22 * Input(s): c - processed character
23 * p_reg - command register, involves
24 * information about system state and
25 * switching time of valves
26 * Returns: none
27 */
28void uart_byte_available(uint8_t c, uint32_t * p_reg)
29{
30 static uint16_t cnt;
31 static char data[CMD_BUFFER_LEN];
32
33 if (cnt < CMD_BUFFER_LEN && c >= 32 && c <= 126)
34 {
35 data[cnt++] = c;
36 }
37
38 /* Checking terminating characters */
39 if ((c == '\n' || c == '\r') && cnt > 0)
40 {
41 data[cnt] = '\0';
42 process_cmd(data, p_reg);
43 cnt = 0;
44 }
45}
46
47/* Static functions ---------------------------------------*/
48/*
49 * Function: process_cmd
50 * Purpose: Executes the corresponding commands are stores
51 * the result in the command register.
52 * Input(s): cmd - pointer to the string with processed command
53 * p_reg - command register, involves
54 * information about system state and
55 * switching time of valves
56 * Returns: none
57 */
58static void process_cmd(char * cmd, uint32_t * p_reg)
59{
60 char *token;
61 token = strtok(cmd, " ");
62
63 /* Communication test */
64 if (strcasecmp(token, "HELLO") == 0)
65 {
66 printf("Communication OK\n");
67 }
68 /* Return default position */
69 else if (strcasecmp(token, "HOME") == 0)
70 {
71 process_cmd_home(p_reg);
72 }
73 /* Read status register */
74 else if (strcasecmp(token, "STATUS") == 0)
75 {
76 printf("reg:%08lx\n", *p_reg);
77 }
78 /* Reset status register */
79 else if (strcasecmp(token, "RESET") == 0)
80 {
81 process_cmd_reset(p_reg);
82 }
83 /* Perform 1 step */
84 else if (strcasecmp(token, "TURN") == 0)
85 {
86 process_cmd_turn(token, p_reg);
87 }
88 /* Perform 1 pulse */
89 else if (strcasecmp(token, "PULSE") == 0)
90 {
91 process_cmd_pulse(token, p_reg);
92 }
93 /* Once read data from sensor */
94 else if (strcasecmp(token, "READ") == 0)
95 {
96 process_cmd_read(token);
97 }
98 /* Periodic reading data from sensors */
99 else if (strcasecmp(token, "AUTOREAD") == 0)
100 {
101 process_cmd_autoread(token, p_reg);
102 }
103 /* Enables configurate the cube */
104 else if (strcasecmp(token, "SET") == 0)
105 {
106 process_cmd_set(token, p_reg);
107 }
108 /* Reserved */
109 else if (strcasecmp(token, "CMD") == 0)
110 {
111 process_cmd_ncmd(token, p_reg);
112 }
113 else
114 {
115 printf("Invalid cmd\n");
116 }
117}
118
119/*
120* Function: process_cmd_turn
121* Purpose: Triggers a rotation by a defined angle.
122* Input(s): cmd - pointer to the string with processed command
123* p_reg - command register, involves
124* information about system state and
125* switching time of valves
126* Returns: none
127*/
128static void process_cmd_turn(char * token, uint32_t * p_reg)
129{
130 /* During performing another cmd is disable */
131 if (_read_valve(*p_reg))
132 {
133 return;
134 }
135
136 token = strtok(NULL, " ");
137 if (strcasecmp(token, "RIGHT") == 0)
138 {
139 _set_BV(*p_reg, DIR_BIT);
140 }
141 else if (strcasecmp(token, "LEFT") == 0)
142 {
143 _clr_BV(*p_reg, DIR_BIT);
144 }
145 else
146 {
147 printf("Invalid dir\n");
148 return;
149 }
150
151 /* Update time setting */
152 _clr_time(*p_reg);
154
155 /* Save turn request */
156 _set_BV(*p_reg, RUN_BIT);
157 _set_BV(*p_reg, TURN_BIT);
158}
159
160/*
161* Function: process_cmd_read
162* Purpose: Sends sensors data based on the command.
163* Input(s): cmd - pointer to the string with processed command
164*
165* Returns: none
166*/
167static void process_cmd_read(char * token)
168{
169 token = strtok(NULL, " ");
170
171 if (strcasecmp(token, "GYR") == 0)
172 {
173 printf("G: X=%d, Y=%d, Z=%d\n", _float2int(measured_data.gyr[0]),
175 }
176 else if (strcasecmp(token, "ACC") == 0)
177 {
178 printf("A: X=%d, Y=%d, Z=%d\n", _float2int(measured_data.acc[0]),
180 }
181 else if (strcasecmp(token, "POS") == 0)
182 {
183 printf("P: X=%ld, Y=%ld, Z=%ld\n", (int32_t)(measured_data.pos[0]),
184 (int32_t)(measured_data.pos[1]), (int32_t)(measured_data.pos[2]));
185 }
186 else if (strcasecmp(token, "ALL") == 0)
187 {
188 printf("G: X=%d, Y=%d, Z=%d\n", _float2int(measured_data.gyr[0]),
190 printf("A: X=%d, Y=%d, Z=%d\n", _float2int(measured_data.acc[0]),
192 printf("P: X=%ld, Y=%ld, Z=%ld\n", (int32_t)(measured_data.pos[0]),
193 (int32_t)(measured_data.pos[1]), (int32_t)(measured_data.pos[2]));
194 }
195 else
196 {
197 printf("Unknown\n");
198 }
199}
200
201/*
202* Function: process_cmd_pulse
203* Purpose: Triggers a pulse with a defined duration.
204* Input(s): cmd - pointer to the string with processed command
205* p_reg - command register, involves
206* information about system state and
207* switching time of valves
208* Returns: none
209*/
210static void process_cmd_pulse(char * token, uint32_t * p_reg)
211{
212 /* During performing another cmd is disable */
213 if (_read_valve(*p_reg))
214 {
215 return;
216 }
217
218 /* Data which will be set to time register */
219 uint8_t time_array[2] = {set_data.time_l, set_data.time_r};
220 uint8_t dir_pointer;
221
222 uint16_t pulse_len;
223 token = strtok(NULL, " ");
224
225 _clr_time(*p_reg);
226
227 if (strcasecmp(token, "RIGHT") == 0)
228 {
229 _set_BV(*p_reg, DIR_BIT);
230 dir_pointer = 1;
231 }
232 else if (strcasecmp(token, "LEFT") == 0)
233 {
234 _clr_BV(*p_reg, DIR_BIT);
235 dir_pointer = 0;
236 }
237 else
238 {
239 printf("Invalid dir\n");
240 return;
241 }
242
243 token = strtok(NULL, " ");
244
245 pulse_len = atoi(token);
246
247 if ((pulse_len >= PULSE_LEN_MIN) && (pulse_len <= PULSE_LEN_MAX))
248 {
249 /* Valid time */
250 /* Arrange time setting only in selected direction */
251 time_array[dir_pointer] = (uint8_t)(pulse_len/PULSE_REPRE);
252 }
253 /* Time opening valve was not specified*/
254 else if (token == NULL)
255 {
256 /* No time setting*/
257 /* Use default time settings */
258 }
259 else
260 {
261 printf("Invalid time\n");
262 return;
263 }
264
265 /* Update time setting*/
266 _set_time(*p_reg, time_array[0], time_array[1]);
267
268 /* Save pulse request */
269 _set_BV(*p_reg, RUN_BIT);
270 _set_BV(*p_reg, PULSE_BIT);
271}
272
273/*
274* Function: process_cmd_autoread
275* Purpose: Enables and disables autoread.
276* Input(s): cmd - pointer to the string with processed command
277* p_reg - command register, involves
278* information about system state and
279* switching time of valves
280* Returns: none
281*/
282static void process_cmd_autoread(char * token, uint32_t * p_reg)
283{
284 token = strtok(NULL, " ");
285
286 if (strcasecmp(token, "ON") == 0)
287 {
288 /* By setting AUTOREAD_BIT, automatic reading will by started */
289 _set_BV(*p_reg, AUTOREAD_BIT);
290 }
291 else if (strcasecmp(token, "OFF") == 0)
292 {
293 _clr_BV(*p_reg, AUTOREAD_BIT);
294 }
295 else
296 {
297 printf("Invalid cmd\n");
298 return;
299 }
300
301}
302
303/*
304* Function: process_cmd_set
305* Purpose: Allows modifying the settings global variable and
306* changing the contents of the autoread report.
307* Input(s): cmd - pointer to the string with processed command
308* p_reg - command register, involves
309* information about system state and
310* switching time of valves
311* Returns: none
312*/
313static void process_cmd_set(char * token, uint32_t * p_reg)
314{
315 token = strtok(NULL, " ");
316
317 if (strcasecmp(token, "READ") == 0)
318 {
319 process_cmd_set_read(token, p_reg);
320 }
321 else if (strcasecmp(token, "AUTO") == 0)
322 {
324 }
325 else if (strcasecmp(token, "TIME") == 0)
326 {
328 }
329 else if (strcasecmp(token, "ANGLE") == 0)
330 {
332 }
333 else if (strcasecmp(token, "HOME") == 0)
334 {
336 }
337 else
338 {
339 printf("Invalid cmd\n");
340 return;
341 }
342}
343
344/*
345* Function: process_cmd_reset
346* Purpose: Clears command register. Closes valves.
347* Input(s): p_reg - command register, involves
348* information about system state and
349* switching time of valves
350* Returns: none
351*/
352static void process_cmd_reset(uint32_t * p_reg)
353{
354 /* Clear cmd register */
355 *p_reg = 0;
356
357 /* Close all valves */
358 HAL_GPIO_WritePin(VALVE_R_GPIO_Port, VALVE_R_Pin, 0);
359 HAL_GPIO_WritePin(VALVE_L_GPIO_Port, VALVE_L_Pin, 0);
360}
361
362/*
363* Function: process_cmd_set_read
364* Purpose: Enables turn on/off autoreport from these sensors.
365* Input(s): cmd - pointer to the string with processed command
366* p_reg - command register, involves
367* information about system state and
368* switching time of valves
369* Returns: none
370*/
371static void process_cmd_set_read(char * token, uint32_t * p_reg)
372{
373 token = strtok(NULL, " ");
374 uint8_t bit;
375
376 /* Select which sensor */
377 if (strcasecmp(token, "ACC") == 0)
378 {
379 bit = AUTOREAD_ACC_BIT;
380 }
381 else if (strcasecmp(token, "GYR") == 0)
382 {
383 bit = AUTOREAD_GYR_BIT;
384 }
385 else if (strcasecmp(token, "POS") == 0)
386 {
387 bit = AUTOREAD_POS_BIT;
388 }
389 else
390 {
391 printf("Invalid cmd\n");
392 return;
393 }
394
395 token = strtok(NULL, " ");
396
397 /* Turn on or turn off report */
398 if (strcasecmp(token, "ON") == 0)
399 {
400 _set_BV(*p_reg, bit);
401 }
402 else if (strcasecmp(token, "OFF") == 0)
403 {
404 _clr_BV(*p_reg, bit);
405 }
406 else
407 {
408 printf("Invalid cmd\n");
409 return;
410 }
411}
412
413/*
414* Function: process_cmd_set_auto
415* Purpose: Enables change the period of autoreading.
416* Input(s): cmd - pointer to the string with processed command
417*
418* Returns: none
419*/
420static void process_cmd_set_auto(char * token)
421{
422 token = strtok(NULL, " ");
423 uint8_t time = atoi(token);
424
425 if ((time != 0) && (time <= MAX_TIME))
426 {
427 set_data.time_a = time;
428 }
429}
430
431/*
432* Function: process_cmd_set_time
433* Purpose: Allows adjusting the valve-opening time settings.
434* Input(s): cmd - pointer to the string with processed command
435*
436* Returns: none
437*/
438static void process_cmd_set_time(char * token)
439{
440 token = strtok(NULL, " ");
441
442 char * dir = token;
443
444 token = strtok(NULL, " ");
445 uint16_t time = atoi(token);
446
447 if ((time >= PULSE_LEN_MIN) && (time <= PULSE_LEN_MAX))
448 {
449 if (strcasecmp(dir, "RIGHT") == 0)
450 {
451 set_data.time_r = (uint8_t)(time/PULSE_REPRE);
452 }
453 else if (strcasecmp(dir, "LEFT") == 0)
454 {
455 set_data.time_l = (uint8_t)(time/PULSE_REPRE);
456 }
457 else if (strcasecmp(dir, "ALL") == 0)
458 {
459 set_data.time_r = (uint8_t)(time/PULSE_REPRE);
460 set_data.time_l = (uint8_t)(time/PULSE_REPRE);
461 }
462 else
463 {
464 printf("Invalid dir\n");
465 return;
466 }
467 }
468}
469
470/*
471* Function: process_cmd_set_angle
472* Purpose: Allows setting the rotation angle for the TURN command.
473* Input(s): cmd - pointer to the string with processed command
474*
475* Returns: none
476*/
477static void process_cmd_set_angle(char * token)
478{
479 token = strtok(NULL, " ");
480 uint8_t angle = atoi(token);
481
482 if ((angle > TURN_ANGLE_MIN) && (angle <= TURN_ANGLE_MAX))
483 {
484 set_data.angle = angle;
485 }
486}
487
488/*
489* Function: process_cmd_set_home
490* Purpose: Allows setting the default orientation for the HOME command.
491* Input(s): cmd - pointer to the string with processed command
492*
493* Returns: none
494*/
495static void process_cmd_set_home(char * token)
496{
497 token = strtok(NULL, " ");
498 int16_t home = atoi(token);
499
500 if (home >= HOME_ANGLE_MIN && home <= HOME_ANGLE_MAX)
501 {
502 set_data.home = home;
503 }
504 else
505 {
506 printf("Invalid position\n");
507 return;
508 }
509}
510
511/*
512* Function: process_cmd_home
513* Purpose: Triggers a home command.
514* Input(s): p_reg - command register, involves
515* information about system state and
516* switching time of valves
517* Returns: none
518*/
519static void process_cmd_home(uint32_t * p_reg)
520{
521 /* During performing another cmd is disable */
522 if (_read_valve(*p_reg))
523 {
524 return;
525 }
526
527 /* Preper time setting */
528 _clr_time(*p_reg);
530
531 /* Save home request */
532 _set_BV(*p_reg, RUN_BIT);
533 _set_BV(*p_reg, HOME_BIT);
534}
535
536/*
537* Function: process_cmd_ncomd
538* Purpose: Reserved.
539* Input(s): cmd - pointer to the string with processed command
540* p_reg - command register, involves
541* information about system state and
542* switching time of valves
543* Returns: none
544*/
545static void process_cmd_ncmd(char * token, uint32_t * p_reg)
546{
547 uint8_t ncmd;
548
549 token = strtok(NULL, " ");
550 ncmd = atoi(token);
551
552 switch (ncmd)
553 {
554 case 0:
555 _tog_BV(*p_reg, CMD0_BIT);
556 break;
557 case 1:
558 _tog_BV(*p_reg, CMD1_BIT);
559 break;
560 case 2:
561 _tog_BV(*p_reg, CMD2_BIT);
562 break;
563 case 3:
564 _tog_BV(*p_reg, CMD3_BIT);
565 break;
566 default:
567 printf("Invalid cmd\n");
568 break;
569 }
570}
571
572
static void process_cmd_set_home(char *token)
static void process_cmd(char *cmd, uint32_t *p_reg)
static void process_cmd_autoread(char *token, uint32_t *p_reg)
static void process_cmd_ncmd(char *token, uint32_t *p_reg)
static void process_cmd_home(uint32_t *p_reg)
static void process_cmd_turn(char *token, uint32_t *p_reg)
static void process_cmd_set_auto(char *token)
static void process_cmd_set_angle(char *token)
static void process_cmd_set_read(char *token, uint32_t *p_reg)
static void process_cmd_set_time(char *token)
static void process_cmd_set(char *token, uint32_t *p_reg)
static void process_cmd_pulse(char *token, uint32_t *p_reg)
static void process_cmd_read(char *token)
static void process_cmd_reset(uint32_t *p_reg)
#define HOME_ANGLE_MAX
#define PULSE_LEN_MIN
settings_t set_data
Main system settings.
Definition main.c:61
sensor_data_t measured_data
Current sensor measured data.
Definition main.c:60
#define TURN_ANGLE_MIN
#define MAX_TIME
void uart_byte_available(uint8_t c, uint32_t *p_reg)
Recognizes commands in the received characters and sets the cmd register accordingly.
#define TURN_ANGLE_MAX
#define HOME_ANGLE_MIN
#define PULSE_LEN_MAX
#define CMD_BUFFER_LEN
: Header for main.c file. This file contains the common defines of the application.
#define _read_valve(reg)
Definition main.h:200
#define AUTOREAD_BIT
Definition main.h:183
#define VALVE_L_Pin
Definition main.h:149
#define _clr_time(reg)
Definition main.h:118
#define DIR_BIT
Definition main.h:165
#define CMD0_BIT
Definition main.h:208
#define CMD1_BIT
Definition main.h:211
#define VALVE_R_Pin
Definition main.h:147
#define _float2int(data_fl)
Definition main.h:133
#define VALVE_R_GPIO_Port
Definition main.h:148
#define RUN_BIT
Definition main.h:162
#define _tog_BV(reg, bit)
Definition main.h:112
#define TURN_BIT
Definition main.h:171
#define _clr_BV(reg, bit)
Definition main.h:109
#define _set_time(reg, time_l, time_r)
Definition main.h:122
#define AUTOREAD_ACC_BIT
Definition main.h:186
#define HOME_BIT
Definition main.h:180
#define CMD3_BIT
Definition main.h:217
#define PULSE_BIT
Definition main.h:168
#define VALVE_L_GPIO_Port
Definition main.h:150
#define AUTOREAD_POS_BIT
Definition main.h:192
#define _set_BV(reg, bit)
Definition main.h:106
#define PULSE_REPRE
Definition main.h:195
#define CMD2_BIT
Definition main.h:214
#define AUTOREAD_GYR_BIT
Definition main.h:189
float pos[3]
Orientation X, Y, Z [deg]; related to initial position.
Definition main.h:82
float gyr[3]
Gyroscope X, Y, Z [dps].
Definition main.h:80
float acc[3]
Accelerometer X, Y, Z [g].
Definition main.h:79
uint8_t time_r
Time [10*ms], right valve is open.
Definition main.h:88
uint8_t angle
Angle [deg], cube rotate after turn cmd.
Definition main.h:87
int16_t home
Angle [deg], default orientation.
Definition main.h:91
uint8_t time_l
Time [10*ms], left valve is open.
Definition main.h:89
uint8_t time_a
Period [100*ms], sensor report will be sended.
Definition main.h:90