Mavlink Messages for Emaxx Nav Board

Dependents:   Madpulse_Speed_Control_temp Madpulse_Speed_Control_Students

Committer:
jdawkins
Date:
Fri Jan 20 13:27:11 2017 +0000
Revision:
1:7e9af9a921f7
Parent:
0:bb2cacd02294
Fixed Asin error in mavlink_conversions.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jdawkins 0:bb2cacd02294 1 #ifndef _MAVLINK_HELPERS_H_
jdawkins 0:bb2cacd02294 2 #define _MAVLINK_HELPERS_H_
jdawkins 0:bb2cacd02294 3
jdawkins 0:bb2cacd02294 4 #include "string.h"
jdawkins 0:bb2cacd02294 5 #include "checksum.h"
jdawkins 0:bb2cacd02294 6 #include "mavlink_types.h"
jdawkins 0:bb2cacd02294 7 #include "mavlink_conversions.h"
jdawkins 0:bb2cacd02294 8
jdawkins 0:bb2cacd02294 9 #ifndef MAVLINK_HELPER
jdawkins 0:bb2cacd02294 10 #define MAVLINK_HELPER
jdawkins 0:bb2cacd02294 11 #endif
jdawkins 0:bb2cacd02294 12
jdawkins 0:bb2cacd02294 13 /*
jdawkins 0:bb2cacd02294 14 * Internal function to give access to the channel status for each channel
jdawkins 0:bb2cacd02294 15 */
jdawkins 0:bb2cacd02294 16 #ifndef MAVLINK_GET_CHANNEL_STATUS
jdawkins 0:bb2cacd02294 17 MAVLINK_HELPER mavlink_status_t* mavlink_get_channel_status(uint8_t chan)
jdawkins 0:bb2cacd02294 18 {
jdawkins 0:bb2cacd02294 19 #ifdef MAVLINK_EXTERNAL_RX_STATUS
jdawkins 0:bb2cacd02294 20 // No m_mavlink_status array defined in function,
jdawkins 0:bb2cacd02294 21 // has to be defined externally
jdawkins 0:bb2cacd02294 22 #else
jdawkins 0:bb2cacd02294 23 static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
jdawkins 0:bb2cacd02294 24 #endif
jdawkins 0:bb2cacd02294 25 return &m_mavlink_status[chan];
jdawkins 0:bb2cacd02294 26 }
jdawkins 0:bb2cacd02294 27 #endif
jdawkins 0:bb2cacd02294 28
jdawkins 0:bb2cacd02294 29 /*
jdawkins 0:bb2cacd02294 30 * Internal function to give access to the channel buffer for each channel
jdawkins 0:bb2cacd02294 31 */
jdawkins 0:bb2cacd02294 32 #ifndef MAVLINK_GET_CHANNEL_BUFFER
jdawkins 0:bb2cacd02294 33 MAVLINK_HELPER mavlink_message_t* mavlink_get_channel_buffer(uint8_t chan)
jdawkins 0:bb2cacd02294 34 {
jdawkins 0:bb2cacd02294 35
jdawkins 0:bb2cacd02294 36 #ifdef MAVLINK_EXTERNAL_RX_BUFFER
jdawkins 0:bb2cacd02294 37 // No m_mavlink_buffer array defined in function,
jdawkins 0:bb2cacd02294 38 // has to be defined externally
jdawkins 0:bb2cacd02294 39 #else
jdawkins 0:bb2cacd02294 40 static mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS];
jdawkins 0:bb2cacd02294 41 #endif
jdawkins 0:bb2cacd02294 42 return &m_mavlink_buffer[chan];
jdawkins 0:bb2cacd02294 43 }
jdawkins 0:bb2cacd02294 44 #endif
jdawkins 0:bb2cacd02294 45
jdawkins 0:bb2cacd02294 46 /**
jdawkins 0:bb2cacd02294 47 * @brief Reset the status of a channel.
jdawkins 0:bb2cacd02294 48 */
jdawkins 0:bb2cacd02294 49 MAVLINK_HELPER void mavlink_reset_channel_status(uint8_t chan)
jdawkins 0:bb2cacd02294 50 {
jdawkins 0:bb2cacd02294 51 mavlink_status_t *status = mavlink_get_channel_status(chan);
jdawkins 0:bb2cacd02294 52 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
jdawkins 0:bb2cacd02294 53 }
jdawkins 0:bb2cacd02294 54
jdawkins 0:bb2cacd02294 55 /**
jdawkins 0:bb2cacd02294 56 * @brief Finalize a MAVLink message with channel assignment
jdawkins 0:bb2cacd02294 57 *
jdawkins 0:bb2cacd02294 58 * This function calculates the checksum and sets length and aircraft id correctly.
jdawkins 0:bb2cacd02294 59 * It assumes that the message id and the payload are already correctly set. This function
jdawkins 0:bb2cacd02294 60 * can also be used if the message header has already been written before (as in mavlink_msg_xxx_pack
jdawkins 0:bb2cacd02294 61 * instead of mavlink_msg_xxx_pack_headerless), it just introduces little extra overhead.
jdawkins 0:bb2cacd02294 62 *
jdawkins 0:bb2cacd02294 63 * @param msg Message to finalize
jdawkins 0:bb2cacd02294 64 * @param system_id Id of the sending (this) system, 1-127
jdawkins 0:bb2cacd02294 65 * @param length Message length
jdawkins 0:bb2cacd02294 66 */
jdawkins 0:bb2cacd02294 67 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 68 MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
jdawkins 0:bb2cacd02294 69 uint8_t chan, uint8_t min_length, uint8_t length, uint8_t crc_extra)
jdawkins 0:bb2cacd02294 70 #else
jdawkins 0:bb2cacd02294 71 MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
jdawkins 0:bb2cacd02294 72 uint8_t chan, uint8_t length)
jdawkins 0:bb2cacd02294 73 #endif
jdawkins 0:bb2cacd02294 74 {
jdawkins 0:bb2cacd02294 75 // This is only used for the v2 protocol and we silence it here
jdawkins 0:bb2cacd02294 76 (void)min_length;
jdawkins 0:bb2cacd02294 77 // This code part is the same for all messages;
jdawkins 0:bb2cacd02294 78 msg->magic = MAVLINK_STX;
jdawkins 0:bb2cacd02294 79 msg->len = length;
jdawkins 0:bb2cacd02294 80 msg->sysid = system_id;
jdawkins 0:bb2cacd02294 81 msg->compid = component_id;
jdawkins 0:bb2cacd02294 82 // One sequence number per channel
jdawkins 0:bb2cacd02294 83 msg->seq = mavlink_get_channel_status(chan)->current_tx_seq;
jdawkins 0:bb2cacd02294 84 mavlink_get_channel_status(chan)->current_tx_seq = mavlink_get_channel_status(chan)->current_tx_seq+1;
jdawkins 0:bb2cacd02294 85 msg->checksum = crc_calculate(((const uint8_t*)(msg)) + 3, MAVLINK_CORE_HEADER_LEN);
jdawkins 0:bb2cacd02294 86 crc_accumulate_buffer(&msg->checksum, _MAV_PAYLOAD(msg), msg->len);
jdawkins 0:bb2cacd02294 87 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 88 crc_accumulate(crc_extra, &msg->checksum);
jdawkins 0:bb2cacd02294 89 #endif
jdawkins 0:bb2cacd02294 90 mavlink_ck_a(msg) = (uint8_t)(msg->checksum & 0xFF);
jdawkins 0:bb2cacd02294 91 mavlink_ck_b(msg) = (uint8_t)(msg->checksum >> 8);
jdawkins 0:bb2cacd02294 92
jdawkins 0:bb2cacd02294 93 return length + MAVLINK_NUM_NON_PAYLOAD_BYTES;
jdawkins 0:bb2cacd02294 94 }
jdawkins 0:bb2cacd02294 95
jdawkins 0:bb2cacd02294 96
jdawkins 0:bb2cacd02294 97 /**
jdawkins 0:bb2cacd02294 98 * @brief Finalize a MAVLink message with MAVLINK_COMM_0 as default channel
jdawkins 0:bb2cacd02294 99 */
jdawkins 0:bb2cacd02294 100 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 101 MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
jdawkins 0:bb2cacd02294 102 uint8_t min_length, uint8_t length, uint8_t crc_extra)
jdawkins 0:bb2cacd02294 103 {
jdawkins 0:bb2cacd02294 104 return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, min_length, length, crc_extra);
jdawkins 0:bb2cacd02294 105 }
jdawkins 0:bb2cacd02294 106 #else
jdawkins 0:bb2cacd02294 107 MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
jdawkins 0:bb2cacd02294 108 uint8_t length)
jdawkins 0:bb2cacd02294 109 {
jdawkins 0:bb2cacd02294 110 return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length);
jdawkins 0:bb2cacd02294 111 }
jdawkins 0:bb2cacd02294 112 #endif
jdawkins 0:bb2cacd02294 113
jdawkins 0:bb2cacd02294 114 #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
jdawkins 0:bb2cacd02294 115 MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len);
jdawkins 0:bb2cacd02294 116
jdawkins 0:bb2cacd02294 117 /**
jdawkins 0:bb2cacd02294 118 * @brief Finalize a MAVLink message with channel assignment and send
jdawkins 0:bb2cacd02294 119 */
jdawkins 0:bb2cacd02294 120 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 121 MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet,
jdawkins 0:bb2cacd02294 122 uint8_t min_length, uint8_t length, uint8_t crc_extra)
jdawkins 0:bb2cacd02294 123 #else
jdawkins 0:bb2cacd02294 124 MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length)
jdawkins 0:bb2cacd02294 125 #endif
jdawkins 0:bb2cacd02294 126 {
jdawkins 0:bb2cacd02294 127 uint16_t checksum;
jdawkins 0:bb2cacd02294 128 uint8_t buf[MAVLINK_NUM_HEADER_BYTES];
jdawkins 0:bb2cacd02294 129 uint8_t ck[2];
jdawkins 0:bb2cacd02294 130 mavlink_status_t *status = mavlink_get_channel_status(chan);
jdawkins 0:bb2cacd02294 131 buf[0] = MAVLINK_STX;
jdawkins 0:bb2cacd02294 132 buf[1] = length;
jdawkins 0:bb2cacd02294 133 buf[2] = status->current_tx_seq;
jdawkins 0:bb2cacd02294 134 buf[3] = mavlink_system.sysid;
jdawkins 0:bb2cacd02294 135 buf[4] = mavlink_system.compid;
jdawkins 0:bb2cacd02294 136 buf[5] = msgid;
jdawkins 0:bb2cacd02294 137 status->current_tx_seq++;
jdawkins 0:bb2cacd02294 138 checksum = crc_calculate((const uint8_t*)&buf[1], MAVLINK_CORE_HEADER_LEN);
jdawkins 0:bb2cacd02294 139 crc_accumulate_buffer(&checksum, packet, length);
jdawkins 0:bb2cacd02294 140 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 141 crc_accumulate(crc_extra, &checksum);
jdawkins 0:bb2cacd02294 142 #endif
jdawkins 0:bb2cacd02294 143 ck[0] = (uint8_t)(checksum & 0xFF);
jdawkins 0:bb2cacd02294 144 ck[1] = (uint8_t)(checksum >> 8);
jdawkins 0:bb2cacd02294 145
jdawkins 0:bb2cacd02294 146 MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length);
jdawkins 0:bb2cacd02294 147 _mavlink_send_uart(chan, (const char *)buf, MAVLINK_NUM_HEADER_BYTES);
jdawkins 0:bb2cacd02294 148 _mavlink_send_uart(chan, packet, length);
jdawkins 0:bb2cacd02294 149 _mavlink_send_uart(chan, (const char *)ck, 2);
jdawkins 0:bb2cacd02294 150 MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length);
jdawkins 0:bb2cacd02294 151 }
jdawkins 0:bb2cacd02294 152
jdawkins 0:bb2cacd02294 153 /**
jdawkins 0:bb2cacd02294 154 * @brief re-send a message over a uart channel
jdawkins 0:bb2cacd02294 155 * this is more stack efficient than re-marshalling the message
jdawkins 0:bb2cacd02294 156 */
jdawkins 0:bb2cacd02294 157 MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg)
jdawkins 0:bb2cacd02294 158 {
jdawkins 0:bb2cacd02294 159 uint8_t ck[2];
jdawkins 0:bb2cacd02294 160
jdawkins 0:bb2cacd02294 161 ck[0] = (uint8_t)(msg->checksum & 0xFF);
jdawkins 0:bb2cacd02294 162 ck[1] = (uint8_t)(msg->checksum >> 8);
jdawkins 0:bb2cacd02294 163 // XXX use the right sequence here
jdawkins 0:bb2cacd02294 164
jdawkins 0:bb2cacd02294 165 MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len);
jdawkins 0:bb2cacd02294 166 _mavlink_send_uart(chan, (const char *)&msg->magic, MAVLINK_NUM_HEADER_BYTES);
jdawkins 0:bb2cacd02294 167 _mavlink_send_uart(chan, _MAV_PAYLOAD(msg), msg->len);
jdawkins 0:bb2cacd02294 168 _mavlink_send_uart(chan, (const char *)ck, 2);
jdawkins 0:bb2cacd02294 169 MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len);
jdawkins 0:bb2cacd02294 170 }
jdawkins 0:bb2cacd02294 171 #endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS
jdawkins 0:bb2cacd02294 172
jdawkins 0:bb2cacd02294 173 /**
jdawkins 0:bb2cacd02294 174 * @brief Pack a message to send it over a serial byte stream
jdawkins 0:bb2cacd02294 175 */
jdawkins 0:bb2cacd02294 176 MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg)
jdawkins 0:bb2cacd02294 177 {
jdawkins 0:bb2cacd02294 178 memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
jdawkins 0:bb2cacd02294 179
jdawkins 0:bb2cacd02294 180 uint8_t *ck = buffer + (MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
jdawkins 0:bb2cacd02294 181
jdawkins 0:bb2cacd02294 182 ck[0] = (uint8_t)(msg->checksum & 0xFF);
jdawkins 0:bb2cacd02294 183 ck[1] = (uint8_t)(msg->checksum >> 8);
jdawkins 0:bb2cacd02294 184
jdawkins 0:bb2cacd02294 185 return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len;
jdawkins 0:bb2cacd02294 186 }
jdawkins 0:bb2cacd02294 187
jdawkins 0:bb2cacd02294 188 union __mavlink_bitfield {
jdawkins 0:bb2cacd02294 189 uint8_t uint8;
jdawkins 0:bb2cacd02294 190 int8_t int8;
jdawkins 0:bb2cacd02294 191 uint16_t uint16;
jdawkins 0:bb2cacd02294 192 int16_t int16;
jdawkins 0:bb2cacd02294 193 uint32_t uint32;
jdawkins 0:bb2cacd02294 194 int32_t int32;
jdawkins 0:bb2cacd02294 195 };
jdawkins 0:bb2cacd02294 196
jdawkins 0:bb2cacd02294 197
jdawkins 0:bb2cacd02294 198 MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t* msg)
jdawkins 0:bb2cacd02294 199 {
jdawkins 0:bb2cacd02294 200 crc_init(&msg->checksum);
jdawkins 0:bb2cacd02294 201 }
jdawkins 0:bb2cacd02294 202
jdawkins 0:bb2cacd02294 203 MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t* msg, uint8_t c)
jdawkins 0:bb2cacd02294 204 {
jdawkins 0:bb2cacd02294 205 crc_accumulate(c, &msg->checksum);
jdawkins 0:bb2cacd02294 206 }
jdawkins 0:bb2cacd02294 207
jdawkins 0:bb2cacd02294 208 /**
jdawkins 0:bb2cacd02294 209 * This is a varient of mavlink_frame_char() but with caller supplied
jdawkins 0:bb2cacd02294 210 * parsing buffers. It is useful when you want to create a MAVLink
jdawkins 0:bb2cacd02294 211 * parser in a library that doesn't use any global variables
jdawkins 0:bb2cacd02294 212 *
jdawkins 0:bb2cacd02294 213 * @param rxmsg parsing message buffer
jdawkins 0:bb2cacd02294 214 * @param status parsing starus buffer
jdawkins 0:bb2cacd02294 215 * @param c The char to parse
jdawkins 0:bb2cacd02294 216 *
jdawkins 0:bb2cacd02294 217 * @param returnMsg NULL if no message could be decoded, the message data else
jdawkins 0:bb2cacd02294 218 * @param returnStats if a message was decoded, this is filled with the channel's stats
jdawkins 0:bb2cacd02294 219 * @return 0 if no message could be decoded, 1 on good message and CRC, 2 on bad CRC
jdawkins 0:bb2cacd02294 220 *
jdawkins 0:bb2cacd02294 221 * A typical use scenario of this function call is:
jdawkins 0:bb2cacd02294 222 *
jdawkins 0:bb2cacd02294 223 * @code
jdawkins 0:bb2cacd02294 224 * #include <mavlink.h>
jdawkins 0:bb2cacd02294 225 *
jdawkins 0:bb2cacd02294 226 * mavlink_message_t msg;
jdawkins 0:bb2cacd02294 227 * int chan = 0;
jdawkins 0:bb2cacd02294 228 *
jdawkins 0:bb2cacd02294 229 *
jdawkins 0:bb2cacd02294 230 * while(serial.bytesAvailable > 0)
jdawkins 0:bb2cacd02294 231 * {
jdawkins 0:bb2cacd02294 232 * uint8_t byte = serial.getNextByte();
jdawkins 0:bb2cacd02294 233 * if (mavlink_frame_char(chan, byte, &msg) != MAVLINK_FRAMING_INCOMPLETE)
jdawkins 0:bb2cacd02294 234 * {
jdawkins 0:bb2cacd02294 235 * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
jdawkins 0:bb2cacd02294 236 * }
jdawkins 0:bb2cacd02294 237 * }
jdawkins 0:bb2cacd02294 238 *
jdawkins 0:bb2cacd02294 239 *
jdawkins 0:bb2cacd02294 240 * @endcode
jdawkins 0:bb2cacd02294 241 */
jdawkins 0:bb2cacd02294 242 MAVLINK_HELPER uint8_t mavlink_frame_char_buffer(mavlink_message_t* rxmsg,
jdawkins 0:bb2cacd02294 243 mavlink_status_t* status,
jdawkins 0:bb2cacd02294 244 uint8_t c,
jdawkins 0:bb2cacd02294 245 mavlink_message_t* r_message,
jdawkins 0:bb2cacd02294 246 mavlink_status_t* r_mavlink_status)
jdawkins 0:bb2cacd02294 247 {
jdawkins 0:bb2cacd02294 248 /*
jdawkins 0:bb2cacd02294 249 default message crc function. You can override this per-system to
jdawkins 0:bb2cacd02294 250 put this data in a different memory segment
jdawkins 0:bb2cacd02294 251 */
jdawkins 0:bb2cacd02294 252 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 253 #ifndef MAVLINK_MESSAGE_CRC
jdawkins 0:bb2cacd02294 254 static const uint8_t mavlink_message_crcs[256] = MAVLINK_MESSAGE_CRCS;
jdawkins 0:bb2cacd02294 255 #define MAVLINK_MESSAGE_CRC(msgid) mavlink_message_crcs[msgid]
jdawkins 0:bb2cacd02294 256 #endif
jdawkins 0:bb2cacd02294 257 #endif
jdawkins 0:bb2cacd02294 258
jdawkins 0:bb2cacd02294 259 /* Enable this option to check the length of each message.
jdawkins 0:bb2cacd02294 260 This allows invalid messages to be caught much sooner. Use if the transmission
jdawkins 0:bb2cacd02294 261 medium is prone to missing (or extra) characters (e.g. a radio that fades in
jdawkins 0:bb2cacd02294 262 and out). Only use if the channel will only contain messages types listed in
jdawkins 0:bb2cacd02294 263 the headers.
jdawkins 0:bb2cacd02294 264 */
jdawkins 0:bb2cacd02294 265 #ifdef MAVLINK_CHECK_MESSAGE_LENGTH
jdawkins 0:bb2cacd02294 266 #ifndef MAVLINK_MESSAGE_LENGTH
jdawkins 0:bb2cacd02294 267 static const uint8_t mavlink_message_lengths[256] = MAVLINK_MESSAGE_LENGTHS;
jdawkins 0:bb2cacd02294 268 #define MAVLINK_MESSAGE_LENGTH(msgid) mavlink_message_lengths[msgid]
jdawkins 0:bb2cacd02294 269 #endif
jdawkins 0:bb2cacd02294 270 #endif
jdawkins 0:bb2cacd02294 271
jdawkins 0:bb2cacd02294 272 int bufferIndex = 0;
jdawkins 0:bb2cacd02294 273
jdawkins 0:bb2cacd02294 274 status->msg_received = MAVLINK_FRAMING_INCOMPLETE;
jdawkins 0:bb2cacd02294 275
jdawkins 0:bb2cacd02294 276 switch (status->parse_state)
jdawkins 0:bb2cacd02294 277 {
jdawkins 0:bb2cacd02294 278 case MAVLINK_PARSE_STATE_UNINIT:
jdawkins 0:bb2cacd02294 279 case MAVLINK_PARSE_STATE_IDLE:
jdawkins 0:bb2cacd02294 280 if (c == MAVLINK_STX)
jdawkins 0:bb2cacd02294 281 {
jdawkins 0:bb2cacd02294 282 status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
jdawkins 0:bb2cacd02294 283 rxmsg->len = 0;
jdawkins 0:bb2cacd02294 284 rxmsg->magic = c;
jdawkins 0:bb2cacd02294 285 mavlink_start_checksum(rxmsg);
jdawkins 0:bb2cacd02294 286 }
jdawkins 0:bb2cacd02294 287 break;
jdawkins 0:bb2cacd02294 288
jdawkins 0:bb2cacd02294 289 case MAVLINK_PARSE_STATE_GOT_STX:
jdawkins 0:bb2cacd02294 290 if (status->msg_received
jdawkins 0:bb2cacd02294 291 /* Support shorter buffers than the
jdawkins 0:bb2cacd02294 292 default maximum packet size */
jdawkins 0:bb2cacd02294 293 #if (MAVLINK_MAX_PAYLOAD_LEN < 255)
jdawkins 0:bb2cacd02294 294 || c > MAVLINK_MAX_PAYLOAD_LEN
jdawkins 0:bb2cacd02294 295 #endif
jdawkins 0:bb2cacd02294 296 )
jdawkins 0:bb2cacd02294 297 {
jdawkins 0:bb2cacd02294 298 status->buffer_overrun++;
jdawkins 0:bb2cacd02294 299 status->parse_error++;
jdawkins 0:bb2cacd02294 300 status->msg_received = 0;
jdawkins 0:bb2cacd02294 301 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
jdawkins 0:bb2cacd02294 302 }
jdawkins 0:bb2cacd02294 303 else
jdawkins 0:bb2cacd02294 304 {
jdawkins 0:bb2cacd02294 305 // NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2
jdawkins 0:bb2cacd02294 306 rxmsg->len = c;
jdawkins 0:bb2cacd02294 307 status->packet_idx = 0;
jdawkins 0:bb2cacd02294 308 mavlink_update_checksum(rxmsg, c);
jdawkins 0:bb2cacd02294 309 status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH;
jdawkins 0:bb2cacd02294 310 }
jdawkins 0:bb2cacd02294 311 break;
jdawkins 0:bb2cacd02294 312
jdawkins 0:bb2cacd02294 313 case MAVLINK_PARSE_STATE_GOT_LENGTH:
jdawkins 0:bb2cacd02294 314 rxmsg->seq = c;
jdawkins 0:bb2cacd02294 315 mavlink_update_checksum(rxmsg, c);
jdawkins 0:bb2cacd02294 316 status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ;
jdawkins 0:bb2cacd02294 317 break;
jdawkins 0:bb2cacd02294 318
jdawkins 0:bb2cacd02294 319 case MAVLINK_PARSE_STATE_GOT_SEQ:
jdawkins 0:bb2cacd02294 320 rxmsg->sysid = c;
jdawkins 0:bb2cacd02294 321 mavlink_update_checksum(rxmsg, c);
jdawkins 0:bb2cacd02294 322 status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID;
jdawkins 0:bb2cacd02294 323 break;
jdawkins 0:bb2cacd02294 324
jdawkins 0:bb2cacd02294 325 case MAVLINK_PARSE_STATE_GOT_SYSID:
jdawkins 0:bb2cacd02294 326 rxmsg->compid = c;
jdawkins 0:bb2cacd02294 327 mavlink_update_checksum(rxmsg, c);
jdawkins 0:bb2cacd02294 328 status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID;
jdawkins 0:bb2cacd02294 329 break;
jdawkins 0:bb2cacd02294 330
jdawkins 0:bb2cacd02294 331 case MAVLINK_PARSE_STATE_GOT_COMPID:
jdawkins 0:bb2cacd02294 332 #ifdef MAVLINK_CHECK_MESSAGE_LENGTH
jdawkins 0:bb2cacd02294 333 if (rxmsg->len != MAVLINK_MESSAGE_LENGTH(c))
jdawkins 0:bb2cacd02294 334 {
jdawkins 0:bb2cacd02294 335 status->parse_error++;
jdawkins 0:bb2cacd02294 336 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
jdawkins 0:bb2cacd02294 337 break;
jdawkins 0:bb2cacd02294 338 }
jdawkins 0:bb2cacd02294 339 #endif
jdawkins 0:bb2cacd02294 340 rxmsg->msgid = c;
jdawkins 0:bb2cacd02294 341 mavlink_update_checksum(rxmsg, c);
jdawkins 0:bb2cacd02294 342 if (rxmsg->len == 0)
jdawkins 0:bb2cacd02294 343 {
jdawkins 0:bb2cacd02294 344 status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
jdawkins 0:bb2cacd02294 345 }
jdawkins 0:bb2cacd02294 346 else
jdawkins 0:bb2cacd02294 347 {
jdawkins 0:bb2cacd02294 348 status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID;
jdawkins 0:bb2cacd02294 349 }
jdawkins 0:bb2cacd02294 350 break;
jdawkins 0:bb2cacd02294 351
jdawkins 0:bb2cacd02294 352 case MAVLINK_PARSE_STATE_GOT_MSGID:
jdawkins 0:bb2cacd02294 353 _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx++] = (char)c;
jdawkins 0:bb2cacd02294 354 mavlink_update_checksum(rxmsg, c);
jdawkins 0:bb2cacd02294 355 if (status->packet_idx == rxmsg->len)
jdawkins 0:bb2cacd02294 356 {
jdawkins 0:bb2cacd02294 357 status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
jdawkins 0:bb2cacd02294 358 }
jdawkins 0:bb2cacd02294 359 break;
jdawkins 0:bb2cacd02294 360
jdawkins 0:bb2cacd02294 361 case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
jdawkins 0:bb2cacd02294 362 #if MAVLINK_CRC_EXTRA
jdawkins 0:bb2cacd02294 363 mavlink_update_checksum(rxmsg, MAVLINK_MESSAGE_CRC(rxmsg->msgid));
jdawkins 0:bb2cacd02294 364 #endif
jdawkins 0:bb2cacd02294 365 if (c != (rxmsg->checksum & 0xFF)) {
jdawkins 0:bb2cacd02294 366 status->parse_state = MAVLINK_PARSE_STATE_GOT_BAD_CRC1;
jdawkins 0:bb2cacd02294 367 } else {
jdawkins 0:bb2cacd02294 368 status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1;
jdawkins 0:bb2cacd02294 369 }
jdawkins 0:bb2cacd02294 370 _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx] = (char)c;
jdawkins 0:bb2cacd02294 371 break;
jdawkins 0:bb2cacd02294 372
jdawkins 0:bb2cacd02294 373 case MAVLINK_PARSE_STATE_GOT_CRC1:
jdawkins 0:bb2cacd02294 374 case MAVLINK_PARSE_STATE_GOT_BAD_CRC1:
jdawkins 0:bb2cacd02294 375 if (status->parse_state == MAVLINK_PARSE_STATE_GOT_BAD_CRC1 || c != (rxmsg->checksum >> 8)) {
jdawkins 0:bb2cacd02294 376 // got a bad CRC message
jdawkins 0:bb2cacd02294 377 status->msg_received = MAVLINK_FRAMING_BAD_CRC;
jdawkins 0:bb2cacd02294 378 } else {
jdawkins 0:bb2cacd02294 379 // Successfully got message
jdawkins 0:bb2cacd02294 380 status->msg_received = MAVLINK_FRAMING_OK;
jdawkins 0:bb2cacd02294 381 }
jdawkins 0:bb2cacd02294 382 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
jdawkins 0:bb2cacd02294 383 _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx+1] = (char)c;
jdawkins 0:bb2cacd02294 384 memcpy(r_message, rxmsg, sizeof(mavlink_message_t));
jdawkins 0:bb2cacd02294 385 break;
jdawkins 0:bb2cacd02294 386 }
jdawkins 0:bb2cacd02294 387
jdawkins 0:bb2cacd02294 388 bufferIndex++;
jdawkins 0:bb2cacd02294 389 // If a message has been sucessfully decoded, check index
jdawkins 0:bb2cacd02294 390 if (status->msg_received == MAVLINK_FRAMING_OK)
jdawkins 0:bb2cacd02294 391 {
jdawkins 0:bb2cacd02294 392 //while(status->current_seq != rxmsg->seq)
jdawkins 0:bb2cacd02294 393 //{
jdawkins 0:bb2cacd02294 394 // status->packet_rx_drop_count++;
jdawkins 0:bb2cacd02294 395 // status->current_seq++;
jdawkins 0:bb2cacd02294 396 //}
jdawkins 0:bb2cacd02294 397 status->current_rx_seq = rxmsg->seq;
jdawkins 0:bb2cacd02294 398 // Initial condition: If no packet has been received so far, drop count is undefined
jdawkins 0:bb2cacd02294 399 if (status->packet_rx_success_count == 0) status->packet_rx_drop_count = 0;
jdawkins 0:bb2cacd02294 400 // Count this packet as received
jdawkins 0:bb2cacd02294 401 status->packet_rx_success_count++;
jdawkins 0:bb2cacd02294 402 }
jdawkins 0:bb2cacd02294 403
jdawkins 0:bb2cacd02294 404 r_message->len = rxmsg->len; // Provide visibility on how far we are into current msg
jdawkins 0:bb2cacd02294 405 r_mavlink_status->parse_state = status->parse_state;
jdawkins 0:bb2cacd02294 406 r_mavlink_status->packet_idx = status->packet_idx;
jdawkins 0:bb2cacd02294 407 r_mavlink_status->current_rx_seq = status->current_rx_seq+1;
jdawkins 0:bb2cacd02294 408 r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count;
jdawkins 0:bb2cacd02294 409 r_mavlink_status->packet_rx_drop_count = status->parse_error;
jdawkins 0:bb2cacd02294 410 status->parse_error = 0;
jdawkins 0:bb2cacd02294 411
jdawkins 0:bb2cacd02294 412 if (status->msg_received == MAVLINK_FRAMING_BAD_CRC) {
jdawkins 0:bb2cacd02294 413 /*
jdawkins 0:bb2cacd02294 414 the CRC came out wrong. We now need to overwrite the
jdawkins 0:bb2cacd02294 415 msg CRC with the one on the wire so that if the
jdawkins 0:bb2cacd02294 416 caller decides to forward the message anyway that
jdawkins 0:bb2cacd02294 417 mavlink_msg_to_send_buffer() won't overwrite the
jdawkins 0:bb2cacd02294 418 checksum
jdawkins 0:bb2cacd02294 419 */
jdawkins 0:bb2cacd02294 420 r_message->checksum = _MAV_PAYLOAD(rxmsg)[status->packet_idx] | (_MAV_PAYLOAD(rxmsg)[status->packet_idx+1]<<8);
jdawkins 0:bb2cacd02294 421 }
jdawkins 0:bb2cacd02294 422
jdawkins 0:bb2cacd02294 423 return status->msg_received;
jdawkins 0:bb2cacd02294 424 }
jdawkins 0:bb2cacd02294 425
jdawkins 0:bb2cacd02294 426 /**
jdawkins 0:bb2cacd02294 427 * This is a convenience function which handles the complete MAVLink parsing.
jdawkins 0:bb2cacd02294 428 * the function will parse one byte at a time and return the complete packet once
jdawkins 0:bb2cacd02294 429 * it could be successfully decoded. This function will return 0, 1 or
jdawkins 0:bb2cacd02294 430 * 2 (MAVLINK_FRAMING_INCOMPLETE, MAVLINK_FRAMING_OK or MAVLINK_FRAMING_BAD_CRC)
jdawkins 0:bb2cacd02294 431 *
jdawkins 0:bb2cacd02294 432 * Messages are parsed into an internal buffer (one for each channel). When a complete
jdawkins 0:bb2cacd02294 433 * message is received it is copies into *returnMsg and the channel's status is
jdawkins 0:bb2cacd02294 434 * copied into *returnStats.
jdawkins 0:bb2cacd02294 435 *
jdawkins 0:bb2cacd02294 436 * @param chan ID of the current channel. This allows to parse different channels with this function.
jdawkins 0:bb2cacd02294 437 * a channel is not a physical message channel like a serial port, but a logic partition of
jdawkins 0:bb2cacd02294 438 * the communication streams in this case. COMM_NB is the limit for the number of channels
jdawkins 0:bb2cacd02294 439 * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
jdawkins 0:bb2cacd02294 440 * @param c The char to parse
jdawkins 0:bb2cacd02294 441 *
jdawkins 0:bb2cacd02294 442 * @param returnMsg NULL if no message could be decoded, the message data else
jdawkins 0:bb2cacd02294 443 * @param returnStats if a message was decoded, this is filled with the channel's stats
jdawkins 0:bb2cacd02294 444 * @return 0 if no message could be decoded, 1 on good message and CRC, 2 on bad CRC
jdawkins 0:bb2cacd02294 445 *
jdawkins 0:bb2cacd02294 446 * A typical use scenario of this function call is:
jdawkins 0:bb2cacd02294 447 *
jdawkins 0:bb2cacd02294 448 * @code
jdawkins 0:bb2cacd02294 449 * #include <mavlink.h>
jdawkins 0:bb2cacd02294 450 *
jdawkins 0:bb2cacd02294 451 * mavlink_message_t msg;
jdawkins 0:bb2cacd02294 452 * int chan = 0;
jdawkins 0:bb2cacd02294 453 *
jdawkins 0:bb2cacd02294 454 *
jdawkins 0:bb2cacd02294 455 * while(serial.bytesAvailable > 0)
jdawkins 0:bb2cacd02294 456 * {
jdawkins 0:bb2cacd02294 457 * uint8_t byte = serial.getNextByte();
jdawkins 0:bb2cacd02294 458 * if (mavlink_frame_char(chan, byte, &msg) != MAVLINK_FRAMING_INCOMPLETE)
jdawkins 0:bb2cacd02294 459 * {
jdawkins 0:bb2cacd02294 460 * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
jdawkins 0:bb2cacd02294 461 * }
jdawkins 0:bb2cacd02294 462 * }
jdawkins 0:bb2cacd02294 463 *
jdawkins 0:bb2cacd02294 464 *
jdawkins 0:bb2cacd02294 465 * @endcode
jdawkins 0:bb2cacd02294 466 */
jdawkins 0:bb2cacd02294 467 MAVLINK_HELPER uint8_t mavlink_frame_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
jdawkins 0:bb2cacd02294 468 {
jdawkins 0:bb2cacd02294 469 return mavlink_frame_char_buffer(mavlink_get_channel_buffer(chan),
jdawkins 0:bb2cacd02294 470 mavlink_get_channel_status(chan),
jdawkins 0:bb2cacd02294 471 c,
jdawkins 0:bb2cacd02294 472 r_message,
jdawkins 0:bb2cacd02294 473 r_mavlink_status);
jdawkins 0:bb2cacd02294 474 }
jdawkins 0:bb2cacd02294 475
jdawkins 0:bb2cacd02294 476
jdawkins 0:bb2cacd02294 477 /**
jdawkins 0:bb2cacd02294 478 * This is a convenience function which handles the complete MAVLink parsing.
jdawkins 0:bb2cacd02294 479 * the function will parse one byte at a time and return the complete packet once
jdawkins 0:bb2cacd02294 480 * it could be successfully decoded. This function will return 0 or 1.
jdawkins 0:bb2cacd02294 481 *
jdawkins 0:bb2cacd02294 482 * Messages are parsed into an internal buffer (one for each channel). When a complete
jdawkins 0:bb2cacd02294 483 * message is received it is copies into *returnMsg and the channel's status is
jdawkins 0:bb2cacd02294 484 * copied into *returnStats.
jdawkins 0:bb2cacd02294 485 *
jdawkins 0:bb2cacd02294 486 * @param chan ID of the current channel. This allows to parse different channels with this function.
jdawkins 0:bb2cacd02294 487 * a channel is not a physical message channel like a serial port, but a logic partition of
jdawkins 0:bb2cacd02294 488 * the communication streams in this case. COMM_NB is the limit for the number of channels
jdawkins 0:bb2cacd02294 489 * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
jdawkins 0:bb2cacd02294 490 * @param c The char to parse
jdawkins 0:bb2cacd02294 491 *
jdawkins 0:bb2cacd02294 492 * @param returnMsg NULL if no message could be decoded, the message data else
jdawkins 0:bb2cacd02294 493 * @param returnStats if a message was decoded, this is filled with the channel's stats
jdawkins 0:bb2cacd02294 494 * @return 0 if no message could be decoded or bad CRC, 1 on good message and CRC
jdawkins 0:bb2cacd02294 495 *
jdawkins 0:bb2cacd02294 496 * A typical use scenario of this function call is:
jdawkins 0:bb2cacd02294 497 *
jdawkins 0:bb2cacd02294 498 * @code
jdawkins 0:bb2cacd02294 499 * #include <mavlink.h>
jdawkins 0:bb2cacd02294 500 *
jdawkins 0:bb2cacd02294 501 * mavlink_message_t msg;
jdawkins 0:bb2cacd02294 502 * int chan = 0;
jdawkins 0:bb2cacd02294 503 *
jdawkins 0:bb2cacd02294 504 *
jdawkins 0:bb2cacd02294 505 * while(serial.bytesAvailable > 0)
jdawkins 0:bb2cacd02294 506 * {
jdawkins 0:bb2cacd02294 507 * uint8_t byte = serial.getNextByte();
jdawkins 0:bb2cacd02294 508 * if (mavlink_parse_char(chan, byte, &msg))
jdawkins 0:bb2cacd02294 509 * {
jdawkins 0:bb2cacd02294 510 * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
jdawkins 0:bb2cacd02294 511 * }
jdawkins 0:bb2cacd02294 512 * }
jdawkins 0:bb2cacd02294 513 *
jdawkins 0:bb2cacd02294 514 *
jdawkins 0:bb2cacd02294 515 * @endcode
jdawkins 0:bb2cacd02294 516 */
jdawkins 0:bb2cacd02294 517 MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
jdawkins 0:bb2cacd02294 518 {
jdawkins 0:bb2cacd02294 519 uint8_t msg_received = mavlink_frame_char(chan, c, r_message, r_mavlink_status);
jdawkins 0:bb2cacd02294 520 if (msg_received == MAVLINK_FRAMING_BAD_CRC) {
jdawkins 0:bb2cacd02294 521 // we got a bad CRC. Treat as a parse failure
jdawkins 0:bb2cacd02294 522 mavlink_message_t* rxmsg = mavlink_get_channel_buffer(chan);
jdawkins 0:bb2cacd02294 523 mavlink_status_t* status = mavlink_get_channel_status(chan);
jdawkins 0:bb2cacd02294 524 status->parse_error++;
jdawkins 0:bb2cacd02294 525 status->msg_received = MAVLINK_FRAMING_INCOMPLETE;
jdawkins 0:bb2cacd02294 526 status->parse_state = MAVLINK_PARSE_STATE_IDLE;
jdawkins 0:bb2cacd02294 527 if (c == MAVLINK_STX)
jdawkins 0:bb2cacd02294 528 {
jdawkins 0:bb2cacd02294 529 status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
jdawkins 0:bb2cacd02294 530 rxmsg->len = 0;
jdawkins 0:bb2cacd02294 531 mavlink_start_checksum(rxmsg);
jdawkins 0:bb2cacd02294 532 }
jdawkins 0:bb2cacd02294 533 return 0;
jdawkins 0:bb2cacd02294 534 }
jdawkins 0:bb2cacd02294 535 return msg_received;
jdawkins 0:bb2cacd02294 536 }
jdawkins 0:bb2cacd02294 537
jdawkins 0:bb2cacd02294 538 /**
jdawkins 0:bb2cacd02294 539 * @brief Put a bitfield of length 1-32 bit into the buffer
jdawkins 0:bb2cacd02294 540 *
jdawkins 0:bb2cacd02294 541 * @param b the value to add, will be encoded in the bitfield
jdawkins 0:bb2cacd02294 542 * @param bits number of bits to use to encode b, e.g. 1 for boolean, 2, 3, etc.
jdawkins 0:bb2cacd02294 543 * @param packet_index the position in the packet (the index of the first byte to use)
jdawkins 0:bb2cacd02294 544 * @param bit_index the position in the byte (the index of the first bit to use)
jdawkins 0:bb2cacd02294 545 * @param buffer packet buffer to write into
jdawkins 0:bb2cacd02294 546 * @return new position of the last used byte in the buffer
jdawkins 0:bb2cacd02294 547 */
jdawkins 0:bb2cacd02294 548 MAVLINK_HELPER 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)
jdawkins 0:bb2cacd02294 549 {
jdawkins 0:bb2cacd02294 550 uint16_t bits_remain = bits;
jdawkins 0:bb2cacd02294 551 // Transform number into network order
jdawkins 0:bb2cacd02294 552 int32_t v;
jdawkins 0:bb2cacd02294 553 uint8_t i_bit_index, i_byte_index, curr_bits_n;
jdawkins 0:bb2cacd02294 554 #if MAVLINK_NEED_BYTE_SWAP
jdawkins 0:bb2cacd02294 555 union {
jdawkins 0:bb2cacd02294 556 int32_t i;
jdawkins 0:bb2cacd02294 557 uint8_t b[4];
jdawkins 0:bb2cacd02294 558 } bin, bout;
jdawkins 0:bb2cacd02294 559 bin.i = b;
jdawkins 0:bb2cacd02294 560 bout.b[0] = bin.b[3];
jdawkins 0:bb2cacd02294 561 bout.b[1] = bin.b[2];
jdawkins 0:bb2cacd02294 562 bout.b[2] = bin.b[1];
jdawkins 0:bb2cacd02294 563 bout.b[3] = bin.b[0];
jdawkins 0:bb2cacd02294 564 v = bout.i;
jdawkins 0:bb2cacd02294 565 #else
jdawkins 0:bb2cacd02294 566 v = b;
jdawkins 0:bb2cacd02294 567 #endif
jdawkins 0:bb2cacd02294 568
jdawkins 0:bb2cacd02294 569 // buffer in
jdawkins 0:bb2cacd02294 570 // 01100000 01000000 00000000 11110001
jdawkins 0:bb2cacd02294 571 // buffer out
jdawkins 0:bb2cacd02294 572 // 11110001 00000000 01000000 01100000
jdawkins 0:bb2cacd02294 573
jdawkins 0:bb2cacd02294 574 // Existing partly filled byte (four free slots)
jdawkins 0:bb2cacd02294 575 // 0111xxxx
jdawkins 0:bb2cacd02294 576
jdawkins 0:bb2cacd02294 577 // Mask n free bits
jdawkins 0:bb2cacd02294 578 // 00001111 = 2^0 + 2^1 + 2^2 + 2^3 = 2^n - 1
jdawkins 0:bb2cacd02294 579 // = ((uint32_t)(1 << n)) - 1; // = 2^n - 1
jdawkins 0:bb2cacd02294 580
jdawkins 0:bb2cacd02294 581 // Shift n bits into the right position
jdawkins 0:bb2cacd02294 582 // out = in >> n;
jdawkins 0:bb2cacd02294 583
jdawkins 0:bb2cacd02294 584 // Mask and shift bytes
jdawkins 0:bb2cacd02294 585 i_bit_index = bit_index;
jdawkins 0:bb2cacd02294 586 i_byte_index = packet_index;
jdawkins 0:bb2cacd02294 587 if (bit_index > 0)
jdawkins 0:bb2cacd02294 588 {
jdawkins 0:bb2cacd02294 589 // If bits were available at start, they were available
jdawkins 0:bb2cacd02294 590 // in the byte before the current index
jdawkins 0:bb2cacd02294 591 i_byte_index--;
jdawkins 0:bb2cacd02294 592 }
jdawkins 0:bb2cacd02294 593
jdawkins 0:bb2cacd02294 594 // While bits have not been packed yet
jdawkins 0:bb2cacd02294 595 while (bits_remain > 0)
jdawkins 0:bb2cacd02294 596 {
jdawkins 0:bb2cacd02294 597 // Bits still have to be packed
jdawkins 0:bb2cacd02294 598 // there can be more than 8 bits, so
jdawkins 0:bb2cacd02294 599 // we might have to pack them into more than one byte
jdawkins 0:bb2cacd02294 600
jdawkins 0:bb2cacd02294 601 // First pack everything we can into the current 'open' byte
jdawkins 0:bb2cacd02294 602 //curr_bits_n = bits_remain << 3; // Equals bits_remain mod 8
jdawkins 0:bb2cacd02294 603 //FIXME
jdawkins 0:bb2cacd02294 604 if (bits_remain <= (uint8_t)(8 - i_bit_index))
jdawkins 0:bb2cacd02294 605 {
jdawkins 0:bb2cacd02294 606 // Enough space
jdawkins 0:bb2cacd02294 607 curr_bits_n = (uint8_t)bits_remain;
jdawkins 0:bb2cacd02294 608 }
jdawkins 0:bb2cacd02294 609 else
jdawkins 0:bb2cacd02294 610 {
jdawkins 0:bb2cacd02294 611 curr_bits_n = (8 - i_bit_index);
jdawkins 0:bb2cacd02294 612 }
jdawkins 0:bb2cacd02294 613
jdawkins 0:bb2cacd02294 614 // Pack these n bits into the current byte
jdawkins 0:bb2cacd02294 615 // Mask out whatever was at that position with ones (xxx11111)
jdawkins 0:bb2cacd02294 616 buffer[i_byte_index] &= (0xFF >> (8 - curr_bits_n));
jdawkins 0:bb2cacd02294 617 // Put content to this position, by masking out the non-used part
jdawkins 0:bb2cacd02294 618 buffer[i_byte_index] |= ((0x00 << curr_bits_n) & v);
jdawkins 0:bb2cacd02294 619
jdawkins 0:bb2cacd02294 620 // Increment the bit index
jdawkins 0:bb2cacd02294 621 i_bit_index += curr_bits_n;
jdawkins 0:bb2cacd02294 622
jdawkins 0:bb2cacd02294 623 // Now proceed to the next byte, if necessary
jdawkins 0:bb2cacd02294 624 bits_remain -= curr_bits_n;
jdawkins 0:bb2cacd02294 625 if (bits_remain > 0)
jdawkins 0:bb2cacd02294 626 {
jdawkins 0:bb2cacd02294 627 // Offer another 8 bits / one byte
jdawkins 0:bb2cacd02294 628 i_byte_index++;
jdawkins 0:bb2cacd02294 629 i_bit_index = 0;
jdawkins 0:bb2cacd02294 630 }
jdawkins 0:bb2cacd02294 631 }
jdawkins 0:bb2cacd02294 632
jdawkins 0:bb2cacd02294 633 *r_bit_index = i_bit_index;
jdawkins 0:bb2cacd02294 634 // If a partly filled byte is present, mark this as consumed
jdawkins 0:bb2cacd02294 635 if (i_bit_index != 7) i_byte_index++;
jdawkins 0:bb2cacd02294 636 return i_byte_index - packet_index;
jdawkins 0:bb2cacd02294 637 }
jdawkins 0:bb2cacd02294 638
jdawkins 0:bb2cacd02294 639 #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
jdawkins 0:bb2cacd02294 640
jdawkins 0:bb2cacd02294 641 // To make MAVLink work on your MCU, define comm_send_ch() if you wish
jdawkins 0:bb2cacd02294 642 // to send 1 byte at a time, or MAVLINK_SEND_UART_BYTES() to send a
jdawkins 0:bb2cacd02294 643 // whole packet at a time
jdawkins 0:bb2cacd02294 644
jdawkins 0:bb2cacd02294 645 /*
jdawkins 0:bb2cacd02294 646
jdawkins 0:bb2cacd02294 647 #include "mavlink_types.h"
jdawkins 0:bb2cacd02294 648
jdawkins 0:bb2cacd02294 649 void comm_send_ch(mavlink_channel_t chan, uint8_t ch)
jdawkins 0:bb2cacd02294 650 {
jdawkins 0:bb2cacd02294 651 if (chan == MAVLINK_COMM_0)
jdawkins 0:bb2cacd02294 652 {
jdawkins 0:bb2cacd02294 653 uart0_transmit(ch);
jdawkins 0:bb2cacd02294 654 }
jdawkins 0:bb2cacd02294 655 if (chan == MAVLINK_COMM_1)
jdawkins 0:bb2cacd02294 656 {
jdawkins 0:bb2cacd02294 657 uart1_transmit(ch);
jdawkins 0:bb2cacd02294 658 }
jdawkins 0:bb2cacd02294 659 }
jdawkins 0:bb2cacd02294 660 */
jdawkins 0:bb2cacd02294 661
jdawkins 0:bb2cacd02294 662 MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len)
jdawkins 0:bb2cacd02294 663 {
jdawkins 0:bb2cacd02294 664 #ifdef MAVLINK_SEND_UART_BYTES
jdawkins 0:bb2cacd02294 665 /* this is the more efficient approach, if the platform
jdawkins 0:bb2cacd02294 666 defines it */
jdawkins 0:bb2cacd02294 667 MAVLINK_SEND_UART_BYTES(chan, (const uint8_t *)buf, len);
jdawkins 0:bb2cacd02294 668 #else
jdawkins 0:bb2cacd02294 669 /* fallback to one byte at a time */
jdawkins 0:bb2cacd02294 670 uint16_t i;
jdawkins 0:bb2cacd02294 671 for (i = 0; i < len; i++) {
jdawkins 0:bb2cacd02294 672 comm_send_ch(chan, (uint8_t)buf[i]);
jdawkins 0:bb2cacd02294 673 }
jdawkins 0:bb2cacd02294 674 #endif
jdawkins 0:bb2cacd02294 675 }
jdawkins 0:bb2cacd02294 676 #endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS
jdawkins 0:bb2cacd02294 677
jdawkins 0:bb2cacd02294 678 #endif /* _MAVLINK_HELPERS_H_ */
jdawkins 0:bb2cacd02294 679