summaryrefslogtreecommitdiff
path: root/OpenModelicaArduino/Firmware/Tiva C/StandardFirmata/FirmataParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'OpenModelicaArduino/Firmware/Tiva C/StandardFirmata/FirmataParser.cpp')
-rw-r--r--OpenModelicaArduino/Firmware/Tiva C/StandardFirmata/FirmataParser.cpp480
1 files changed, 0 insertions, 480 deletions
diff --git a/OpenModelicaArduino/Firmware/Tiva C/StandardFirmata/FirmataParser.cpp b/OpenModelicaArduino/Firmware/Tiva C/StandardFirmata/FirmataParser.cpp
deleted file mode 100644
index d402fdf..0000000
--- a/OpenModelicaArduino/Firmware/Tiva C/StandardFirmata/FirmataParser.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- FirmataParser.cpp
- Copyright (c) 2006-2008 Hans-Christoph Steiner. All rights reserved.
- Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See file LICENSE.txt for further informations on licensing terms.
-*/
-
-//******************************************************************************
-//* Includes
-//******************************************************************************
-
-#include "FirmataParser.h"
-
-#include "FirmataConstants.h"
-
-using namespace firmata;
-
-//******************************************************************************
-//* Constructors
-//******************************************************************************
-
-/**
- * The FirmataParser class.
- * @param dataBuffer A pointer to an external buffer used to store parsed data
- * @param dataBufferSize The size of the external buffer
- */
-FirmataParser::FirmataParser(uint8_t * const dataBuffer, size_t dataBufferSize)
-:
- dataBuffer(dataBuffer),
- dataBufferSize(dataBufferSize),
- executeMultiByteCommand(0),
- multiByteChannel(0),
- waitForData(0),
- parsingSysex(false),
- sysexBytesRead(0),
- currentAnalogCallbackContext((void *)NULL),
- currentDigitalCallbackContext((void *)NULL),
- currentReportAnalogCallbackContext((void *)NULL),
- currentReportDigitalCallbackContext((void *)NULL),
- currentPinModeCallbackContext((void *)NULL),
- currentPinValueCallbackContext((void *)NULL),
- currentReportFirmwareCallbackContext((void *)NULL),
- currentReportVersionCallbackContext((void *)NULL),
- currentDataBufferOverflowCallbackContext((void *)NULL),
- currentStringCallbackContext((void *)NULL),
- currentSysexCallbackContext((void *)NULL),
- currentSystemResetCallbackContext((void *)NULL),
- currentAnalogCallback((callbackFunction)NULL),
- currentDigitalCallback((callbackFunction)NULL),
- currentReportAnalogCallback((callbackFunction)NULL),
- currentReportDigitalCallback((callbackFunction)NULL),
- currentPinModeCallback((callbackFunction)NULL),
- currentPinValueCallback((callbackFunction)NULL),
- currentDataBufferOverflowCallback((dataBufferOverflowCallbackFunction)NULL),
- currentStringCallback((stringCallbackFunction)NULL),
- currentSysexCallback((sysexCallbackFunction)NULL),
- currentReportFirmwareCallback((versionCallbackFunction)NULL),
- currentReportVersionCallback((systemCallbackFunction)NULL),
- currentSystemResetCallback((systemCallbackFunction)NULL)
-{
- allowBufferUpdate = ((uint8_t *)NULL == dataBuffer);
-}
-
-//******************************************************************************
-//* Public Methods
-//******************************************************************************
-
-//------------------------------------------------------------------------------
-// Serial Receive Handling
-
-/**
- * Parse data from the input stream.
- * @param inputData A single byte to be added to the parser.
- */
-void FirmataParser::parse(uint8_t inputData)
-{
- uint8_t command;
-
- if (parsingSysex) {
- if (inputData == END_SYSEX) {
- //stop sysex byte
- parsingSysex = false;
- //fire off handler function
- processSysexMessage();
- } else {
- //normal data byte - add to buffer
- bufferDataAtPosition(inputData, sysexBytesRead);
- ++sysexBytesRead;
- }
- } else if ( (waitForData > 0) && (inputData < 128) ) {
- --waitForData;
- bufferDataAtPosition(inputData, waitForData);
- if ( (waitForData == 0) && executeMultiByteCommand ) { // got the whole message
- switch (executeMultiByteCommand) {
- case ANALOG_MESSAGE:
- if (currentAnalogCallback) {
- (*currentAnalogCallback)(currentAnalogCallbackContext,
- multiByteChannel,
- (dataBuffer[0] << 7)
- + dataBuffer[1]);
- }
- break;
- case DIGITAL_MESSAGE:
- if (currentDigitalCallback) {
- (*currentDigitalCallback)(currentDigitalCallbackContext,
- multiByteChannel,
- (dataBuffer[0] << 7)
- + dataBuffer[1]);
- }
- break;
- case SET_PIN_MODE:
- if (currentPinModeCallback)
- (*currentPinModeCallback)(currentPinModeCallbackContext, dataBuffer[1], dataBuffer[0]);
- break;
- case SET_DIGITAL_PIN_VALUE:
- if (currentPinValueCallback)
- (*currentPinValueCallback)(currentPinValueCallbackContext, dataBuffer[1], dataBuffer[0]);
- break;
- case REPORT_ANALOG:
- if (currentReportAnalogCallback)
- (*currentReportAnalogCallback)(currentReportAnalogCallbackContext, multiByteChannel, dataBuffer[0]);
- break;
- case REPORT_DIGITAL:
- if (currentReportDigitalCallback)
- (*currentReportDigitalCallback)(currentReportDigitalCallbackContext, multiByteChannel, dataBuffer[0]);
- break;
- }
- executeMultiByteCommand = 0;
- }
- } else {
- // remove channel info from command byte if less than 0xF0
- if (inputData < 0xF0) {
- command = inputData & 0xF0;
- multiByteChannel = inputData & 0x0F;
- } else {
- command = inputData;
- // commands in the 0xF* range don't use channel data
- }
- switch (command) {
- case ANALOG_MESSAGE:
- case DIGITAL_MESSAGE:
- case SET_PIN_MODE:
- case SET_DIGITAL_PIN_VALUE:
- waitForData = 2; // two data bytes needed
- executeMultiByteCommand = command;
- break;
- case REPORT_ANALOG:
- case REPORT_DIGITAL:
- waitForData = 1; // one data byte needed
- executeMultiByteCommand = command;
- break;
- case START_SYSEX:
- parsingSysex = true;
- sysexBytesRead = 0;
- break;
- case SYSTEM_RESET:
- systemReset();
- break;
- case REPORT_VERSION:
- if (currentReportVersionCallback)
- (*currentReportVersionCallback)(currentReportVersionCallbackContext);
- break;
- }
- }
-}
-
-/**
- * @return Returns true if the parser is actively parsing data.
- */
-bool FirmataParser::isParsingMessage(void)
-const
-{
- return (waitForData > 0 || parsingSysex);
-}
-
-/**
- * Provides a mechanism to either set or update the working buffer of the parser.
- * The method will be enabled when no buffer has been provided, or an overflow
- * condition exists.
- * @param dataBuffer A pointer to an external buffer used to store parsed data
- * @param dataBufferSize The size of the external buffer
- */
-int FirmataParser::setDataBufferOfSize(uint8_t * dataBuffer, size_t dataBufferSize)
-{
- int result;
-
- if ( !allowBufferUpdate ) {
- result = __LINE__;
- } else if ((uint8_t *)NULL == dataBuffer) {
- result = __LINE__;
- } else {
- this->dataBuffer = dataBuffer;
- this->dataBufferSize = dataBufferSize;
- allowBufferUpdate = false;
- result = 0;
- }
-
- return result;
-}
-
-/**
- * Attach a generic sysex callback function to a command (options are: ANALOG_MESSAGE,
- * DIGITAL_MESSAGE, REPORT_ANALOG, REPORT DIGITAL, SET_PIN_MODE and SET_DIGITAL_PIN_VALUE).
- * @param command The ID of the command to attach a callback function to.
- * @param newFunction A reference to the callback function to attach.
- * @param context An optional context to be provided to the callback function (NULL by default).
- * @note The context parameter is provided so you can pass a parameter, by reference, to
- * your callback function.
- */
-void FirmataParser::attach(uint8_t command, callbackFunction newFunction, void * context)
-{
- switch (command) {
- case ANALOG_MESSAGE:
- currentAnalogCallback = newFunction;
- currentAnalogCallbackContext = context;
- break;
- case DIGITAL_MESSAGE:
- currentDigitalCallback = newFunction;
- currentDigitalCallbackContext = context;
- break;
- case REPORT_ANALOG:
- currentReportAnalogCallback = newFunction;
- currentReportAnalogCallbackContext = context;
- break;
- case REPORT_DIGITAL:
- currentReportDigitalCallback = newFunction;
- currentReportDigitalCallbackContext = context;
- break;
- case SET_PIN_MODE:
- currentPinModeCallback = newFunction;
- currentPinModeCallbackContext = context;
- break;
- case SET_DIGITAL_PIN_VALUE:
- currentPinValueCallback = newFunction;
- currentPinValueCallbackContext = context;
- break;
- }
-}
-
-/**
- * Attach a version callback function (supported option: REPORT_FIRMWARE).
- * @param command The ID of the command to attach a callback function to.
- * @param newFunction A reference to the callback function to attach.
- * @param context An optional context to be provided to the callback function (NULL by default).
- * @note The context parameter is provided so you can pass a parameter, by reference, to
- * your callback function.
- */
-void FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, void * context)
-{
- switch (command) {
- case REPORT_FIRMWARE:
- currentReportFirmwareCallback = newFunction;
- currentReportFirmwareCallbackContext = context;
- break;
- }
-}
-
-/**
- * Attach a system callback function (supported options are: SYSTEM_RESET, REPORT_VERSION).
- * @param command The ID of the command to attach a callback function to.
- * @param newFunction A reference to the callback function to attach.
- * @param context An optional context to be provided to the callback function (NULL by default).
- * @note The context parameter is provided so you can pass a parameter, by reference, to
- * your callback function.
- */
-void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void * context)
-{
- switch (command) {
- case REPORT_VERSION:
- currentReportVersionCallback = newFunction;
- currentReportVersionCallbackContext = context;
- break;
- case SYSTEM_RESET:
- currentSystemResetCallback = newFunction;
- currentSystemResetCallbackContext = context;
- break;
- }
-}
-
-/**
- * Attach a callback function for the STRING_DATA command.
- * @param command Must be set to STRING_DATA or it will be ignored.
- * @param newFunction A reference to the string callback function to attach.
- * @param context An optional context to be provided to the callback function (NULL by default).
- * @note The context parameter is provided so you can pass a parameter, by reference, to
- * your callback function.
- */
-void FirmataParser::attach(uint8_t command, stringCallbackFunction newFunction, void * context)
-{
- switch (command) {
- case STRING_DATA:
- currentStringCallback = newFunction;
- currentStringCallbackContext = context;
- break;
- }
-}
-
-/**
- * Attach a generic sysex callback function to sysex command.
- * @param command The ID of the command to attach a callback function to.
- * @param newFunction A reference to the sysex callback function to attach.
- * @param context An optional context to be provided to the callback function (NULL by default).
- * @note The context parameter is provided so you can pass a parameter, by reference, to
- * your callback function.
- */
-void FirmataParser::attach(uint8_t command, sysexCallbackFunction newFunction, void * context)
-{
- (void)command;
- currentSysexCallback = newFunction;
- currentSysexCallbackContext = context;
-}
-
-/**
- * Attach a buffer overflow callback
- * @param newFunction A reference to the buffer overflow callback function to attach.
- * @param context An optional context to be provided to the callback function (NULL by default).
- * @note The context parameter is provided so you can pass a parameter, by reference, to
- * your callback function.
- */
-void FirmataParser::attach(dataBufferOverflowCallbackFunction newFunction, void * context)
-{
- currentDataBufferOverflowCallback = newFunction;
- currentDataBufferOverflowCallbackContext = context;
-}
-
-/**
- * Detach a callback function for a specified command (such as SYSTEM_RESET, STRING_DATA,
- * ANALOG_MESSAGE, DIGITAL_MESSAGE, etc).
- * @param command The ID of the command to detatch the callback function from.
- */
-void FirmataParser::detach(uint8_t command)
-{
- switch (command) {
- case REPORT_FIRMWARE:
- attach(command, (versionCallbackFunction)NULL, NULL);
- break;
- case REPORT_VERSION:
- case SYSTEM_RESET:
- attach(command, (systemCallbackFunction)NULL, NULL);
- break;
- case STRING_DATA:
- attach(command, (stringCallbackFunction)NULL, NULL);
- break;
- case START_SYSEX:
- attach(command, (sysexCallbackFunction)NULL, NULL);
- break;
- default:
- attach(command, (callbackFunction)NULL, NULL);
- break;
- }
-}
-
-/**
- * Detach the buffer overflow callback
- * @param <unused> Any pointer of type dataBufferOverflowCallbackFunction.
- */
-void FirmataParser::detach(dataBufferOverflowCallbackFunction)
-{
- currentDataBufferOverflowCallback = (dataBufferOverflowCallbackFunction)NULL;
- currentDataBufferOverflowCallbackContext = (void *)NULL;
-}
-
-//******************************************************************************
-//* Private Methods
-//******************************************************************************
-
-/**
- * Buffer abstraction to prevent memory corruption
- * @param data The byte to put into the buffer
- * @param pos The position to insert the byte into the buffer
- * @return writeError A boolean to indicate if an error occured
- * @private
- */
-bool FirmataParser::bufferDataAtPosition(const uint8_t data, const size_t pos)
-{
- bool bufferOverflow = (pos >= dataBufferSize);
-
- // Notify of overflow condition
- if ( bufferOverflow
- && ((dataBufferOverflowCallbackFunction)NULL != currentDataBufferOverflowCallback) )
- {
- allowBufferUpdate = true;
- currentDataBufferOverflowCallback(currentDataBufferOverflowCallbackContext);
- // Check if overflow was resolved during callback
- bufferOverflow = (pos >= dataBufferSize);
- }
-
- // Write data to buffer if no overflow condition persist
- if ( !bufferOverflow )
- {
- dataBuffer[pos] = data;
- }
-
- return bufferOverflow;
-}
-
-/**
- * Transform 7-bit firmata message into 8-bit stream
- * @param bytec The encoded data byte length of the message (max: 16383).
- * @param bytev A pointer to the encoded array of data bytes.
- * @return The length of the decoded data.
- * @note The conversion will be done in place on the provided buffer.
- * @private
- */
-size_t FirmataParser::decodeByteStream(size_t bytec, uint8_t * bytev) {
- size_t decoded_bytes, i;
-
- for ( i = 0, decoded_bytes = 0 ; i < bytec ; ++decoded_bytes, ++i ) {
- bytev[decoded_bytes] = bytev[i];
- bytev[decoded_bytes] |= (uint8_t)(bytev[++i] << 7);
- }
-
- return decoded_bytes;
-}
-
-/**
- * Process incoming sysex messages. Handles REPORT_FIRMWARE and STRING_DATA internally.
- * Calls callback function for STRING_DATA and all other sysex messages.
- * @private
- */
-void FirmataParser::processSysexMessage(void)
-{
- switch (dataBuffer[0]) { //first byte in buffer is command
- case REPORT_FIRMWARE:
- if (currentReportFirmwareCallback) {
- const size_t major_version_offset = 1;
- const size_t minor_version_offset = 2;
- const size_t string_offset = 3;
- // Test for malformed REPORT_FIRMWARE message (used to query firmware prior to Firmata v3.0.0)
- if ( 3 > sysexBytesRead ) {
- (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, 0, 0, (const char *)NULL);
- } else {
- const size_t end_of_string = (string_offset + decodeByteStream((sysexBytesRead - string_offset), &dataBuffer[string_offset]));
- bufferDataAtPosition('\0', end_of_string); // NULL terminate the string
- (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, (size_t)dataBuffer[major_version_offset], (size_t)dataBuffer[minor_version_offset], (const char *)&dataBuffer[string_offset]);
- }
- }
- break;
- case STRING_DATA:
- if (currentStringCallback) {
- const size_t string_offset = 1;
- const size_t end_of_string = (string_offset + decodeByteStream((sysexBytesRead - string_offset), &dataBuffer[string_offset]));
- bufferDataAtPosition('\0', end_of_string); // NULL terminate the string
- (*currentStringCallback)(currentStringCallbackContext, (const char *)&dataBuffer[string_offset]);
- }
- break;
- default:
- if (currentSysexCallback)
- (*currentSysexCallback)(currentSysexCallbackContext, dataBuffer[0], sysexBytesRead - 1, dataBuffer + 1);
- }
-}
-
-/**
- * Resets the system state upon a SYSTEM_RESET message from the host software.
- * @private
- */
-void FirmataParser::systemReset(void)
-{
- size_t i;
-
- waitForData = 0; // this flag says the next serial input will be data
- executeMultiByteCommand = 0; // execute this after getting multi-byte data
- multiByteChannel = 0; // channel data for multiByteCommands
-
- for (i = 0; i < dataBufferSize; ++i) {
- dataBuffer[i] = 0;
- }
-
- parsingSysex = false;
- sysexBytesRead = 0;
-
- if (currentSystemResetCallback)
- (*currentSystemResetCallback)(currentSystemResetCallbackContext);
-}