add a complete rc_proto stack (not tested)
[protos/xbee-avr.git] / rc_proto.h
index 868f921..2a2a666 100644 (file)
@@ -6,8 +6,9 @@ struct rc_proto_hdr {
        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; /* len of data excluding header */
@@ -15,48 +16,119 @@ struct rc_proto_hello {
 } __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;
+       int8_t power;
        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; /* 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
-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 */
-};
-
 /* acknowledge a servo command */
-#define RC_PROTO_ACK 5
+#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 data[];
+};
+
+/* send stats */
+#define RC_PROTO_STATS 0x06
+struct rc_proto_stats {
+       uint8_t type;
+       uint8_t stats[]; /* format is struct rc_proto_stats_data */
+} __attribute__((packed));
 
 /* send a Hello message to a peer */
-int8_t rc_proto_send_hello(uint64_t addr, void *data, uint8_t data_len);
+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);
 
+/* dmp statistics related to rc_proto */
+void rc_proto_dump_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
+
+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