Skip to content

Commit 0d9e533

Browse files
Merge pull request #359 from zfields/firmware
firmware callbacks
2 parents 168a0c0 + fd76083 commit 0d9e533

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

Firmata.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ FirmataClass::FirmataClass()
9494
parser.attach(SET_DIGITAL_PIN_VALUE, (FirmataParser::callbackFunction)staticPinValueCallback, (void *)NULL);
9595
parser.attach(STRING_DATA, (FirmataParser::stringCallbackFunction)staticStringCallback, (void *)NULL);
9696
parser.attach(START_SYSEX, (FirmataParser::sysexCallbackFunction)staticSysexCallback, (void *)NULL);
97-
parser.attach(REPORT_FIRMWARE, (FirmataParser::systemCallbackFunction)staticReportFirmwareCallback, this);
97+
parser.attach(REPORT_FIRMWARE, (FirmataParser::versionCallbackFunction)staticReportFirmwareCallback, this);
9898
parser.attach(REPORT_VERSION, (FirmataParser::systemCallbackFunction)staticReportVersionCallback, this);
9999
parser.attach(SYSTEM_RESET, (FirmataParser::systemCallbackFunction)staticSystemResetCallback, (void *)NULL);
100100
}

Firmata.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ class FirmataClass
148148
inline static void staticPinValueCallback (void *, uint8_t command, uint16_t value) { if ( currentPinValueCallback ) { currentPinValueCallback(command, (int)value); } }
149149
inline static void staticReportAnalogCallback (void *, uint8_t command, uint16_t value) { if ( currentReportAnalogCallback ) { currentReportAnalogCallback(command, (int)value); } }
150150
inline static void staticReportDigitalCallback (void *, uint8_t command, uint16_t value) { if ( currentReportDigitalCallback ) { currentReportDigitalCallback(command, (int)value); } }
151-
inline static void staticStringCallback (void *, char * c_str) { if ( currentStringCallback ) { currentStringCallback(c_str); } }
151+
inline static void staticStringCallback (void *, const char * c_str) { if ( currentStringCallback ) { currentStringCallback((char *)c_str); } }
152152
inline static void staticSysexCallback (void *, uint8_t command, size_t argc, uint8_t *argv) { if ( currentSysexCallback ) { currentSysexCallback(command, (uint8_t)argc, argv); } }
153-
inline static void staticReportFirmwareCallback (void * context) { if ( context ) { ((FirmataClass *)context)->printFirmwareVersion(); } }
153+
inline static void staticReportFirmwareCallback (void * context, size_t, size_t, const char *) { if ( context ) { ((FirmataClass *)context)->printFirmwareVersion(); } }
154154
inline static void staticReportVersionCallback (void * context) { if ( context ) { ((FirmataClass *)context)->printVersion(); } }
155155
inline static void staticSystemResetCallback (void *) { if ( currentSystemResetCallback ) { currentSystemResetCallback(); } }
156156
};

