2016-05-25 18:37:40 +03:00
|
|
|
#ifndef __COMMAND_H
|
|
|
|
#define __COMMAND_H
|
|
|
|
|
2017-06-16 20:57:11 +03:00
|
|
|
#include <stdarg.h> // va_list
|
2017-05-25 23:54:31 +03:00
|
|
|
#include <stddef.h>
|
2016-05-25 18:37:40 +03:00
|
|
|
#include <stdint.h> // uint8_t
|
2017-05-25 23:54:31 +03:00
|
|
|
#include "ctr.h" // DECL_CTR
|
2016-05-25 18:37:40 +03:00
|
|
|
|
|
|
|
// Declare a function to run when the specified command is received
|
2019-08-22 20:26:30 +03:00
|
|
|
#define DECL_COMMAND_FLAGS(FUNC, FLAGS, MSG) \
|
|
|
|
DECL_CTR("DECL_COMMAND_FLAGS " __stringify(FUNC) " " \
|
|
|
|
__stringify(FLAGS) " " MSG)
|
2016-05-25 18:37:40 +03:00
|
|
|
#define DECL_COMMAND(FUNC, MSG) \
|
2019-03-05 07:24:43 +03:00
|
|
|
DECL_COMMAND_FLAGS(FUNC, 0, MSG)
|
2016-05-25 18:37:40 +03:00
|
|
|
|
|
|
|
// Flags for command handler declarations.
|
|
|
|
#define HF_IN_SHUTDOWN 0x01 // Handler can run even when in emergency stop
|
|
|
|
|
2016-12-23 07:47:46 +03:00
|
|
|
// Declare a constant exported to the host
|
2019-08-22 19:12:21 +03:00
|
|
|
#define DECL_CONSTANT(NAME, VALUE) \
|
2019-08-22 20:26:30 +03:00
|
|
|
DECL_CTR_INT("DECL_CONSTANT " NAME, 1, CTR_INT(VALUE))
|
2019-03-05 07:24:43 +03:00
|
|
|
#define DECL_CONSTANT_STR(NAME, VALUE) \
|
2019-08-22 20:26:30 +03:00
|
|
|
DECL_CTR("DECL_CONSTANT_STR " NAME " " VALUE)
|
2016-12-23 07:47:46 +03:00
|
|
|
|
2019-03-05 20:42:35 +03:00
|
|
|
// Declare an enumeration
|
2019-08-22 19:12:21 +03:00
|
|
|
#define DECL_ENUMERATION(ENUM, NAME, VALUE) \
|
2019-08-22 20:26:30 +03:00
|
|
|
DECL_CTR_INT("DECL_ENUMERATION " ENUM " " NAME, 1, CTR_INT(VALUE))
|
2019-03-05 20:42:35 +03:00
|
|
|
#define DECL_ENUMERATION_RANGE(ENUM, NAME, VALUE, COUNT) \
|
2019-08-22 20:26:30 +03:00
|
|
|
DECL_CTR_INT("DECL_ENUMERATION_RANGE " ENUM " " NAME, \
|
2019-08-22 19:15:44 +03:00
|
|
|
2, CTR_INT(VALUE), CTR_INT(COUNT))
|
2019-03-05 20:42:35 +03:00
|
|
|
|
2016-05-25 18:37:40 +03:00
|
|
|
// Send an output message (and declare a static message type for it)
|
|
|
|
#define output(FMT, args...) \
|
2017-06-16 20:57:11 +03:00
|
|
|
command_sendf(_DECL_OUTPUT(FMT) , ##args )
|
2016-05-25 18:37:40 +03:00
|
|
|
|
|
|
|
// Declare a message type and transmit it.
|
|
|
|
#define sendf(FMT, args...) \
|
2017-06-16 20:57:11 +03:00
|
|
|
command_sendf(_DECL_ENCODER(FMT) , ##args )
|
2016-05-25 18:37:40 +03:00
|
|
|
|
|
|
|
// Shut down the machine (also declares a static string to transmit)
|
|
|
|
#define shutdown(msg) \
|
|
|
|
sched_shutdown(_DECL_STATIC_STR(msg))
|
|
|
|
#define try_shutdown(msg) \
|
|
|
|
sched_try_shutdown(_DECL_STATIC_STR(msg))
|
|
|
|
|
2017-06-30 01:14:39 +03:00
|
|
|
#define MESSAGE_MIN 5
|
|
|
|
#define MESSAGE_MAX 64
|
|
|
|
#define MESSAGE_HEADER_SIZE 2
|
|
|
|
#define MESSAGE_TRAILER_SIZE 3
|
|
|
|
#define MESSAGE_POS_LEN 0
|
|
|
|
#define MESSAGE_POS_SEQ 1
|
|
|
|
#define MESSAGE_TRAILER_CRC 3
|
|
|
|
#define MESSAGE_TRAILER_SYNC 1
|
|
|
|
#define MESSAGE_PAYLOAD_MAX (MESSAGE_MAX - MESSAGE_MIN)
|
|
|
|
#define MESSAGE_SEQ_MASK 0x0f
|
|
|
|
#define MESSAGE_DEST 0x10
|
|
|
|
#define MESSAGE_SYNC 0x7E
|
|
|
|
|
2016-05-25 18:37:40 +03:00
|
|
|
struct command_encoder {
|
|
|
|
uint8_t msg_id, max_size, num_params;
|
|
|
|
const uint8_t *param_types;
|
|
|
|
};
|
|
|
|
struct command_parser {
|
|
|
|
uint8_t msg_id, num_args, flags, num_params;
|
|
|
|
const uint8_t *param_types;
|
|
|
|
void (*func)(uint32_t *args);
|
|
|
|
};
|
|
|
|
enum {
|
|
|
|
PT_uint32, PT_int32, PT_uint16, PT_int16, PT_byte,
|
|
|
|
PT_string, PT_progmem_buffer, PT_buffer,
|
|
|
|
};
|
2017-06-16 20:57:11 +03:00
|
|
|
|
|
|
|
// command.c
|
2020-10-30 06:54:17 +03:00
|
|
|
void *command_decode_ptr(uint32_t v);
|
2018-05-24 19:49:23 +03:00
|
|
|
uint8_t *command_parsef(uint8_t *p, uint8_t *maxend
|
|
|
|
, const struct command_parser *cp, uint32_t *args);
|
2018-05-24 20:07:43 +03:00
|
|
|
uint_fast8_t command_encode_and_frame(
|
|
|
|
uint8_t *buf, const struct command_encoder *ce, va_list args);
|
|
|
|
void command_sendf(const struct command_encoder *ce, ...);
|
2018-05-24 19:49:23 +03:00
|
|
|
int_fast8_t command_find_block(uint8_t *buf, uint_fast8_t buf_len
|
|
|
|
, uint_fast8_t *pop_count);
|
|
|
|
void command_dispatch(uint8_t *buf, uint_fast8_t msglen);
|
2018-05-24 20:30:24 +03:00
|
|
|
void command_send_ack(void);
|
2018-05-24 20:18:03 +03:00
|
|
|
int_fast8_t command_find_and_dispatch(uint8_t *buf, uint_fast8_t buf_len
|
|
|
|
, uint_fast8_t *pop_count);
|
2017-06-16 20:57:11 +03:00
|
|
|
|
|
|
|
// out/compile_time_request.c (auto generated file)
|
2017-05-26 20:20:20 +03:00
|
|
|
extern const struct command_parser command_index[];
|
2016-05-25 18:37:40 +03:00
|
|
|
extern const uint8_t command_index_size;
|
|
|
|
extern const uint8_t command_identify_data[];
|
|
|
|
extern const uint32_t command_identify_size;
|
2017-05-25 23:54:31 +03:00
|
|
|
const struct command_encoder *ctr_lookup_encoder(const char *str);
|
|
|
|
const struct command_encoder *ctr_lookup_output(const char *str);
|
|
|
|
uint8_t ctr_lookup_static_string(const char *str);
|
2016-05-25 18:37:40 +03:00
|
|
|
|
2017-05-25 23:54:31 +03:00
|
|
|
#define _DECL_ENCODER(FMT) ({ \
|
|
|
|
DECL_CTR("_DECL_ENCODER " FMT); \
|
|
|
|
ctr_lookup_encoder(FMT); })
|
2016-05-25 18:37:40 +03:00
|
|
|
|
2017-05-25 23:54:31 +03:00
|
|
|
#define _DECL_OUTPUT(FMT) ({ \
|
|
|
|
DECL_CTR("_DECL_OUTPUT " FMT); \
|
|
|
|
ctr_lookup_output(FMT); })
|
2016-05-25 18:37:40 +03:00
|
|
|
|
2017-05-25 23:54:31 +03:00
|
|
|
#define _DECL_STATIC_STR(MSG) ({ \
|
|
|
|
DECL_CTR("_DECL_STATIC_STR " MSG); \
|
|
|
|
ctr_lookup_static_string(MSG); })
|
2016-05-25 18:37:40 +03:00
|
|
|
|
|
|
|
#endif // command.h
|