Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-rtos mbed Xbus
Fork of MTi-1_example by
xbus/xbusparser.c@10:18a6661b7e59, 2015-05-13 (annotated)
- Committer:
- Alex Young
- Date:
- Wed May 13 17:42:38 2015 +0200
- Revision:
- 10:18a6661b7e59
- Parent:
- 9:e4dc986e59f6
- Child:
- 14:155f9a55ec51
Add basic support for formatting xbus messages.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Alex Young |
3:abc451d82b88 | 1 | /*! |
| Alex Young |
3:abc451d82b88 | 2 | * \file |
| Alex Young |
3:abc451d82b88 | 3 | * \copyright |
| Alex Young |
3:abc451d82b88 | 4 | * Copyright (C) Xsens Technologies B.V., 2015. All rights reserved. |
| Alex Young |
3:abc451d82b88 | 5 | * |
| Alex Young |
3:abc451d82b88 | 6 | * This source code is intended for use only by Xsens Technologies BV and |
| Alex Young |
3:abc451d82b88 | 7 | * those that have explicit written permission to use it from |
| Alex Young |
3:abc451d82b88 | 8 | * Xsens Technologies BV. |
| Alex Young |
3:abc451d82b88 | 9 | * |
| Alex Young |
3:abc451d82b88 | 10 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY |
| Alex Young |
3:abc451d82b88 | 11 | * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
| Alex Young |
3:abc451d82b88 | 12 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A |
| Alex Young |
3:abc451d82b88 | 13 | * PARTICULAR PURPOSE. |
| Alex Young |
3:abc451d82b88 | 14 | */ |
| Alex Young |
3:abc451d82b88 | 15 | |
| Alex Young |
3:abc451d82b88 | 16 | #include "xbusparser.h" |
| Alex Young |
10:18a6661b7e59 | 17 | #include "xbusdef.h" |
| Alex Young |
3:abc451d82b88 | 18 | #include <stdlib.h> |
| Alex Young |
3:abc451d82b88 | 19 | |
| Alex Young |
3:abc451d82b88 | 20 | enum XbusParserState |
| Alex Young |
3:abc451d82b88 | 21 | { |
| Alex Young |
3:abc451d82b88 | 22 | XBPS_Preamble, /*!< \brief Looking for preamble. */ |
| Alex Young |
3:abc451d82b88 | 23 | XBPS_BusId, /*!< \brief Waiting for bus ID. */ |
| Alex Young |
3:abc451d82b88 | 24 | XBPS_MessageId, /*!< \brief Waiting for message ID. */ |
| Alex Young |
3:abc451d82b88 | 25 | XBPS_Length, /*!< \brief Waiting for length. */ |
| Alex Young |
3:abc451d82b88 | 26 | XBPS_ExtendedLengthMsb, /*!< \brief Waiting for extended length MSB*/ |
| Alex Young |
3:abc451d82b88 | 27 | XBPS_ExtendedLengthLsb, /*!< \brief Waiting for extended length LSB*/ |
| Alex Young |
3:abc451d82b88 | 28 | XBPS_Payload, /*!< \brief Reading payload. */ |
| Alex Young |
3:abc451d82b88 | 29 | XBPS_Checksum /*!< \brief Waiting for checksum. */ |
| Alex Young |
3:abc451d82b88 | 30 | }; |
| Alex Young |
3:abc451d82b88 | 31 | |
| Alex Young |
3:abc451d82b88 | 32 | struct XbusParser |
| Alex Young |
3:abc451d82b88 | 33 | { |
| Alex Young |
3:abc451d82b88 | 34 | struct XbusParserCallback callbacks; |
| Alex Young |
3:abc451d82b88 | 35 | uint8_t* messageBuffer; |
| Alex Young |
3:abc451d82b88 | 36 | uint16_t currentMessageLength; |
| Alex Young |
3:abc451d82b88 | 37 | uint16_t payloadReceived; |
| Alex Young |
3:abc451d82b88 | 38 | uint8_t currentMessageId; |
| Alex Young |
3:abc451d82b88 | 39 | uint8_t checksum; |
| Alex Young |
3:abc451d82b88 | 40 | enum XbusParserState state; |
| Alex Young |
3:abc451d82b88 | 41 | }; |
| Alex Young |
3:abc451d82b88 | 42 | |
| Alex Young |
3:abc451d82b88 | 43 | size_t XbusParser_mem(void) |
| Alex Young |
3:abc451d82b88 | 44 | { |
| Alex Young |
3:abc451d82b88 | 45 | return sizeof(struct XbusParser); |
| Alex Young |
3:abc451d82b88 | 46 | } |
| Alex Young |
3:abc451d82b88 | 47 | |
| Alex Young |
3:abc451d82b88 | 48 | struct XbusParser* XbusParser_create(struct XbusParserCallback const* callback) |
| Alex Young |
3:abc451d82b88 | 49 | { |
| Alex Young |
3:abc451d82b88 | 50 | void* mem = malloc(XbusParser_mem()); |
| Alex Young |
3:abc451d82b88 | 51 | if (mem) |
| Alex Young |
3:abc451d82b88 | 52 | { |
| Alex Young |
3:abc451d82b88 | 53 | return XbusParser_init(mem, callback); |
| Alex Young |
3:abc451d82b88 | 54 | } |
| Alex Young |
3:abc451d82b88 | 55 | return NULL; |
| Alex Young |
3:abc451d82b88 | 56 | } |
| Alex Young |
3:abc451d82b88 | 57 | |
| Alex Young |
3:abc451d82b88 | 58 | void XbusParser_destroy(struct XbusParser* parser) |
| Alex Young |
3:abc451d82b88 | 59 | { |
| Alex Young |
3:abc451d82b88 | 60 | free(parser); |
| Alex Young |
3:abc451d82b88 | 61 | } |
| Alex Young |
3:abc451d82b88 | 62 | |
| Alex Young |
3:abc451d82b88 | 63 | struct XbusParser* XbusParser_init(void* parserMem, struct XbusParserCallback const* callback) |
| Alex Young |
3:abc451d82b88 | 64 | { |
| Alex Young |
3:abc451d82b88 | 65 | struct XbusParser* parser = (struct XbusParser*)parserMem; |
| Alex Young |
3:abc451d82b88 | 66 | parser->state = XBPS_Preamble; |
| Alex Young |
3:abc451d82b88 | 67 | parser->callbacks.allocateBuffer = callback->allocateBuffer; |
| Alex Young |
3:abc451d82b88 | 68 | parser->callbacks.handleMessage = callback->handleMessage; |
| Alex Young |
3:abc451d82b88 | 69 | return parser; |
| Alex Young |
3:abc451d82b88 | 70 | } |
| Alex Young |
3:abc451d82b88 | 71 | |
| Alex Young |
3:abc451d82b88 | 72 | static void prepareForPayload(struct XbusParser* parser) |
| Alex Young |
3:abc451d82b88 | 73 | { |
| Alex Young |
3:abc451d82b88 | 74 | parser->messageBuffer = parser->callbacks.allocateBuffer(parser->currentMessageLength); |
| Alex Young |
3:abc451d82b88 | 75 | parser->payloadReceived = 0; |
| Alex Young |
3:abc451d82b88 | 76 | } |
| Alex Young |
3:abc451d82b88 | 77 | |
| Alex Young |
3:abc451d82b88 | 78 | void XbusParser_parseByte(struct XbusParser* parser, const uint8_t byte) |
| Alex Young |
3:abc451d82b88 | 79 | { |
| Alex Young |
3:abc451d82b88 | 80 | switch (parser->state) |
| Alex Young |
3:abc451d82b88 | 81 | { |
| Alex Young |
3:abc451d82b88 | 82 | case XBPS_Preamble: |
| Alex Young |
3:abc451d82b88 | 83 | if (byte == XBUS_PREAMBLE) |
| Alex Young |
3:abc451d82b88 | 84 | { |
| Alex Young |
3:abc451d82b88 | 85 | parser->checksum = 0; |
| Alex Young |
3:abc451d82b88 | 86 | parser->state = XBPS_BusId; |
| Alex Young |
3:abc451d82b88 | 87 | } |
| Alex Young |
3:abc451d82b88 | 88 | break; |
| Alex Young |
3:abc451d82b88 | 89 | |
| Alex Young |
3:abc451d82b88 | 90 | case XBPS_BusId: |
| Alex Young |
3:abc451d82b88 | 91 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 92 | parser->state = XBPS_MessageId; |
| Alex Young |
3:abc451d82b88 | 93 | break; |
| Alex Young |
3:abc451d82b88 | 94 | |
| Alex Young |
3:abc451d82b88 | 95 | case XBPS_MessageId: |
| Alex Young |
3:abc451d82b88 | 96 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 97 | parser->currentMessageId = byte; |
| Alex Young |
3:abc451d82b88 | 98 | parser->state = XBPS_Length; |
| Alex Young |
3:abc451d82b88 | 99 | break; |
| Alex Young |
3:abc451d82b88 | 100 | |
| Alex Young |
3:abc451d82b88 | 101 | case XBPS_Length: |
| Alex Young |
3:abc451d82b88 | 102 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 103 | if (byte == XBUS_NO_PAYLOAD) |
| Alex Young |
3:abc451d82b88 | 104 | { |
| Alex Young |
9:e4dc986e59f6 | 105 | parser->currentMessageLength = byte; |
| Alex Young |
3:abc451d82b88 | 106 | parser->state = XBPS_Checksum; |
| Alex Young |
3:abc451d82b88 | 107 | } |
| Alex Young |
3:abc451d82b88 | 108 | else if (byte < XBUS_EXTENDED_LENGTH) |
| Alex Young |
3:abc451d82b88 | 109 | { |
| Alex Young |
3:abc451d82b88 | 110 | parser->currentMessageLength = byte; |
| Alex Young |
3:abc451d82b88 | 111 | prepareForPayload(parser); |
| Alex Young |
3:abc451d82b88 | 112 | parser->state = XBPS_Payload; |
| Alex Young |
3:abc451d82b88 | 113 | } |
| Alex Young |
3:abc451d82b88 | 114 | else |
| Alex Young |
3:abc451d82b88 | 115 | { |
| Alex Young |
3:abc451d82b88 | 116 | parser->state = XBPS_ExtendedLengthMsb; |
| Alex Young |
3:abc451d82b88 | 117 | } |
| Alex Young |
3:abc451d82b88 | 118 | break; |
| Alex Young |
3:abc451d82b88 | 119 | |
| Alex Young |
3:abc451d82b88 | 120 | case XBPS_ExtendedLengthMsb: |
| Alex Young |
3:abc451d82b88 | 121 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 122 | parser->currentMessageLength = ((uint16_t)byte) << 8; |
| Alex Young |
3:abc451d82b88 | 123 | parser->state = XBPS_ExtendedLengthLsb; |
| Alex Young |
3:abc451d82b88 | 124 | break; |
| Alex Young |
3:abc451d82b88 | 125 | |
| Alex Young |
3:abc451d82b88 | 126 | case XBPS_ExtendedLengthLsb: |
| Alex Young |
3:abc451d82b88 | 127 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 128 | parser->currentMessageLength |= byte; |
| Alex Young |
3:abc451d82b88 | 129 | prepareForPayload(parser); |
| Alex Young |
3:abc451d82b88 | 130 | parser->state = XBPS_Payload; |
| Alex Young |
3:abc451d82b88 | 131 | break; |
| Alex Young |
3:abc451d82b88 | 132 | |
| Alex Young |
3:abc451d82b88 | 133 | case XBPS_Payload: |
| Alex Young |
3:abc451d82b88 | 134 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 135 | if (parser->messageBuffer) |
| Alex Young |
3:abc451d82b88 | 136 | { |
| Alex Young |
3:abc451d82b88 | 137 | parser->messageBuffer[parser->payloadReceived] = byte; |
| Alex Young |
3:abc451d82b88 | 138 | } |
| Alex Young |
3:abc451d82b88 | 139 | if (++parser->payloadReceived == parser->currentMessageLength) |
| Alex Young |
3:abc451d82b88 | 140 | { |
| Alex Young |
3:abc451d82b88 | 141 | parser->state = XBPS_Checksum; |
| Alex Young |
3:abc451d82b88 | 142 | } |
| Alex Young |
3:abc451d82b88 | 143 | break; |
| Alex Young |
3:abc451d82b88 | 144 | |
| Alex Young |
3:abc451d82b88 | 145 | case XBPS_Checksum: |
| Alex Young |
3:abc451d82b88 | 146 | parser->checksum += byte; |
| Alex Young |
3:abc451d82b88 | 147 | if ((parser->checksum == 0) && parser->messageBuffer) |
| Alex Young |
3:abc451d82b88 | 148 | { |
| Alex Young |
3:abc451d82b88 | 149 | parser->callbacks.handleMessage(parser->currentMessageId, |
| Alex Young |
3:abc451d82b88 | 150 | parser->currentMessageLength, |
| Alex Young |
3:abc451d82b88 | 151 | parser->messageBuffer); |
| Alex Young |
3:abc451d82b88 | 152 | } |
| Alex Young |
3:abc451d82b88 | 153 | parser->state = XBPS_Preamble; |
| Alex Young |
3:abc451d82b88 | 154 | break; |
| Alex Young |
3:abc451d82b88 | 155 | } |
| Alex Young |
3:abc451d82b88 | 156 | } |
| Alex Young |
3:abc451d82b88 | 157 | |
| Alex Young |
3:abc451d82b88 | 158 | void XbusParser_parseBuffer(struct XbusParser* parser, uint8_t const* buf, size_t bufSize) |
| Alex Young |
3:abc451d82b88 | 159 | { |
| Alex Young |
3:abc451d82b88 | 160 | for (size_t i = 0; i < bufSize; ++i) |
| Alex Young |
3:abc451d82b88 | 161 | { |
| Alex Young |
3:abc451d82b88 | 162 | XbusParser_parseByte(parser, buf[i]); |
| Alex Young |
3:abc451d82b88 | 163 | } |
| Alex Young |
3:abc451d82b88 | 164 | } |
| Alex Young |
3:abc451d82b88 | 165 |