FirmataParser.cpp

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ FirmataParser::FirmataParser(uint8_t * const dataBuffer, size_t dataBufferSize)
6060
currentDataBufferOverflowCallback((dataBufferOverflowCallbackFunction)NULL),
6161
currentStringCallback((stringCallbackFunction)NULL),
6262
currentSysexCallback((sysexCallbackFunction)NULL),
63-
currentReportFirmwareCallback((systemCallbackFunction)NULL),
63+
currentReportFirmwareCallback((versionCallbackFunction)NULL),
6464
currentReportVersionCallback((systemCallbackFunction)NULL),
6565
currentSystemResetCallback((systemCallbackFunction)NULL)
6666
{
@@ -244,21 +244,34 @@ void FirmataParser::attach(uint8_t command, callbackFunction newFunction, void *
244244
}
245245

246246
/**
247-
* Attach a system callback function (options are: REPORT_FIRMWARE, REPORT_VERSION
248-
* and SYSTEM_RESET).
247+
* Attach a version callback function (supported option: REPORT_FIRMWARE).
249248
* @param command The ID of the command to attach a callback function to.
250249
* @param newFunction A reference to the callback function to attach.
251250
* @param context An optional context to be provided to the callback function (NULL by default).
252251
* @note The context parameter is provided so you can pass a parameter, by reference, to
253252
* your callback function.
254253
*/
255-
void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void * context)
254+
void FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, void * context)
256255
{
257256
switch (command) {
258257
case REPORT_FIRMWARE:
259258
currentReportFirmwareCallback = newFunction;
260259
currentReportFirmwareCallbackContext = context;
261260
break;
261+
}
262+
}
263+
264+
/**
265+
* Attach a system callback function (supported options are: SYSTEM_RESET, REPORT_VERSION).
266+
* @param command The ID of the command to attach a callback function to.
267+
* @param newFunction A reference to the callback function to attach.
268+
* @param context An optional context to be provided to the callback function (NULL by default).
269+
* @note The context parameter is provided so you can pass a parameter, by reference, to
270+
* your callback function.
271+
*/
272+
void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void * context)
273+
{
274+
switch (command) {
262275
case REPORT_VERSION:
263276
currentReportVersionCallback = newFunction;
264277
currentReportVersionCallbackContext = context;
@@ -325,6 +338,8 @@ void FirmataParser::detach(uint8_t command)
325338
{
326339
switch (command) {
327340
case REPORT_FIRMWARE:
341+
attach(command, (versionCallbackFunction)NULL, NULL);
342+
break;
328343
case REPORT_VERSION:
329344
case SYSTEM_RESET:
330345
attach(command, (systemCallbackFunction)NULL, NULL);
@@ -394,14 +409,24 @@ void FirmataParser::processSysexMessage(void)
394409
{
395410
switch (dataBuffer[0]) { //first byte in buffer is command
396411
case REPORT_FIRMWARE:
397-
if (currentReportFirmwareCallback)
398-
(*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext);
412+
if (currentReportFirmwareCallback) {
413+
size_t sv_major = dataBuffer[1], sv_minor = dataBuffer[2];
414+
size_t i = 0, j = 3;
415+
while (j < sysexBytesRead) {
416+
// The string length will only be at most half the size of the
417+
// stored input buffer so we can decode the string within the buffer.
418+
bufferDataAtPosition(dataBuffer[j], i);
419+
++i;
420+
++j;
421+
}
422+
bufferDataAtPosition('\0', i); // Terminate the string
423+
(*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, sv_major, sv_minor, (const char *)&dataBuffer[0]);
424+
}
399425
break;
400426
case STRING_DATA:
401427
if (currentStringCallback) {
402428
size_t bufferLength = (sysexBytesRead - 1) / 2;
403-
size_t i = 1;
404-
size_t j = 0;
429+
size_t i = 1, j = 0;
405430
while (j < bufferLength) {
406431
// The string length will only be at most half the size of the
407432
// stored input buffer so we can decode the string within the buffer.
@@ -417,7 +442,7 @@ void FirmataParser::processSysexMessage(void)
417442
if (dataBuffer[j - 1] != '\0') {
418443
bufferDataAtPosition('\0', j);
419444
}
420-
(*currentStringCallback)(currentStringCallbackContext, (char *)&dataBuffer[0]);
445+
(*currentStringCallback)(currentStringCallbackContext, (const char *)&dataBuffer[0]);
421446
}
422447
break;
423448
default:

FirmataParser.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ class FirmataParser
3030
/* callback function types */
3131
typedef void (*callbackFunction)(void * context, uint8_t command, uint16_t value);
3232
typedef void (*dataBufferOverflowCallbackFunction)(void * context);
33-
typedef void (*stringCallbackFunction)(void * context, char * c_str);
33+
typedef void (*stringCallbackFunction)(void * context, const char * c_str);
3434
typedef void (*sysexCallbackFunction)(void * context, uint8_t command, size_t argc, uint8_t * argv);
3535
typedef void (*systemCallbackFunction)(void * context);
36+
typedef void (*versionCallbackFunction)(void * context, size_t sv_major, size_t sv_minor, const char * firmware);
3637

3738
FirmataParser(uint8_t * dataBuffer = (uint8_t *)NULL, size_t dataBufferSize = 0);
3839

@@ -47,6 +48,7 @@ class FirmataParser
4748
void attach(uint8_t command, stringCallbackFunction newFunction, void * context = NULL);
4849
void attach(uint8_t command, sysexCallbackFunction newFunction, void * context = NULL);
4950
void attach(uint8_t command, systemCallbackFunction newFunction, void * context = NULL);
51+
void attach(uint8_t command, versionCallbackFunction newFunction, void * context = NULL);
5052
void detach(uint8_t command);
5153
void detach(dataBufferOverflowCallbackFunction);
5254

@@ -87,14 +89,14 @@ class FirmataParser
8789
dataBufferOverflowCallbackFunction currentDataBufferOverflowCallback;
8890
stringCallbackFunction currentStringCallback;
8991
sysexCallbackFunction currentSysexCallback;
90-
systemCallbackFunction currentReportFirmwareCallback;
92+
versionCallbackFunction currentReportFirmwareCallback;
9193
systemCallbackFunction currentReportVersionCallback;
9294
systemCallbackFunction currentSystemResetCallback;
9395

9496
/* private methods ------------------------------ */
97+
bool bufferDataAtPosition(const uint8_t data, const size_t pos);
9598
void processSysexMessage(void);
9699
void systemReset(void);
97-
bool bufferDataAtPosition(const uint8_t data, const size_t pos);
98100
};
99101

100102
} // firmata

0 commit comments

Comments
 (0)