下面會同時混雜 Firmata.cpp 跟 Firmata.h 的資料,但是因為類型相同不影響閱讀連續性。
// 這邊定義了 4 種不同用途的 callback function
extern "C" {
// callback function types
typedef void (*callbackFunction)(byte, int);
typedef void (*systemResetCallbackFunction)(void);
typedef void (*stringCallbackFunction)(char*);
typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
}
// 輸入輸出相關 所以資料為(byte, int) 形式
callbackFunction currentAnalogCallback;
callbackFunction currentDigitalCallback;
callbackFunction currentReportAnalogCallback;
callbackFunction currentReportDigitalCallback;
callbackFunction currentPinModeCallback;
// reset 相關,所以不用輸入任何參數 (void)
systemResetCallbackFunction currentSystemResetCallback;
// 要處理 string data 的 callback function , 輸入為一個 char* 指標
stringCallbackFunction currentStringCallback;
// (byte command, byte argc, byte*argv) 目前暫時不知用途,只知道跟 SYSEX_START command 相關
sysexCallbackFunction currentSysexCallback;
// generic callbacks
// 把 callback function 放到對應 command 的位置,供昨天看過的 processInput 調用
void FirmataClass::attach(byte command, callbackFunction newFunction)
{
switch(command) {
case ANALOG_MESSAGE: currentAnalogCallback = newFunction; break;
case DIGITAL_MESSAGE: currentDigitalCallback = newFunction; break;
case REPORT_ANALOG: currentReportAnalogCallback = newFunction; break;
case REPORT_DIGITAL: currentReportDigitalCallback = newFunction; break;
case SET_PIN_MODE: currentPinModeCallback = newFunction; break;
}
}
void FirmataClass::attach(byte command, systemResetCallbackFunction newFunction)
{
switch(command) {
case SYSTEM_RESET: currentSystemResetCallback = newFunction; break;
}
}
void FirmataClass::attach(byte command, stringCallbackFunction newFunction)
{
switch(command) {
case STRING_DATA: currentStringCallback = newFunction; break;
}
}
void FirmataClass::attach(byte command, sysexCallbackFunction newFunction)
{
currentSysexCallback = newFunction;
}
// 解除註冊指定 command 的 callback function
void FirmataClass::detach(byte command)
{
switch(command) { // 把對應位置的資料設定為 null
case SYSTEM_RESET: currentSystemResetCallback = NULL; break;
case STRING_DATA: currentStringCallback = NULL; break;
case START_SYSEX: currentSysexCallback = NULL; break;
default:
attach(command, (callbackFunction)NULL);
}
}
看完 processInput / attach /detach 這三個最重要的method 了,而 digital firmata 跟 analog 在控制上並沒有太大的差異,只需要事先在 pin_mode 定義就好了。
我們明天見