Gabriel Delgado / Mbed 2 deprecated MTi-1_uart

Dependencies:   mbed mbed-rtos Xbus

Committer:
Alex Young
Date:
Wed May 13 12:00:28 2015 +0200
Revision:
3:abc451d82b88
Child:
9:e4dc986e59f6
Add basic Xbus parser implementation.

Who changed what in which revision?

UserRevisionLine numberNew 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 3:abc451d82b88 17 #include <stdlib.h>
Alex Young 3:abc451d82b88 18
Alex Young 3:abc451d82b88 19 #define XBUS_PREAMBLE (0xFA)
Alex Young 3:abc451d82b88 20 #define XBUS_NO_PAYLOAD (0x00)
Alex Young 3:abc451d82b88 21 #define XBUS_EXTENDED_LENGTH (0xFF)
Alex Young 3:abc451d82b88 22
Alex Young 3:abc451d82b88 23 enum XbusParserState
Alex Young 3:abc451d82b88 24 {
Alex Young 3:abc451d82b88 25 XBPS_Preamble, /*!< \brief Looking for preamble. */
Alex Young 3:abc451d82b88 26 XBPS_BusId, /*!< \brief Waiting for bus ID. */
Alex Young 3:abc451d82b88 27 XBPS_MessageId, /*!< \brief Waiting for message ID. */
Alex Young 3:abc451d82b88 28 XBPS_Length, /*!< \brief Waiting for length. */
Alex Young 3:abc451d82b88 29 XBPS_ExtendedLengthMsb, /*!< \brief Waiting for extended length MSB*/
Alex Young 3:abc451d82b88 30 XBPS_ExtendedLengthLsb, /*!< \brief Waiting for extended length LSB*/
Alex Young 3:abc451d82b88 31 XBPS_Payload, /*!< \brief Reading payload. */
Alex Young 3:abc451d82b88 32 XBPS_Checksum /*!< \brief Waiting for checksum. */
Alex Young 3:abc451d82b88 33 };
Alex Young 3:abc451d82b88 34
Alex Young 3:abc451d82b88 35 struct XbusParser
Alex Young 3:abc451d82b88 36 {
Alex Young 3:abc451d82b88 37 struct XbusParserCallback callbacks;
Alex Young 3:abc451d82b88 38 uint8_t* messageBuffer;
Alex Young 3:abc451d82b88 39 uint16_t currentMessageLength;
Alex Young 3:abc451d82b88 40 uint16_t payloadReceived;
Alex Young 3:abc451d82b88 41 uint8_t currentMessageId;
Alex Young 3:abc451d82b88 42 uint8_t checksum;
Alex Young 3:abc451d82b88 43 enum XbusParserState state;
Alex Young 3:abc451d82b88 44 };
Alex Young 3:abc451d82b88 45
Alex Young 3:abc451d82b88 46 size_t XbusParser_mem(void)
Alex Young 3:abc451d82b88 47 {
Alex Young 3:abc451d82b88 48 return sizeof(struct XbusParser);
Alex Young 3:abc451d82b88 49 }
Alex Young 3:abc451d82b88 50
Alex Young 3:abc451d82b88 51 struct XbusParser* XbusParser_create(struct XbusParserCallback const* callback)
Alex Young 3:abc451d82b88 52 {
Alex Young 3:abc451d82b88 53 void* mem = malloc(XbusParser_mem());
Alex Young 3:abc451d82b88 54 if (mem)
Alex Young 3:abc451d82b88 55 {
Alex Young 3:abc451d82b88 56 return XbusParser_init(mem, callback);
Alex Young 3:abc451d82b88 57 }
Alex Young 3:abc451d82b88 58 return NULL;
Alex Young 3:abc451d82b88 59 }
Alex Young 3:abc451d82b88 60
Alex Young 3:abc451d82b88 61 void XbusParser_destroy(struct XbusParser* parser)
Alex Young 3:abc451d82b88 62 {
Alex Young 3:abc451d82b88 63 free(parser);
Alex Young 3:abc451d82b88 64 }
Alex Young 3:abc451d82b88 65
Alex Young 3:abc451d82b88 66 struct XbusParser* XbusParser_init(void* parserMem, struct XbusParserCallback const* callback)
Alex Young 3:abc451d82b88 67 {
Alex Young 3:abc451d82b88 68 struct XbusParser* parser = (struct XbusParser*)parserMem;
Alex Young 3:abc451d82b88 69 parser->state = XBPS_Preamble;
Alex Young 3:abc451d82b88 70 parser->callbacks.allocateBuffer = callback->allocateBuffer;
Alex Young 3:abc451d82b88 71 parser->callbacks.handleMessage = callback->handleMessage;
Alex Young 3:abc451d82b88 72 return parser;
Alex Young 3:abc451d82b88 73 }
Alex Young 3:abc451d82b88 74
Alex Young 3:abc451d82b88 75 static void prepareForPayload(struct XbusParser* parser)
Alex Young 3:abc451d82b88 76 {
Alex Young 3:abc451d82b88 77 parser->messageBuffer = parser->callbacks.allocateBuffer(parser->currentMessageLength);
Alex Young 3:abc451d82b88 78 parser->payloadReceived = 0;
Alex Young 3:abc451d82b88 79 }
Alex Young 3:abc451d82b88 80
Alex Young 3:abc451d82b88 81 void XbusParser_parseByte(struct XbusParser* parser, const uint8_t byte)
Alex Young 3:abc451d82b88 82 {
Alex Young 3:abc451d82b88 83 switch (parser->state)
Alex Young 3:abc451d82b88 84 {
Alex Young 3:abc451d82b88 85 case XBPS_Preamble:
Alex Young 3:abc451d82b88 86 if (byte == XBUS_PREAMBLE)
Alex Young 3:abc451d82b88 87 {
Alex Young 3:abc451d82b88 88 parser->checksum = 0;
Alex Young 3:abc451d82b88 89 parser->state = XBPS_BusId;
Alex Young 3:abc451d82b88 90 }
Alex Young 3:abc451d82b88 91 break;
Alex Young 3:abc451d82b88 92
Alex Young 3:abc451d82b88 93 case XBPS_BusId:
Alex Young 3:abc451d82b88 94 parser->checksum += byte;
Alex Young 3:abc451d82b88 95 parser->state = XBPS_MessageId;
Alex Young 3:abc451d82b88 96 break;
Alex Young 3:abc451d82b88 97
Alex Young 3:abc451d82b88 98 case XBPS_MessageId:
Alex Young 3:abc451d82b88 99 parser->checksum += byte;
Alex Young 3:abc451d82b88 100 parser->currentMessageId = byte;
Alex Young 3:abc451d82b88 101 parser->state = XBPS_Length;
Alex Young 3:abc451d82b88 102 break;
Alex Young 3:abc451d82b88 103
Alex Young 3:abc451d82b88 104 case XBPS_Length:
Alex Young 3:abc451d82b88 105 parser->checksum += byte;
Alex Young 3:abc451d82b88 106 if (byte == XBUS_NO_PAYLOAD)
Alex Young 3:abc451d82b88 107 {
Alex Young 3:abc451d82b88 108 parser->state = XBPS_Checksum;
Alex Young 3:abc451d82b88 109 }
Alex Young 3:abc451d82b88 110 else if (byte < XBUS_EXTENDED_LENGTH)
Alex Young 3:abc451d82b88 111 {
Alex Young 3:abc451d82b88 112 parser->currentMessageLength = byte;
Alex Young 3:abc451d82b88 113 prepareForPayload(parser);
Alex Young 3:abc451d82b88 114 parser->state = XBPS_Payload;
Alex Young 3:abc451d82b88 115 }
Alex Young 3:abc451d82b88 116 else
Alex Young 3:abc451d82b88 117 {
Alex Young 3:abc451d82b88 118 parser->state = XBPS_ExtendedLengthMsb;
Alex Young 3:abc451d82b88 119 }
Alex Young 3:abc451d82b88 120 break;
Alex Young 3:abc451d82b88 121
Alex Young 3:abc451d82b88 122 case XBPS_ExtendedLengthMsb:
Alex Young 3:abc451d82b88 123 parser->checksum += byte;
Alex Young 3:abc451d82b88 124 parser->currentMessageLength = ((uint16_t)byte) << 8;
Alex Young 3:abc451d82b88 125 parser->state = XBPS_ExtendedLengthLsb;
Alex Young 3:abc451d82b88 126 break;
Alex Young 3:abc451d82b88 127
Alex Young 3:abc451d82b88 128 case XBPS_ExtendedLengthLsb:
Alex Young 3:abc451d82b88 129 parser->checksum += byte;
Alex Young 3:abc451d82b88 130 parser->currentMessageLength |= byte;
Alex Young 3:abc451d82b88 131 prepareForPayload(parser);
Alex Young 3:abc451d82b88 132 parser->state = XBPS_Payload;
Alex Young 3:abc451d82b88 133 break;
Alex Young 3:abc451d82b88 134
Alex Young 3:abc451d82b88 135 case XBPS_Payload:
Alex Young 3:abc451d82b88 136 parser->checksum += byte;
Alex Young 3:abc451d82b88 137 if (parser->messageBuffer)
Alex Young 3:abc451d82b88 138 {
Alex Young 3:abc451d82b88 139 parser->messageBuffer[parser->payloadReceived] = byte;
Alex Young 3:abc451d82b88 140 }
Alex Young 3:abc451d82b88 141 if (++parser->payloadReceived == parser->currentMessageLength)
Alex Young 3:abc451d82b88 142 {
Alex Young 3:abc451d82b88 143 parser->state = XBPS_Checksum;
Alex Young 3:abc451d82b88 144 }
Alex Young 3:abc451d82b88 145 break;
Alex Young 3:abc451d82b88 146
Alex Young 3:abc451d82b88 147 case XBPS_Checksum:
Alex Young 3:abc451d82b88 148 parser->checksum += byte;
Alex Young 3:abc451d82b88 149 if ((parser->checksum == 0) && parser->messageBuffer)
Alex Young 3:abc451d82b88 150 {
Alex Young 3:abc451d82b88 151 parser->callbacks.handleMessage(parser->currentMessageId,
Alex Young 3:abc451d82b88 152 parser->currentMessageLength,
Alex Young 3:abc451d82b88 153 parser->messageBuffer);
Alex Young 3:abc451d82b88 154 }
Alex Young 3:abc451d82b88 155 parser->state = XBPS_Preamble;
Alex Young 3:abc451d82b88 156 break;
Alex Young 3:abc451d82b88 157 }
Alex Young 3:abc451d82b88 158 }
Alex Young 3:abc451d82b88 159
Alex Young 3:abc451d82b88 160 void XbusParser_parseBuffer(struct XbusParser* parser, uint8_t const* buf, size_t bufSize)
Alex Young 3:abc451d82b88 161 {
Alex Young 3:abc451d82b88 162 for (size_t i = 0; i < bufSize; ++i)
Alex Young 3:abc451d82b88 163 {
Alex Young 3:abc451d82b88 164 XbusParser_parseByte(parser, buf[i]);
Alex Young 3:abc451d82b88 165 }
Alex Young 3:abc451d82b88 166 }
Alex Young 3:abc451d82b88 167