Code for autonomous ground vehicle, Data Bus, 3rd place winner in 2012 Sparkfun AVC.

Dependencies:   Watchdog mbed Schedule SimpleFilter LSM303DLM PinDetect DebounceIn Servo

Committer:
shimniok
Date:
Wed Jun 20 14:57:48 2012 +0000
Revision:
0:826c6171fc1b
Updated documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shimniok 0:826c6171fc1b 1 #ifndef _MAVLINK_PROTOCOL_H_
shimniok 0:826c6171fc1b 2 #define _MAVLINK_PROTOCOL_H_
shimniok 0:826c6171fc1b 3
shimniok 0:826c6171fc1b 4 #include "string.h"
shimniok 0:826c6171fc1b 5 #include "checksum.h"
shimniok 0:826c6171fc1b 6
shimniok 0:826c6171fc1b 7 #include "mavlink_types.h"
shimniok 0:826c6171fc1b 8
shimniok 0:826c6171fc1b 9
shimniok 0:826c6171fc1b 10 /**
shimniok 0:826c6171fc1b 11 * @brief Initialize the communication stack
shimniok 0:826c6171fc1b 12 *
shimniok 0:826c6171fc1b 13 * This function has to be called before using commParseBuffer() to initialize the different status registers.
shimniok 0:826c6171fc1b 14 *
shimniok 0:826c6171fc1b 15 * @return Will initialize the different buffers and status registers.
shimniok 0:826c6171fc1b 16 */
shimniok 0:826c6171fc1b 17 static void mavlink_parse_state_initialize(mavlink_status_t* initStatus)
shimniok 0:826c6171fc1b 18 {
shimniok 0:826c6171fc1b 19 if ((initStatus->parse_state <= MAVLINK_PARSE_STATE_UNINIT) || (initStatus->parse_state > MAVLINK_PARSE_STATE_GOT_CRC1))
shimniok 0:826c6171fc1b 20 {
shimniok 0:826c6171fc1b 21 initStatus->ck_a = 0;
shimniok 0:826c6171fc1b 22 initStatus->ck_b = 0;
shimniok 0:826c6171fc1b 23 initStatus->msg_received = 0;
shimniok 0:826c6171fc1b 24 initStatus->buffer_overrun = 0;
shimniok 0:826c6171fc1b 25 initStatus->parse_error = 0;
shimniok 0:826c6171fc1b 26 initStatus->parse_state = MAVLINK_PARSE_STATE_UNINIT;
shimniok 0:826c6171fc1b 27 initStatus->packet_idx = 0;
shimniok 0:826c6171fc1b 28 initStatus->packet_rx_drop_count = 0;
shimniok 0:826c6171fc1b 29 initStatus->packet_rx_success_count = 0;
shimniok 0:826c6171fc1b 30 initStatus->current_rx_seq = 0;
shimniok 0:826c6171fc1b 31 initStatus->current_tx_seq = 0;
shimniok 0:826c6171fc1b 32 }
shimniok 0:826c6171fc1b 33 }
shimniok 0:826c6171fc1b 34
shimniok 0:826c6171fc1b 35 static inline mavlink_status_t* mavlink_get_channel_status(uint8_t chan)
shimniok 0:826c6171fc1b 36 {
shimniok 0:826c6171fc1b 37 static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 38 return &m_mavlink_status[chan];
shimniok 0:826c6171fc1b 39 }
shimniok 0:826c6171fc1b 40
shimniok 0:826c6171fc1b 41 /**
shimniok 0:826c6171fc1b 42 * @brief Finalize a MAVLink message with MAVLINK_COMM_0 as default channel
shimniok 0:826c6171fc1b 43 *
shimniok 0:826c6171fc1b 44 * This function calculates the checksum and sets length and aircraft id correctly.
shimniok 0:826c6171fc1b 45 * It assumes that the message id and the payload are already correctly set.
shimniok 0:826c6171fc1b 46 *
shimniok 0:826c6171fc1b 47 * @warning This function implicitely assumes the message is sent over channel zero.
shimniok 0:826c6171fc1b 48 * if the message is sent over a different channel it will reach the receiver
shimniok 0:826c6171fc1b 49 * without error, BUT the sequence number might be wrong due to the wrong
shimniok 0:826c6171fc1b 50 * channel sequence counter. This will result is wrongly reported excessive
shimniok 0:826c6171fc1b 51 * packet loss. Please use @see mavlink_{pack|encode}_headerless and then
shimniok 0:826c6171fc1b 52 * @see mavlink_finalize_message_chan before sending for a correct channel
shimniok 0:826c6171fc1b 53 * assignment. Please note that the mavlink_msg_xxx_pack and encode functions
shimniok 0:826c6171fc1b 54 * assign channel zero as default and thus induce possible loss counter errors.\
shimniok 0:826c6171fc1b 55 * They have been left to ensure code compatibility.
shimniok 0:826c6171fc1b 56 *
shimniok 0:826c6171fc1b 57 * @see mavlink_finalize_message_chan
shimniok 0:826c6171fc1b 58 * @param msg Message to finalize
shimniok 0:826c6171fc1b 59 * @param system_id Id of the sending (this) system, 1-127
shimniok 0:826c6171fc1b 60 * @param length Message length, usually just the counter incremented while packing the message
shimniok 0:826c6171fc1b 61 */
shimniok 0:826c6171fc1b 62 static inline uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id, uint16_t length)
shimniok 0:826c6171fc1b 63 {
shimniok 0:826c6171fc1b 64 // This code part is the same for all messages;
shimniok 0:826c6171fc1b 65 uint16_t checksum;
shimniok 0:826c6171fc1b 66 msg->len = length;
shimniok 0:826c6171fc1b 67 msg->sysid = system_id;
shimniok 0:826c6171fc1b 68 msg->compid = component_id;
shimniok 0:826c6171fc1b 69 // One sequence number per component
shimniok 0:826c6171fc1b 70 msg->seq = mavlink_get_channel_status(MAVLINK_COMM_0)->current_tx_seq;
shimniok 0:826c6171fc1b 71 mavlink_get_channel_status(MAVLINK_COMM_0)->current_tx_seq = mavlink_get_channel_status(MAVLINK_COMM_0)->current_tx_seq+1;
shimniok 0:826c6171fc1b 72 checksum = crc_calculate((uint8_t*)((void*)msg), length + MAVLINK_CORE_HEADER_LEN);
shimniok 0:826c6171fc1b 73 msg->ck_a = (uint8_t)(checksum & 0xFF); ///< High byte
shimniok 0:826c6171fc1b 74 msg->ck_b = (uint8_t)(checksum >> 8); ///< Low byte
shimniok 0:826c6171fc1b 75
shimniok 0:826c6171fc1b 76 return length + MAVLINK_NUM_NON_STX_PAYLOAD_BYTES;
shimniok 0:826c6171fc1b 77 }
shimniok 0:826c6171fc1b 78
shimniok 0:826c6171fc1b 79 /**
shimniok 0:826c6171fc1b 80 * @brief Finalize a MAVLink message with channel assignment
shimniok 0:826c6171fc1b 81 *
shimniok 0:826c6171fc1b 82 * This function calculates the checksum and sets length and aircraft id correctly.
shimniok 0:826c6171fc1b 83 * It assumes that the message id and the payload are already correctly set. This function
shimniok 0:826c6171fc1b 84 * can also be used if the message header has already been written before (as in mavlink_msg_xxx_pack
shimniok 0:826c6171fc1b 85 * instead of mavlink_msg_xxx_pack_headerless), it just introduces little extra overhead.
shimniok 0:826c6171fc1b 86 *
shimniok 0:826c6171fc1b 87 * @param msg Message to finalize
shimniok 0:826c6171fc1b 88 * @param system_id Id of the sending (this) system, 1-127
shimniok 0:826c6171fc1b 89 * @param length Message length, usually just the counter incremented while packing the message
shimniok 0:826c6171fc1b 90 */
shimniok 0:826c6171fc1b 91 static inline uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id, uint8_t chan, uint16_t length)
shimniok 0:826c6171fc1b 92 {
shimniok 0:826c6171fc1b 93 // This code part is the same for all messages;
shimniok 0:826c6171fc1b 94 uint16_t checksum;
shimniok 0:826c6171fc1b 95 msg->len = length;
shimniok 0:826c6171fc1b 96 msg->sysid = system_id;
shimniok 0:826c6171fc1b 97 msg->compid = component_id;
shimniok 0:826c6171fc1b 98 // One sequence number per component
shimniok 0:826c6171fc1b 99 msg->seq = mavlink_get_channel_status(chan)->current_tx_seq;
shimniok 0:826c6171fc1b 100 mavlink_get_channel_status(chan)->current_tx_seq = mavlink_get_channel_status(chan)->current_tx_seq+1;
shimniok 0:826c6171fc1b 101 checksum = crc_calculate((uint8_t*)((void*)msg), length + MAVLINK_CORE_HEADER_LEN);
shimniok 0:826c6171fc1b 102 msg->ck_a = (uint8_t)(checksum & 0xFF); ///< High byte
shimniok 0:826c6171fc1b 103 msg->ck_b = (uint8_t)(checksum >> 8); ///< Low byte
shimniok 0:826c6171fc1b 104
shimniok 0:826c6171fc1b 105 return length + MAVLINK_NUM_NON_STX_PAYLOAD_BYTES;
shimniok 0:826c6171fc1b 106 }
shimniok 0:826c6171fc1b 107
shimniok 0:826c6171fc1b 108 /**
shimniok 0:826c6171fc1b 109 * @brief Pack a message to send it over a serial byte stream
shimniok 0:826c6171fc1b 110 */
shimniok 0:826c6171fc1b 111 static inline uint16_t mavlink_msg_to_send_buffer(uint8_t* buffer, const mavlink_message_t* msg)
shimniok 0:826c6171fc1b 112 {
shimniok 0:826c6171fc1b 113 *(buffer+0) = MAVLINK_STX; ///< Start transmit
shimniok 0:826c6171fc1b 114 memcpy((buffer+1), msg, msg->len + MAVLINK_CORE_HEADER_LEN); ///< Core header plus payload
shimniok 0:826c6171fc1b 115 *(buffer + msg->len + MAVLINK_CORE_HEADER_LEN + 1) = msg->ck_a;
shimniok 0:826c6171fc1b 116 *(buffer + msg->len + MAVLINK_CORE_HEADER_LEN + 2) = msg->ck_b;
shimniok 0:826c6171fc1b 117 return msg->len + MAVLINK_NUM_NON_PAYLOAD_BYTES;
shimniok 0:826c6171fc1b 118 //return 0;
shimniok 0:826c6171fc1b 119 }
shimniok 0:826c6171fc1b 120
shimniok 0:826c6171fc1b 121 /**
shimniok 0:826c6171fc1b 122 * @brief Get the required buffer size for this message
shimniok 0:826c6171fc1b 123 */
shimniok 0:826c6171fc1b 124 static inline uint16_t mavlink_msg_get_send_buffer_length(const mavlink_message_t* msg)
shimniok 0:826c6171fc1b 125 {
shimniok 0:826c6171fc1b 126 return msg->len + MAVLINK_NUM_NON_PAYLOAD_BYTES;
shimniok 0:826c6171fc1b 127 }
shimniok 0:826c6171fc1b 128
shimniok 0:826c6171fc1b 129 union checksum_ {
shimniok 0:826c6171fc1b 130 uint16_t s;
shimniok 0:826c6171fc1b 131 uint8_t c[2];
shimniok 0:826c6171fc1b 132 };
shimniok 0:826c6171fc1b 133
shimniok 0:826c6171fc1b 134 union __mavlink_bitfield {
shimniok 0:826c6171fc1b 135 uint8_t uint8;
shimniok 0:826c6171fc1b 136 int8_t int8;
shimniok 0:826c6171fc1b 137 uint16_t uint16;
shimniok 0:826c6171fc1b 138 int16_t int16;
shimniok 0:826c6171fc1b 139 uint32_t uint32;
shimniok 0:826c6171fc1b 140 int32_t int32;
shimniok 0:826c6171fc1b 141 };
shimniok 0:826c6171fc1b 142
shimniok 0:826c6171fc1b 143
shimniok 0:826c6171fc1b 144 static inline void mavlink_start_checksum(mavlink_message_t* msg)
shimniok 0:826c6171fc1b 145 {
shimniok 0:826c6171fc1b 146 union checksum_ ck;
shimniok 0:826c6171fc1b 147 crc_init(&(ck.s));
shimniok 0:826c6171fc1b 148 msg->ck_a = ck.c[0];
shimniok 0:826c6171fc1b 149 msg->ck_b = ck.c[1];
shimniok 0:826c6171fc1b 150 }
shimniok 0:826c6171fc1b 151
shimniok 0:826c6171fc1b 152 static inline void mavlink_update_checksum(mavlink_message_t* msg, uint8_t c)
shimniok 0:826c6171fc1b 153 {
shimniok 0:826c6171fc1b 154 union checksum_ ck;
shimniok 0:826c6171fc1b 155 ck.c[0] = msg->ck_a;
shimniok 0:826c6171fc1b 156 ck.c[1] = msg->ck_b;
shimniok 0:826c6171fc1b 157 crc_accumulate(c, &(ck.s));
shimniok 0:826c6171fc1b 158 msg->ck_a = ck.c[0];
shimniok 0:826c6171fc1b 159 msg->ck_b = ck.c[1];
shimniok 0:826c6171fc1b 160 }
shimniok 0:826c6171fc1b 161
shimniok 0:826c6171fc1b 162 /**
shimniok 0:826c6171fc1b 163 * This is a convenience function which handles the complete MAVLink parsing.
shimniok 0:826c6171fc1b 164 * the function will parse one byte at a time and return the complete packet once
shimniok 0:826c6171fc1b 165 * it could be successfully decoded. Checksum and other failures will be silently
shimniok 0:826c6171fc1b 166 * ignored.
shimniok 0:826c6171fc1b 167 *
shimniok 0:826c6171fc1b 168 * @param chan ID of the current channel. This allows to parse different channels with this function.
shimniok 0:826c6171fc1b 169 * a channel is not a physical message channel like a serial port, but a logic partition of
shimniok 0:826c6171fc1b 170 * the communication streams in this case. COMM_NB is the limit for the number of channels
shimniok 0:826c6171fc1b 171 * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
shimniok 0:826c6171fc1b 172 * @param c The char to barse
shimniok 0:826c6171fc1b 173 *
shimniok 0:826c6171fc1b 174 * @param returnMsg NULL if no message could be decoded, the message data else
shimniok 0:826c6171fc1b 175 * @return 0 if no message could be decoded, 1 else
shimniok 0:826c6171fc1b 176 *
shimniok 0:826c6171fc1b 177 * A typical use scenario of this function call is:
shimniok 0:826c6171fc1b 178 *
shimniok 0:826c6171fc1b 179 * @code
shimniok 0:826c6171fc1b 180 * #include <inttypes.h> // For fixed-width uint8_t type
shimniok 0:826c6171fc1b 181 *
shimniok 0:826c6171fc1b 182 * mavlink_message_t msg;
shimniok 0:826c6171fc1b 183 * int chan = 0;
shimniok 0:826c6171fc1b 184 *
shimniok 0:826c6171fc1b 185 *
shimniok 0:826c6171fc1b 186 * while(serial.bytesAvailable > 0)
shimniok 0:826c6171fc1b 187 * {
shimniok 0:826c6171fc1b 188 * uint8_t byte = serial.getNextByte();
shimniok 0:826c6171fc1b 189 * if (mavlink_parse_char(chan, byte, &msg))
shimniok 0:826c6171fc1b 190 * {
shimniok 0:826c6171fc1b 191 * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
shimniok 0:826c6171fc1b 192 * }
shimniok 0:826c6171fc1b 193 * }
shimniok 0:826c6171fc1b 194 *
shimniok 0:826c6171fc1b 195 *
shimniok 0:826c6171fc1b 196 * @endcode
shimniok 0:826c6171fc1b 197 */
shimniok 0:826c6171fc1b 198 static inline uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
shimniok 0:826c6171fc1b 199 {
shimniok 0:826c6171fc1b 200 static mavlink_message_t m_mavlink_message[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 201
shimniok 0:826c6171fc1b 202 // Initializes only once, values keep unchanged after first initialization
shimniok 0:826c6171fc1b 203 mavlink_parse_state_initialize(mavlink_get_channel_status(chan));
shimniok 0:826c6171fc1b 204
shimniok 0:826c6171fc1b 205 mavlink_message_t* rxmsg = &m_mavlink_message[chan]; ///< The currently decoded message
shimniok 0:826c6171fc1b 206 mavlink_status_t* status = mavlink_get_channel_status(chan); ///< The current decode status
shimniok 0:826c6171fc1b 207 int bufferIndex = 0;
shimniok 0:826c6171fc1b 208
shimniok 0:826c6171fc1b 209 status->msg_received = 0;
shimniok 0:826c6171fc1b 210
shimniok 0:826c6171fc1b 211 switch (status->parse_state)
shimniok 0:826c6171fc1b 212 {
shimniok 0:826c6171fc1b 213 case MAVLINK_PARSE_STATE_UNINIT:
shimniok 0:826c6171fc1b 214 case MAVLINK_PARSE_STATE_IDLE:
shimniok 0:826c6171fc1b 215 if (c == MAVLINK_STX)
shimniok 0:826c6171fc1b 216 {
shimniok 0:826c6171fc1b 217 status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
shimniok 0:826c6171fc1b 218 mavlink_start_checksum(rxmsg);
shimniok 0:826c6171fc1b 219 }
shimniok 0:826c6171fc1b 220 break;
shimniok 0:826c6171fc1b 221
shimniok 0:826c6171fc1b 222 case MAVLINK_PARSE_STATE_GOT_STX:
shimniok 0:826c6171fc1b 223 if (status->msg_received)
shimniok 0:826c6171fc1b 224 {
shimniok 0:826c6171fc1b 225 status->buffer_overrun++;
shimniok 0:826c6171fc1b 226 status->parse_error++;
shimniok 0:826c6171fc1b 227 status->msg_received = 0;
shimniok 0:826c6171fc1b 228 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 229 }
shimniok 0:826c6171fc1b 230 else
shimniok 0:826c6171fc1b 231 {
shimniok 0:826c6171fc1b 232 // NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2
shimniok 0:826c6171fc1b 233 rxmsg->len = c;
shimniok 0:826c6171fc1b 234 status->packet_idx = 0;
shimniok 0:826c6171fc1b 235 mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 236 status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH;
shimniok 0:826c6171fc1b 237 }
shimniok 0:826c6171fc1b 238 break;
shimniok 0:826c6171fc1b 239
shimniok 0:826c6171fc1b 240 case MAVLINK_PARSE_STATE_GOT_LENGTH:
shimniok 0:826c6171fc1b 241 rxmsg->seq = c;
shimniok 0:826c6171fc1b 242 mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 243 status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ;
shimniok 0:826c6171fc1b 244 break;
shimniok 0:826c6171fc1b 245
shimniok 0:826c6171fc1b 246 case MAVLINK_PARSE_STATE_GOT_SEQ:
shimniok 0:826c6171fc1b 247 rxmsg->sysid = c;
shimniok 0:826c6171fc1b 248 mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 249 status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID;
shimniok 0:826c6171fc1b 250 break;
shimniok 0:826c6171fc1b 251
shimniok 0:826c6171fc1b 252 case MAVLINK_PARSE_STATE_GOT_SYSID:
shimniok 0:826c6171fc1b 253 rxmsg->compid = c;
shimniok 0:826c6171fc1b 254 mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 255 status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID;
shimniok 0:826c6171fc1b 256 break;
shimniok 0:826c6171fc1b 257
shimniok 0:826c6171fc1b 258 case MAVLINK_PARSE_STATE_GOT_COMPID:
shimniok 0:826c6171fc1b 259 rxmsg->msgid = c;
shimniok 0:826c6171fc1b 260 mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 261 if (rxmsg->len == 0)
shimniok 0:826c6171fc1b 262 {
shimniok 0:826c6171fc1b 263 status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
shimniok 0:826c6171fc1b 264 }
shimniok 0:826c6171fc1b 265 else
shimniok 0:826c6171fc1b 266 {
shimniok 0:826c6171fc1b 267 status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID;
shimniok 0:826c6171fc1b 268 }
shimniok 0:826c6171fc1b 269 break;
shimniok 0:826c6171fc1b 270
shimniok 0:826c6171fc1b 271 case MAVLINK_PARSE_STATE_GOT_MSGID:
shimniok 0:826c6171fc1b 272 rxmsg->payload[status->packet_idx++] = c;
shimniok 0:826c6171fc1b 273 mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 274 if (status->packet_idx == rxmsg->len)
shimniok 0:826c6171fc1b 275 {
shimniok 0:826c6171fc1b 276 status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
shimniok 0:826c6171fc1b 277 }
shimniok 0:826c6171fc1b 278 break;
shimniok 0:826c6171fc1b 279
shimniok 0:826c6171fc1b 280 case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
shimniok 0:826c6171fc1b 281 if (c != rxmsg->ck_a)
shimniok 0:826c6171fc1b 282 {
shimniok 0:826c6171fc1b 283 // Check first checksum byte
shimniok 0:826c6171fc1b 284 status->parse_error++;
shimniok 0:826c6171fc1b 285 status->msg_received = 0;
shimniok 0:826c6171fc1b 286 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 287 if (c == MAVLINK_STX)
shimniok 0:826c6171fc1b 288 {
shimniok 0:826c6171fc1b 289 status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
shimniok 0:826c6171fc1b 290 mavlink_start_checksum(rxmsg);
shimniok 0:826c6171fc1b 291 }
shimniok 0:826c6171fc1b 292 }
shimniok 0:826c6171fc1b 293 else
shimniok 0:826c6171fc1b 294 {
shimniok 0:826c6171fc1b 295 status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1;
shimniok 0:826c6171fc1b 296 }
shimniok 0:826c6171fc1b 297 break;
shimniok 0:826c6171fc1b 298
shimniok 0:826c6171fc1b 299 case MAVLINK_PARSE_STATE_GOT_CRC1:
shimniok 0:826c6171fc1b 300 if (c != rxmsg->ck_b)
shimniok 0:826c6171fc1b 301 {// Check second checksum byte
shimniok 0:826c6171fc1b 302 status->parse_error++;
shimniok 0:826c6171fc1b 303 status->msg_received = 0;
shimniok 0:826c6171fc1b 304 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 305 if (c == MAVLINK_STX)
shimniok 0:826c6171fc1b 306 {
shimniok 0:826c6171fc1b 307 status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
shimniok 0:826c6171fc1b 308 mavlink_start_checksum(rxmsg);
shimniok 0:826c6171fc1b 309 }
shimniok 0:826c6171fc1b 310 }
shimniok 0:826c6171fc1b 311 else
shimniok 0:826c6171fc1b 312 {
shimniok 0:826c6171fc1b 313 // Successfully got message
shimniok 0:826c6171fc1b 314 status->msg_received = 1;
shimniok 0:826c6171fc1b 315 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 316 memcpy(r_message, rxmsg, sizeof(mavlink_message_t));
shimniok 0:826c6171fc1b 317 }
shimniok 0:826c6171fc1b 318 break;
shimniok 0:826c6171fc1b 319 }
shimniok 0:826c6171fc1b 320
shimniok 0:826c6171fc1b 321 bufferIndex++;
shimniok 0:826c6171fc1b 322 // If a message has been sucessfully decoded, check index
shimniok 0:826c6171fc1b 323 if (status->msg_received == 1)
shimniok 0:826c6171fc1b 324 {
shimniok 0:826c6171fc1b 325 //while(status->current_seq != rxmsg->seq)
shimniok 0:826c6171fc1b 326 //{
shimniok 0:826c6171fc1b 327 // status->packet_rx_drop_count++;
shimniok 0:826c6171fc1b 328 // status->current_seq++;
shimniok 0:826c6171fc1b 329 //}
shimniok 0:826c6171fc1b 330 status->current_rx_seq = rxmsg->seq;
shimniok 0:826c6171fc1b 331 // Initial condition: If no packet has been received so far, drop count is undefined
shimniok 0:826c6171fc1b 332 if (status->packet_rx_success_count == 0) status->packet_rx_drop_count = 0;
shimniok 0:826c6171fc1b 333 // Count this packet as received
shimniok 0:826c6171fc1b 334 status->packet_rx_success_count++;
shimniok 0:826c6171fc1b 335 }
shimniok 0:826c6171fc1b 336
shimniok 0:826c6171fc1b 337 r_mavlink_status->current_rx_seq = status->current_rx_seq+1;
shimniok 0:826c6171fc1b 338 r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count;
shimniok 0:826c6171fc1b 339 r_mavlink_status->packet_rx_drop_count = status->parse_error;
shimniok 0:826c6171fc1b 340 status->parse_error = 0;
shimniok 0:826c6171fc1b 341 return status->msg_received;
shimniok 0:826c6171fc1b 342 }
shimniok 0:826c6171fc1b 343
shimniok 0:826c6171fc1b 344
shimniok 0:826c6171fc1b 345 /**
shimniok 0:826c6171fc1b 346 * This is a convenience function which handles the complete MAVLink parsing.
shimniok 0:826c6171fc1b 347 * the function will parse one byte at a time and return the complete packet once
shimniok 0:826c6171fc1b 348 * it could be successfully decoded. Checksum and other failures will be silently
shimniok 0:826c6171fc1b 349 * ignored.
shimniok 0:826c6171fc1b 350 *
shimniok 0:826c6171fc1b 351 * @param chan ID of the current channel. This allows to parse different channels with this function.
shimniok 0:826c6171fc1b 352 * a channel is not a physical message channel like a serial port, but a logic partition of
shimniok 0:826c6171fc1b 353 * the communication streams in this case. COMM_NB is the limit for the number of channels
shimniok 0:826c6171fc1b 354 * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
shimniok 0:826c6171fc1b 355 * @param c The char to barse
shimniok 0:826c6171fc1b 356 *
shimniok 0:826c6171fc1b 357 * @param returnMsg NULL if no message could be decoded, the message data else
shimniok 0:826c6171fc1b 358 * @return 0 if no message could be decoded, 1 else
shimniok 0:826c6171fc1b 359 *
shimniok 0:826c6171fc1b 360 * A typical use scenario of this function call is:
shimniok 0:826c6171fc1b 361 *
shimniok 0:826c6171fc1b 362 * @code
shimniok 0:826c6171fc1b 363 * #include <inttypes.h> // For fixed-width uint8_t type
shimniok 0:826c6171fc1b 364 *
shimniok 0:826c6171fc1b 365 * mavlink_message_t msg;
shimniok 0:826c6171fc1b 366 * int chan = 0;
shimniok 0:826c6171fc1b 367 *
shimniok 0:826c6171fc1b 368 *
shimniok 0:826c6171fc1b 369 * while(serial.bytesAvailable > 0)
shimniok 0:826c6171fc1b 370 * {
shimniok 0:826c6171fc1b 371 * uint8_t byte = serial.getNextByte();
shimniok 0:826c6171fc1b 372 * if (mavlink_parse_char(chan, byte, &msg))
shimniok 0:826c6171fc1b 373 * {
shimniok 0:826c6171fc1b 374 * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
shimniok 0:826c6171fc1b 375 * }
shimniok 0:826c6171fc1b 376 * }
shimniok 0:826c6171fc1b 377 *
shimniok 0:826c6171fc1b 378 *
shimniok 0:826c6171fc1b 379 * @endcode
shimniok 0:826c6171fc1b 380 */
shimniok 0:826c6171fc1b 381
shimniok 0:826c6171fc1b 382 #define MAVLINK_PACKET_START_CANDIDATES 50
shimniok 0:826c6171fc1b 383 /*
shimniok 0:826c6171fc1b 384 static inline uint8_t mavlink_parse_char_new(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
shimniok 0:826c6171fc1b 385 {
shimniok 0:826c6171fc1b 386 static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 387 static uint8_t m_msgbuf[MAVLINK_COMM_NUM_BUFFERS][MAVLINK_MAX_PACKET_LEN * 2];
shimniok 0:826c6171fc1b 388 static uint8_t m_msgbuf_index[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 389 static mavlink_message_t m_mavlink_message[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 390 static uint8_t m_packet_start[MAVLINK_COMM_NUM_BUFFERS][MAVLINK_PACKET_START_CANDIDATES];
shimniok 0:826c6171fc1b 391 static uint8_t m_packet_start_index_read[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 392 static uint8_t m_packet_start_index_write[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 393
shimniok 0:826c6171fc1b 394 // Set a packet start candidate index if sign is start sign
shimniok 0:826c6171fc1b 395 if (c == MAVLINK_STX)
shimniok 0:826c6171fc1b 396 {
shimniok 0:826c6171fc1b 397 m_packet_start[chan][++(m_packet_start_index_write[chan]) % MAVLINK_PACKET_START_CANDIDATES] = m_msgbuf_index[chan];
shimniok 0:826c6171fc1b 398 }
shimniok 0:826c6171fc1b 399
shimniok 0:826c6171fc1b 400 // Parse normally, if a CRC mismatch occurs retry with the next packet index
shimniok 0:826c6171fc1b 401 }
shimniok 0:826c6171fc1b 402 // static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 403 // static mavlink_message_t m_mavlink_message[MAVLINK_COMM_NUM_BUFFERS];
shimniok 0:826c6171fc1b 404 //// Initializes only once, values keep unchanged after first initialization
shimniok 0:826c6171fc1b 405 // mavlink_parse_state_initialize(&m_mavlink_status[chan]);
shimniok 0:826c6171fc1b 406 //
shimniok 0:826c6171fc1b 407 //mavlink_message_t* rxmsg = &m_mavlink_message[chan]; ///< The currently decoded message
shimniok 0:826c6171fc1b 408 //mavlink_status_t* status = &m_mavlink_status[chan]; ///< The current decode status
shimniok 0:826c6171fc1b 409 //int bufferIndex = 0;
shimniok 0:826c6171fc1b 410 //
shimniok 0:826c6171fc1b 411 //status->msg_received = 0;
shimniok 0:826c6171fc1b 412 //
shimniok 0:826c6171fc1b 413 //switch (status->parse_state)
shimniok 0:826c6171fc1b 414 //{
shimniok 0:826c6171fc1b 415 //case MAVLINK_PARSE_STATE_UNINIT:
shimniok 0:826c6171fc1b 416 //case MAVLINK_PARSE_STATE_IDLE:
shimniok 0:826c6171fc1b 417 // if (c == MAVLINK_STX)
shimniok 0:826c6171fc1b 418 // {
shimniok 0:826c6171fc1b 419 // status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
shimniok 0:826c6171fc1b 420 // mavlink_start_checksum(rxmsg);
shimniok 0:826c6171fc1b 421 // }
shimniok 0:826c6171fc1b 422 // break;
shimniok 0:826c6171fc1b 423 //
shimniok 0:826c6171fc1b 424 //case MAVLINK_PARSE_STATE_GOT_STX:
shimniok 0:826c6171fc1b 425 // if (status->msg_received)
shimniok 0:826c6171fc1b 426 // {
shimniok 0:826c6171fc1b 427 // status->buffer_overrun++;
shimniok 0:826c6171fc1b 428 // status->parse_error++;
shimniok 0:826c6171fc1b 429 // status->msg_received = 0;
shimniok 0:826c6171fc1b 430 // status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 431 // }
shimniok 0:826c6171fc1b 432 // else
shimniok 0:826c6171fc1b 433 // {
shimniok 0:826c6171fc1b 434 // // NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2
shimniok 0:826c6171fc1b 435 // rxmsg->len = c;
shimniok 0:826c6171fc1b 436 // status->packet_idx = 0;
shimniok 0:826c6171fc1b 437 // mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 438 // status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH;
shimniok 0:826c6171fc1b 439 // }
shimniok 0:826c6171fc1b 440 // break;
shimniok 0:826c6171fc1b 441 //
shimniok 0:826c6171fc1b 442 //case MAVLINK_PARSE_STATE_GOT_LENGTH:
shimniok 0:826c6171fc1b 443 // rxmsg->seq = c;
shimniok 0:826c6171fc1b 444 // mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 445 // status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ;
shimniok 0:826c6171fc1b 446 // break;
shimniok 0:826c6171fc1b 447 //
shimniok 0:826c6171fc1b 448 //case MAVLINK_PARSE_STATE_GOT_SEQ:
shimniok 0:826c6171fc1b 449 // rxmsg->sysid = c;
shimniok 0:826c6171fc1b 450 // mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 451 // status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID;
shimniok 0:826c6171fc1b 452 // break;
shimniok 0:826c6171fc1b 453 //
shimniok 0:826c6171fc1b 454 //case MAVLINK_PARSE_STATE_GOT_SYSID:
shimniok 0:826c6171fc1b 455 // rxmsg->compid = c;
shimniok 0:826c6171fc1b 456 // mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 457 // status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID;
shimniok 0:826c6171fc1b 458 // break;
shimniok 0:826c6171fc1b 459 //
shimniok 0:826c6171fc1b 460 //case MAVLINK_PARSE_STATE_GOT_COMPID:
shimniok 0:826c6171fc1b 461 // rxmsg->msgid = c;
shimniok 0:826c6171fc1b 462 // mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 463 // if (rxmsg->len == 0)
shimniok 0:826c6171fc1b 464 // {
shimniok 0:826c6171fc1b 465 // status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
shimniok 0:826c6171fc1b 466 // }
shimniok 0:826c6171fc1b 467 // else
shimniok 0:826c6171fc1b 468 // {
shimniok 0:826c6171fc1b 469 // status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID;
shimniok 0:826c6171fc1b 470 // }
shimniok 0:826c6171fc1b 471 // break;
shimniok 0:826c6171fc1b 472 //
shimniok 0:826c6171fc1b 473 //case MAVLINK_PARSE_STATE_GOT_MSGID:
shimniok 0:826c6171fc1b 474 // rxmsg->payload[status->packet_idx++] = c;
shimniok 0:826c6171fc1b 475 // mavlink_update_checksum(rxmsg, c);
shimniok 0:826c6171fc1b 476 // if (status->packet_idx == rxmsg->len)
shimniok 0:826c6171fc1b 477 // {
shimniok 0:826c6171fc1b 478 // status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
shimniok 0:826c6171fc1b 479 // }
shimniok 0:826c6171fc1b 480 // break;
shimniok 0:826c6171fc1b 481 //
shimniok 0:826c6171fc1b 482 //case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
shimniok 0:826c6171fc1b 483 // if (c != rxmsg->ck_a)
shimniok 0:826c6171fc1b 484 // {
shimniok 0:826c6171fc1b 485 // // Check first checksum byte
shimniok 0:826c6171fc1b 486 // status->parse_error++;
shimniok 0:826c6171fc1b 487 // status->msg_received = 0;
shimniok 0:826c6171fc1b 488 // status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 489 // }
shimniok 0:826c6171fc1b 490 // else
shimniok 0:826c6171fc1b 491 // {
shimniok 0:826c6171fc1b 492 // status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1;
shimniok 0:826c6171fc1b 493 // }
shimniok 0:826c6171fc1b 494 // break;
shimniok 0:826c6171fc1b 495 //
shimniok 0:826c6171fc1b 496 //case MAVLINK_PARSE_STATE_GOT_CRC1:
shimniok 0:826c6171fc1b 497 // if (c != rxmsg->ck_b)
shimniok 0:826c6171fc1b 498 // {// Check second checksum byte
shimniok 0:826c6171fc1b 499 // status->parse_error++;
shimniok 0:826c6171fc1b 500 // status->msg_received = 0;
shimniok 0:826c6171fc1b 501 // status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 502 // }
shimniok 0:826c6171fc1b 503 // else
shimniok 0:826c6171fc1b 504 // {
shimniok 0:826c6171fc1b 505 // // Successfully got message
shimniok 0:826c6171fc1b 506 // status->msg_received = 1;
shimniok 0:826c6171fc1b 507 // status->parse_state = MAVLINK_PARSE_STATE_IDLE;
shimniok 0:826c6171fc1b 508 // memcpy(r_message, rxmsg, sizeof(mavlink_message_t));
shimniok 0:826c6171fc1b 509 // }
shimniok 0:826c6171fc1b 510 // break;
shimniok 0:826c6171fc1b 511 //}
shimniok 0:826c6171fc1b 512
shimniok 0:826c6171fc1b 513 bufferIndex++;
shimniok 0:826c6171fc1b 514 // If a message has been sucessfully decoded, check index
shimniok 0:826c6171fc1b 515 if (status->msg_received == 1)
shimniok 0:826c6171fc1b 516 {
shimniok 0:826c6171fc1b 517 //while(status->current_seq != rxmsg->seq)
shimniok 0:826c6171fc1b 518 //{
shimniok 0:826c6171fc1b 519 // status->packet_rx_drop_count++;
shimniok 0:826c6171fc1b 520 // status->current_seq++;
shimniok 0:826c6171fc1b 521 //}
shimniok 0:826c6171fc1b 522 status->current_seq = rxmsg->seq;
shimniok 0:826c6171fc1b 523 // Initial condition: If no packet has been received so far, drop count is undefined
shimniok 0:826c6171fc1b 524 if (status->packet_rx_success_count == 0) status->packet_rx_drop_count = 0;
shimniok 0:826c6171fc1b 525 // Count this packet as received
shimniok 0:826c6171fc1b 526 status->packet_rx_success_count++;
shimniok 0:826c6171fc1b 527 }
shimniok 0:826c6171fc1b 528
shimniok 0:826c6171fc1b 529 r_mavlink_status->current_seq = status->current_seq+1;
shimniok 0:826c6171fc1b 530 r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count;
shimniok 0:826c6171fc1b 531 r_mavlink_status->packet_rx_drop_count = status->parse_error;
shimniok 0:826c6171fc1b 532 return status->msg_received;
shimniok 0:826c6171fc1b 533 }
shimniok 0:826c6171fc1b 534 */
shimniok 0:826c6171fc1b 535
shimniok 0:826c6171fc1b 536
shimniok 0:826c6171fc1b 537 typedef union __generic_16bit
shimniok 0:826c6171fc1b 538 {
shimniok 0:826c6171fc1b 539 uint8_t b[2];
shimniok 0:826c6171fc1b 540 int16_t s;
shimniok 0:826c6171fc1b 541 } generic_16bit;
shimniok 0:826c6171fc1b 542
shimniok 0:826c6171fc1b 543 typedef union __generic_32bit
shimniok 0:826c6171fc1b 544 {
shimniok 0:826c6171fc1b 545 uint8_t b[4];
shimniok 0:826c6171fc1b 546 float f;
shimniok 0:826c6171fc1b 547 int32_t i;
shimniok 0:826c6171fc1b 548 int16_t s;
shimniok 0:826c6171fc1b 549 } generic_32bit;
shimniok 0:826c6171fc1b 550
shimniok 0:826c6171fc1b 551 typedef union __generic_64bit
shimniok 0:826c6171fc1b 552 {
shimniok 0:826c6171fc1b 553 uint8_t b[8];
shimniok 0:826c6171fc1b 554 int64_t ll; ///< Long long (64 bit)
shimniok 0:826c6171fc1b 555 double d; ///< IEEE-754 double precision floating point
shimniok 0:826c6171fc1b 556 } generic_64bit;
shimniok 0:826c6171fc1b 557
shimniok 0:826c6171fc1b 558 /**
shimniok 0:826c6171fc1b 559 * @brief Place an unsigned byte into the buffer
shimniok 0:826c6171fc1b 560 *
shimniok 0:826c6171fc1b 561 * @param b the byte to add
shimniok 0:826c6171fc1b 562 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 563 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 564 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 565 */
shimniok 0:826c6171fc1b 566 static inline uint8_t put_uint8_t_by_index(uint8_t b, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 567 {
shimniok 0:826c6171fc1b 568 *(buffer + bindex) = b;
shimniok 0:826c6171fc1b 569 return sizeof(b);
shimniok 0:826c6171fc1b 570 }
shimniok 0:826c6171fc1b 571
shimniok 0:826c6171fc1b 572 /**
shimniok 0:826c6171fc1b 573 * @brief Place a signed byte into the buffer
shimniok 0:826c6171fc1b 574 *
shimniok 0:826c6171fc1b 575 * @param b the byte to add
shimniok 0:826c6171fc1b 576 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 577 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 578 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 579 */
shimniok 0:826c6171fc1b 580 static inline uint8_t put_int8_t_by_index(int8_t b, int8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 581 {
shimniok 0:826c6171fc1b 582 *(buffer + bindex) = (uint8_t)b;
shimniok 0:826c6171fc1b 583 return sizeof(b);
shimniok 0:826c6171fc1b 584 }
shimniok 0:826c6171fc1b 585
shimniok 0:826c6171fc1b 586 /**
shimniok 0:826c6171fc1b 587 * @brief Place two unsigned bytes into the buffer
shimniok 0:826c6171fc1b 588 *
shimniok 0:826c6171fc1b 589 * @param b the bytes to add
shimniok 0:826c6171fc1b 590 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 591 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 592 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 593 */
shimniok 0:826c6171fc1b 594 static inline uint8_t put_uint16_t_by_index(uint16_t b, const uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 595 {
shimniok 0:826c6171fc1b 596 buffer[bindex] = (b>>8)&0xff;
shimniok 0:826c6171fc1b 597 buffer[bindex+1] = (b & 0xff);
shimniok 0:826c6171fc1b 598 return sizeof(b);
shimniok 0:826c6171fc1b 599 }
shimniok 0:826c6171fc1b 600
shimniok 0:826c6171fc1b 601 /**
shimniok 0:826c6171fc1b 602 * @brief Place two signed bytes into the buffer
shimniok 0:826c6171fc1b 603 *
shimniok 0:826c6171fc1b 604 * @param b the bytes to add
shimniok 0:826c6171fc1b 605 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 606 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 607 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 608 */
shimniok 0:826c6171fc1b 609 static inline uint8_t put_int16_t_by_index(int16_t b, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 610 {
shimniok 0:826c6171fc1b 611 return put_uint16_t_by_index(b, bindex, buffer);
shimniok 0:826c6171fc1b 612 }
shimniok 0:826c6171fc1b 613
shimniok 0:826c6171fc1b 614 /**
shimniok 0:826c6171fc1b 615 * @brief Place four unsigned bytes into the buffer
shimniok 0:826c6171fc1b 616 *
shimniok 0:826c6171fc1b 617 * @param b the bytes to add
shimniok 0:826c6171fc1b 618 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 619 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 620 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 621 */
shimniok 0:826c6171fc1b 622 static inline uint8_t put_uint32_t_by_index(uint32_t b, const uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 623 {
shimniok 0:826c6171fc1b 624 buffer[bindex] = (b>>24)&0xff;
shimniok 0:826c6171fc1b 625 buffer[bindex+1] = (b>>16)&0xff;
shimniok 0:826c6171fc1b 626 buffer[bindex+2] = (b>>8)&0xff;
shimniok 0:826c6171fc1b 627 buffer[bindex+3] = (b & 0xff);
shimniok 0:826c6171fc1b 628 return sizeof(b);
shimniok 0:826c6171fc1b 629 }
shimniok 0:826c6171fc1b 630
shimniok 0:826c6171fc1b 631 /**
shimniok 0:826c6171fc1b 632 * @brief Place four signed bytes into the buffer
shimniok 0:826c6171fc1b 633 *
shimniok 0:826c6171fc1b 634 * @param b the bytes to add
shimniok 0:826c6171fc1b 635 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 636 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 637 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 638 */
shimniok 0:826c6171fc1b 639 static inline uint8_t put_int32_t_by_index(int32_t b, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 640 {
shimniok 0:826c6171fc1b 641 buffer[bindex] = (b>>24)&0xff;
shimniok 0:826c6171fc1b 642 buffer[bindex+1] = (b>>16)&0xff;
shimniok 0:826c6171fc1b 643 buffer[bindex+2] = (b>>8)&0xff;
shimniok 0:826c6171fc1b 644 buffer[bindex+3] = (b & 0xff);
shimniok 0:826c6171fc1b 645 return sizeof(b);
shimniok 0:826c6171fc1b 646 }
shimniok 0:826c6171fc1b 647
shimniok 0:826c6171fc1b 648 /**
shimniok 0:826c6171fc1b 649 * @brief Place four unsigned bytes into the buffer
shimniok 0:826c6171fc1b 650 *
shimniok 0:826c6171fc1b 651 * @param b the bytes to add
shimniok 0:826c6171fc1b 652 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 653 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 654 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 655 */
shimniok 0:826c6171fc1b 656 static inline uint8_t put_uint64_t_by_index(uint64_t b, const uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 657 {
shimniok 0:826c6171fc1b 658 buffer[bindex] = (b>>56)&0xff;
shimniok 0:826c6171fc1b 659 buffer[bindex+1] = (b>>48)&0xff;
shimniok 0:826c6171fc1b 660 buffer[bindex+2] = (b>>40)&0xff;
shimniok 0:826c6171fc1b 661 buffer[bindex+3] = (b>>32)&0xff;
shimniok 0:826c6171fc1b 662 buffer[bindex+4] = (b>>24)&0xff;
shimniok 0:826c6171fc1b 663 buffer[bindex+5] = (b>>16)&0xff;
shimniok 0:826c6171fc1b 664 buffer[bindex+6] = (b>>8)&0xff;
shimniok 0:826c6171fc1b 665 buffer[bindex+7] = (b & 0xff);
shimniok 0:826c6171fc1b 666 return sizeof(b);
shimniok 0:826c6171fc1b 667 }
shimniok 0:826c6171fc1b 668
shimniok 0:826c6171fc1b 669 /**
shimniok 0:826c6171fc1b 670 * @brief Place four signed bytes into the buffer
shimniok 0:826c6171fc1b 671 *
shimniok 0:826c6171fc1b 672 * @param b the bytes to add
shimniok 0:826c6171fc1b 673 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 674 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 675 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 676 */
shimniok 0:826c6171fc1b 677 static inline uint8_t put_int64_t_by_index(int64_t b, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 678 {
shimniok 0:826c6171fc1b 679 return put_uint64_t_by_index(b, bindex, buffer);
shimniok 0:826c6171fc1b 680 }
shimniok 0:826c6171fc1b 681
shimniok 0:826c6171fc1b 682 /**
shimniok 0:826c6171fc1b 683 * @brief Place a float into the buffer
shimniok 0:826c6171fc1b 684 *
shimniok 0:826c6171fc1b 685 * @param b the float to add
shimniok 0:826c6171fc1b 686 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 687 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 688 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 689 */
shimniok 0:826c6171fc1b 690 static inline uint8_t put_float_by_index(float b, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 691 {
shimniok 0:826c6171fc1b 692 generic_32bit g;
shimniok 0:826c6171fc1b 693 g.f = b;
shimniok 0:826c6171fc1b 694 return put_int32_t_by_index(g.i, bindex, buffer);
shimniok 0:826c6171fc1b 695 }
shimniok 0:826c6171fc1b 696
shimniok 0:826c6171fc1b 697 /**
shimniok 0:826c6171fc1b 698 * @brief Place a double into the buffer
shimniok 0:826c6171fc1b 699 *
shimniok 0:826c6171fc1b 700 * @param b the double to add
shimniok 0:826c6171fc1b 701 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 702 * @param buffer the packet buffer
shimniok 0:826c6171fc1b 703 * @return the new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 704 */
shimniok 0:826c6171fc1b 705 static inline uint8_t put_double_by_index(double b, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 706 {
shimniok 0:826c6171fc1b 707 generic_64bit g;
shimniok 0:826c6171fc1b 708 g.d = b;
shimniok 0:826c6171fc1b 709 return put_int64_t_by_index(g.ll, bindex, buffer);
shimniok 0:826c6171fc1b 710 }
shimniok 0:826c6171fc1b 711
shimniok 0:826c6171fc1b 712 /**
shimniok 0:826c6171fc1b 713 * @brief Place an array into the buffer
shimniok 0:826c6171fc1b 714 *
shimniok 0:826c6171fc1b 715 * @param b the array to add
shimniok 0:826c6171fc1b 716 * @param length size of the array (for strings: length WITH '\0' char)
shimniok 0:826c6171fc1b 717 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 718 * @param buffer packet buffer
shimniok 0:826c6171fc1b 719 * @return new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 720 */
shimniok 0:826c6171fc1b 721 static inline uint8_t put_array_by_index(const int8_t* b, uint8_t length, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 722 {
shimniok 0:826c6171fc1b 723 memcpy(buffer+bindex, b, length);
shimniok 0:826c6171fc1b 724 return length;
shimniok 0:826c6171fc1b 725 }
shimniok 0:826c6171fc1b 726
shimniok 0:826c6171fc1b 727 /**
shimniok 0:826c6171fc1b 728 * @brief Place a string into the buffer
shimniok 0:826c6171fc1b 729 *
shimniok 0:826c6171fc1b 730 * @param b the string to add
shimniok 0:826c6171fc1b 731 * @param maxlength size of the array (for strings: length WITHOUT '\0' char)
shimniok 0:826c6171fc1b 732 * @param bindex the position in the packet
shimniok 0:826c6171fc1b 733 * @param buffer packet buffer
shimniok 0:826c6171fc1b 734 * @return new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 735 */
shimniok 0:826c6171fc1b 736 static inline uint8_t put_string_by_index(const char* b, uint8_t maxlength, uint8_t bindex, uint8_t* buffer)
shimniok 0:826c6171fc1b 737 {
shimniok 0:826c6171fc1b 738 uint16_t length = 0;
shimniok 0:826c6171fc1b 739 // Copy string into buffer, ensuring not to exceed the buffer size
shimniok 0:826c6171fc1b 740 int i;
shimniok 0:826c6171fc1b 741 for (i = 1; i < maxlength; i++)
shimniok 0:826c6171fc1b 742 {
shimniok 0:826c6171fc1b 743 length++;
shimniok 0:826c6171fc1b 744 // String characters
shimniok 0:826c6171fc1b 745 if (i < (maxlength - 1))
shimniok 0:826c6171fc1b 746 {
shimniok 0:826c6171fc1b 747 buffer[bindex+i] = b[i];
shimniok 0:826c6171fc1b 748 // Stop at null character
shimniok 0:826c6171fc1b 749 if (b[i] == '\0')
shimniok 0:826c6171fc1b 750 {
shimniok 0:826c6171fc1b 751 break;
shimniok 0:826c6171fc1b 752 }
shimniok 0:826c6171fc1b 753 }
shimniok 0:826c6171fc1b 754 // Enforce null termination at end of buffer
shimniok 0:826c6171fc1b 755 else if (i == (maxlength - 1))
shimniok 0:826c6171fc1b 756 {
shimniok 0:826c6171fc1b 757 buffer[i] = '\0';
shimniok 0:826c6171fc1b 758 }
shimniok 0:826c6171fc1b 759 }
shimniok 0:826c6171fc1b 760 // Write length into first field
shimniok 0:826c6171fc1b 761 put_uint8_t_by_index(length, bindex, buffer);
shimniok 0:826c6171fc1b 762 return length;
shimniok 0:826c6171fc1b 763 }
shimniok 0:826c6171fc1b 764
shimniok 0:826c6171fc1b 765 /**
shimniok 0:826c6171fc1b 766 * @brief Put a bitfield of length 1-32 bit into the buffer
shimniok 0:826c6171fc1b 767 *
shimniok 0:826c6171fc1b 768 * @param b the value to add, will be encoded in the bitfield
shimniok 0:826c6171fc1b 769 * @param bits number of bits to use to encode b, e.g. 1 for boolean, 2, 3, etc.
shimniok 0:826c6171fc1b 770 * @param packet_index the position in the packet (the index of the first byte to use)
shimniok 0:826c6171fc1b 771 * @param bit_index the position in the byte (the index of the first bit to use)
shimniok 0:826c6171fc1b 772 * @param buffer packet buffer to write into
shimniok 0:826c6171fc1b 773 * @return new position of the last used byte in the buffer
shimniok 0:826c6171fc1b 774 */
shimniok 0:826c6171fc1b 775 static inline uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index, uint8_t* r_bit_index, uint8_t* buffer)
shimniok 0:826c6171fc1b 776 {
shimniok 0:826c6171fc1b 777 uint16_t bits_remain = bits;
shimniok 0:826c6171fc1b 778 // Transform number into network order
shimniok 0:826c6171fc1b 779 generic_32bit bin;
shimniok 0:826c6171fc1b 780 generic_32bit bout;
shimniok 0:826c6171fc1b 781 uint8_t i_bit_index, i_byte_index, curr_bits_n;
shimniok 0:826c6171fc1b 782 bin.i = b;
shimniok 0:826c6171fc1b 783 bout.b[0] = bin.b[3];
shimniok 0:826c6171fc1b 784 bout.b[1] = bin.b[2];
shimniok 0:826c6171fc1b 785 bout.b[2] = bin.b[1];
shimniok 0:826c6171fc1b 786 bout.b[3] = bin.b[0];
shimniok 0:826c6171fc1b 787
shimniok 0:826c6171fc1b 788 // buffer in
shimniok 0:826c6171fc1b 789 // 01100000 01000000 00000000 11110001
shimniok 0:826c6171fc1b 790 // buffer out
shimniok 0:826c6171fc1b 791 // 11110001 00000000 01000000 01100000
shimniok 0:826c6171fc1b 792
shimniok 0:826c6171fc1b 793 // Existing partly filled byte (four free slots)
shimniok 0:826c6171fc1b 794 // 0111xxxx
shimniok 0:826c6171fc1b 795
shimniok 0:826c6171fc1b 796 // Mask n free bits
shimniok 0:826c6171fc1b 797 // 00001111 = 2^0 + 2^1 + 2^2 + 2^3 = 2^n - 1
shimniok 0:826c6171fc1b 798 // = ((uint32_t)(1 << n)) - 1; // = 2^n - 1
shimniok 0:826c6171fc1b 799
shimniok 0:826c6171fc1b 800 // Shift n bits into the right position
shimniok 0:826c6171fc1b 801 // out = in >> n;
shimniok 0:826c6171fc1b 802
shimniok 0:826c6171fc1b 803 // Mask and shift bytes
shimniok 0:826c6171fc1b 804 i_bit_index = bit_index;
shimniok 0:826c6171fc1b 805 i_byte_index = packet_index;
shimniok 0:826c6171fc1b 806 if (bit_index > 0)
shimniok 0:826c6171fc1b 807 {
shimniok 0:826c6171fc1b 808 // If bits were available at start, they were available
shimniok 0:826c6171fc1b 809 // in the byte before the current index
shimniok 0:826c6171fc1b 810 i_byte_index--;
shimniok 0:826c6171fc1b 811 }
shimniok 0:826c6171fc1b 812
shimniok 0:826c6171fc1b 813 // While bits have not been packed yet
shimniok 0:826c6171fc1b 814 while (bits_remain > 0)
shimniok 0:826c6171fc1b 815 {
shimniok 0:826c6171fc1b 816 // Bits still have to be packed
shimniok 0:826c6171fc1b 817 // there can be more than 8 bits, so
shimniok 0:826c6171fc1b 818 // we might have to pack them into more than one byte
shimniok 0:826c6171fc1b 819
shimniok 0:826c6171fc1b 820 // First pack everything we can into the current 'open' byte
shimniok 0:826c6171fc1b 821 //curr_bits_n = bits_remain << 3; // Equals bits_remain mod 8
shimniok 0:826c6171fc1b 822 //FIXME
shimniok 0:826c6171fc1b 823 if (bits_remain <= (8 - i_bit_index))
shimniok 0:826c6171fc1b 824 {
shimniok 0:826c6171fc1b 825 // Enough space
shimniok 0:826c6171fc1b 826 curr_bits_n = bits_remain;
shimniok 0:826c6171fc1b 827 }
shimniok 0:826c6171fc1b 828 else
shimniok 0:826c6171fc1b 829 {
shimniok 0:826c6171fc1b 830 curr_bits_n = (8 - i_bit_index);
shimniok 0:826c6171fc1b 831 }
shimniok 0:826c6171fc1b 832
shimniok 0:826c6171fc1b 833 // Pack these n bits into the current byte
shimniok 0:826c6171fc1b 834 // Mask out whatever was at that position with ones (xxx11111)
shimniok 0:826c6171fc1b 835 buffer[i_byte_index] &= (0xFF >> (8 - curr_bits_n));
shimniok 0:826c6171fc1b 836 // Put content to this position, by masking out the non-used part
shimniok 0:826c6171fc1b 837 buffer[i_byte_index] |= ((0x00 << curr_bits_n) & bout.i);
shimniok 0:826c6171fc1b 838
shimniok 0:826c6171fc1b 839 // Increment the bit index
shimniok 0:826c6171fc1b 840 i_bit_index += curr_bits_n;
shimniok 0:826c6171fc1b 841
shimniok 0:826c6171fc1b 842 // Now proceed to the next byte, if necessary
shimniok 0:826c6171fc1b 843 bits_remain -= curr_bits_n;
shimniok 0:826c6171fc1b 844 if (bits_remain > 0)
shimniok 0:826c6171fc1b 845 {
shimniok 0:826c6171fc1b 846 // Offer another 8 bits / one byte
shimniok 0:826c6171fc1b 847 i_byte_index++;
shimniok 0:826c6171fc1b 848 i_bit_index = 0;
shimniok 0:826c6171fc1b 849 }
shimniok 0:826c6171fc1b 850 }
shimniok 0:826c6171fc1b 851
shimniok 0:826c6171fc1b 852 *r_bit_index = i_bit_index;
shimniok 0:826c6171fc1b 853 // If a partly filled byte is present, mark this as consumed
shimniok 0:826c6171fc1b 854 if (i_bit_index != 7) i_byte_index++;
shimniok 0:826c6171fc1b 855 return i_byte_index - packet_index;
shimniok 0:826c6171fc1b 856 }
shimniok 0:826c6171fc1b 857
shimniok 0:826c6171fc1b 858 #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
shimniok 0:826c6171fc1b 859
shimniok 0:826c6171fc1b 860 // To make MAVLink work on your MCU, define a similar function
shimniok 0:826c6171fc1b 861
shimniok 0:826c6171fc1b 862 /*
shimniok 0:826c6171fc1b 863
shimniok 0:826c6171fc1b 864 #include "mavlink_types.h"
shimniok 0:826c6171fc1b 865
shimniok 0:826c6171fc1b 866 void comm_send_ch(mavlink_channel_t chan, uint8_t ch)
shimniok 0:826c6171fc1b 867 {
shimniok 0:826c6171fc1b 868 if (chan == MAVLINK_COMM_0)
shimniok 0:826c6171fc1b 869 {
shimniok 0:826c6171fc1b 870 uart0_transmit(ch);
shimniok 0:826c6171fc1b 871 }
shimniok 0:826c6171fc1b 872 if (chan == MAVLINK_COMM_1)
shimniok 0:826c6171fc1b 873 {
shimniok 0:826c6171fc1b 874 uart1_transmit(ch);
shimniok 0:826c6171fc1b 875 }
shimniok 0:826c6171fc1b 876 }
shimniok 0:826c6171fc1b 877 */
shimniok 0:826c6171fc1b 878
shimniok 0:826c6171fc1b 879 static inline void mavlink_send_uart_uint8_t(mavlink_channel_t chan, uint8_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 880 {
shimniok 0:826c6171fc1b 881 crc_accumulate(b, checksum);
shimniok 0:826c6171fc1b 882 comm_send_ch(chan, b);
shimniok 0:826c6171fc1b 883 }
shimniok 0:826c6171fc1b 884
shimniok 0:826c6171fc1b 885 static inline void mavlink_send_uart_int8_t(mavlink_channel_t chan, int8_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 886 {
shimniok 0:826c6171fc1b 887 crc_accumulate(b, checksum);
shimniok 0:826c6171fc1b 888 comm_send_ch(chan, b);
shimniok 0:826c6171fc1b 889 }
shimniok 0:826c6171fc1b 890
shimniok 0:826c6171fc1b 891 static inline void mavlink_send_uart_uint16_t(mavlink_channel_t chan, uint16_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 892 {
shimniok 0:826c6171fc1b 893 char s;
shimniok 0:826c6171fc1b 894 s = (b>>8)&0xff;
shimniok 0:826c6171fc1b 895 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 896 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 897 s = (b & 0xff);
shimniok 0:826c6171fc1b 898 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 899 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 900 }
shimniok 0:826c6171fc1b 901
shimniok 0:826c6171fc1b 902 static inline void mavlink_send_uart_int16_t(mavlink_channel_t chan, int16_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 903 {
shimniok 0:826c6171fc1b 904 mavlink_send_uart_uint16_t(chan, b, checksum);
shimniok 0:826c6171fc1b 905 }
shimniok 0:826c6171fc1b 906
shimniok 0:826c6171fc1b 907 static inline void mavlink_send_uart_uint32_t(mavlink_channel_t chan, uint32_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 908 {
shimniok 0:826c6171fc1b 909 char s;
shimniok 0:826c6171fc1b 910 s = (b>>24)&0xff;
shimniok 0:826c6171fc1b 911 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 912 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 913 s = (b>>16)&0xff;
shimniok 0:826c6171fc1b 914 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 915 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 916 s = (b>>8)&0xff;
shimniok 0:826c6171fc1b 917 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 918 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 919 s = (b & 0xff);
shimniok 0:826c6171fc1b 920 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 921 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 922 }
shimniok 0:826c6171fc1b 923
shimniok 0:826c6171fc1b 924 static inline void mavlink_send_uart_int32_t(mavlink_channel_t chan, int32_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 925 {
shimniok 0:826c6171fc1b 926 mavlink_send_uart_uint32_t(chan, b, checksum);
shimniok 0:826c6171fc1b 927 }
shimniok 0:826c6171fc1b 928
shimniok 0:826c6171fc1b 929 static inline void mavlink_send_uart_uint64_t(mavlink_channel_t chan, uint64_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 930 {
shimniok 0:826c6171fc1b 931 char s;
shimniok 0:826c6171fc1b 932 s = (b>>56)&0xff;
shimniok 0:826c6171fc1b 933 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 934 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 935 s = (b>>48)&0xff;
shimniok 0:826c6171fc1b 936 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 937 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 938 s = (b>>40)&0xff;
shimniok 0:826c6171fc1b 939 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 940 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 941 s = (b>>32)&0xff;
shimniok 0:826c6171fc1b 942 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 943 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 944 s = (b>>24)&0xff;
shimniok 0:826c6171fc1b 945 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 946 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 947 s = (b>>16)&0xff;
shimniok 0:826c6171fc1b 948 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 949 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 950 s = (b>>8)&0xff;
shimniok 0:826c6171fc1b 951 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 952 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 953 s = (b & 0xff);
shimniok 0:826c6171fc1b 954 comm_send_ch(chan, s);
shimniok 0:826c6171fc1b 955 crc_accumulate(s, checksum);
shimniok 0:826c6171fc1b 956 }
shimniok 0:826c6171fc1b 957
shimniok 0:826c6171fc1b 958 static inline void mavlink_send_uart_int64_t(mavlink_channel_t chan, int64_t b, uint16_t* checksum)
shimniok 0:826c6171fc1b 959 {
shimniok 0:826c6171fc1b 960 mavlink_send_uart_uint64_t(chan, b, checksum);
shimniok 0:826c6171fc1b 961 }
shimniok 0:826c6171fc1b 962
shimniok 0:826c6171fc1b 963 static inline void mavlink_send_uart_float(mavlink_channel_t chan, float b, uint16_t* checksum)
shimniok 0:826c6171fc1b 964 {
shimniok 0:826c6171fc1b 965 generic_32bit g;
shimniok 0:826c6171fc1b 966 g.f = b;
shimniok 0:826c6171fc1b 967 mavlink_send_uart_uint32_t(chan, g.i, checksum);
shimniok 0:826c6171fc1b 968 }
shimniok 0:826c6171fc1b 969
shimniok 0:826c6171fc1b 970 static inline void mavlink_send_uart_double(mavlink_channel_t chan, double b, uint16_t* checksum)
shimniok 0:826c6171fc1b 971 {
shimniok 0:826c6171fc1b 972 generic_64bit g;
shimniok 0:826c6171fc1b 973 g.d = b;
shimniok 0:826c6171fc1b 974 mavlink_send_uart_uint32_t(chan, g.ll, checksum);
shimniok 0:826c6171fc1b 975 }
shimniok 0:826c6171fc1b 976
shimniok 0:826c6171fc1b 977 static inline void mavlink_send_uart(mavlink_channel_t chan, mavlink_message_t* msg)
shimniok 0:826c6171fc1b 978 {
shimniok 0:826c6171fc1b 979 // ARM7 MCU board implementation
shimniok 0:826c6171fc1b 980 // Create pointer on message struct
shimniok 0:826c6171fc1b 981 // Send STX
shimniok 0:826c6171fc1b 982 comm_send_ch(chan, MAVLINK_STX);
shimniok 0:826c6171fc1b 983 comm_send_ch(chan, msg->len);
shimniok 0:826c6171fc1b 984 comm_send_ch(chan, msg->seq);
shimniok 0:826c6171fc1b 985 comm_send_ch(chan, msg->sysid);
shimniok 0:826c6171fc1b 986 comm_send_ch(chan, msg->compid);
shimniok 0:826c6171fc1b 987 comm_send_ch(chan, msg->msgid);
shimniok 0:826c6171fc1b 988 for(uint16_t i = 0; i < msg->len; i++)
shimniok 0:826c6171fc1b 989 {
shimniok 0:826c6171fc1b 990 comm_send_ch(chan, msg->payload[i]);
shimniok 0:826c6171fc1b 991 }
shimniok 0:826c6171fc1b 992 comm_send_ch(chan, msg->ck_a);
shimniok 0:826c6171fc1b 993 comm_send_ch(chan, msg->ck_b);
shimniok 0:826c6171fc1b 994 }
shimniok 0:826c6171fc1b 995 #endif
shimniok 0:826c6171fc1b 996
shimniok 0:826c6171fc1b 997 #endif /* _MAVLINK_PROTOCOL_H_ */