uint8_t type;
} __attribute__((packed));
+
/* send a hello message, no answer is expected from the peer */
-#define RC_PROTO_HELLO 0
+#define RC_PROTO_HELLO 0x00
struct rc_proto_hello {
uint8_t type;
- uint8_t datalen;
+ uint8_t datalen; /* len of data excluding header */
uint8_t data[];
} __attribute__((packed));
/* send an echo request, expect an echo reply from the peer */
-#define RC_PROTO_ECHO_REQ 1
+#define RC_PROTO_ECHO_REQ 0x01
struct rc_proto_echo_req {
uint8_t type;
- uint8_t datalen;
+ int8_t power;
+ uint16_t timestamp; /* copied as-is in answer */
+ uint8_t datalen; /* len of data excluding header */
uint8_t data[];
} __attribute__((packed));
/* reply to an echo request */
-#define RC_PROTO_ECHO_ANS 2
+#define RC_PROTO_ECHO_ANS 0x02
struct rc_proto_echo_ans {
uint8_t type;
- uint8_t datalen;
+ uint16_t timestamp;
+ uint8_t datalen; /* len of data excluding header */
uint8_t data[];
} __attribute__((packed));
-/* send a power level probe to the peer */
-#define RC_PROTO_POWER_PROBE 3
+/* send a power level probe to the peer: no answer is expected, but the peer
+ * will know that a packet with this power-level is received. It can also ask
+ * the RSSI of this packet. */
+#define RC_PROTO_POWER_PROBE 0x03
struct rc_proto_power_probe {
uint8_t type;
uint8_t power_level;
} __attribute__((packed));
-/* send a servo command */
-#define RC_PROTO_SERVO 4
+/* acknowledge a servo command */
+#define RC_PROTO_ACK 0x04
+struct rc_proto_ack {
+ uint8_t type;
+ uint8_t seq;
+} __attribute__((packed));
+
+/*
+ * If type < 0x3f, it's a servo command. The size of the message is critical
+ * because it's send very often. The "type" field contains the bitfield of
+ * servos present in the body of the message. A sequence number (5bits) and the
+ * power level (3 bits) are also sent. The servos are listed as 10bits fields,
+ * without padding.
+ *
+ * Example: we send servo 0 (=0x123) and servo 3 (=0x234). Power = 2.
+ * command type (RC_PROTO_SERVO)
+ * power_level = 0 (3 bits, LSB) \
+ * bypass = 0 (1 bit) > one byte
+ * seq = 1 (4 bits, MSB) /
+ * servo_val[0]=0x123
+ * servo_val[1]=0x234
+ * servo_val[2]=0x321
+ * servo_val[3]=0x123
+ * servo_val[4]=0x234
+ * servo_val[5]=0x321
+ *
+ * -> 0x05 0x10 0x48 0xe3 0x4c 0x85 0x23 0x8d 0x32 0x10
+ * type psb |ser0 ser1 ser2 ser3 |ser4 ser5
+ */
+#define RC_PROTO_SERVO 0x05
+#define RC_PROTO_SERVO_LEN 10 /* len of frame */
struct rc_proto_servo {
uint8_t type;
- uint8_t mask;
- uint8_t seq_and_pow; /* bitfield: pow are the 3 lsb, seq the 5 msb */
+ uint8_t data[];
};
-/* acknowledge a servo command */
-#define RC_PROTO_ACK 5
-struct rc_proto_ack {
+/* send stats */
+#define RC_PROTO_STATS 0x06
+struct rc_proto_stats {
uint8_t type;
- uint8_t seq;
+ uint8_t stats[]; /* format is struct rc_proto_stats_data */
} __attribute__((packed));
-void rc_proto_rx_range(int power_level);
+/* rc_proto timers configuration */
+struct rc_proto_timers {
+ uint16_t send_servo_min_ms;
+ uint16_t send_servo_max_ms;
+ uint16_t send_power_probe_ms;
+ uint16_t autobypass_ms;
+};
+extern struct rc_proto_timers rc_proto_timers;
+
+/* send a Hello message to a peer */
+int8_t rc_proto_send_hello(uint64_t addr, void *data, uint8_t data_len,
+ int8_t power);
+
+int8_t rc_proto_send_echo_req(uint64_t addr, void *data, uint8_t data_len,
+ int8_t power);
+
+/* reception of a xbee message */
+int rc_proto_rx(struct xbee_recv_hdr *recvframe, unsigned len);
+
+/* dump statistics related to rc_proto */
+void rc_proto_dump_stats(void);
+
+/* reset statistics related to rc_proto */
+void rc_proto_reset_stats(void);
+
+/* set the peer xbee address */
+void rc_proto_set_dstaddr(uint64_t addr);
+
+/* get the peer xbee address */
+uint64_t rc_proto_get_dstaddr(void);
+
+void rc_proto_dump_servos(void);
+
+/* tx mode */
+#define RC_PROTO_FLAGS_TX_OFF 0x00
+#define RC_PROTO_FLAGS_TX_BYPASS 0x01
+#define RC_PROTO_FLAGS_TX_COPY_SPI 0x02
+#define RC_PROTO_FLAGS_TX_RESERVED 0x03
+#define RC_PROTO_FLAGS_TX_MASK 0x03
+
+/* if set, copy received servo values to SPI */
+#define RC_PROTO_FLAGS_RX_COPY_SPI 0x04
+
+/* if set, switch to bypass when no servo is received during some time */
+#define RC_PROTO_FLAGS_RX_AUTOBYPASS 0x08
+
+/* if set, send stats periodically to the peer (1 sec) */
+#define RC_PROTO_FLAGS_TX_STATS 0x10
+
+/* if set, send power probe periodically to the peer (500 ms) */
+#define RC_PROTO_FLAGS_TX_POW_PROBE 0x20
+
+/* if set, use received probes to compute best power level */
+#define RC_PROTO_FLAGS_COMPUTE_BEST_POW 0x40
+
+void rc_proto_set_mode(uint8_t flags);
+
+uint8_t rc_proto_get_mode(void);
+
+/* initialize rc_proto module */
+void rc_proto_init(void);
#endif