-
Notifications
You must be signed in to change notification settings - Fork 20
/
firmata.h
325 lines (307 loc) · 9.07 KB
/
firmata.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
Project: 1Sheeld Firmware
File: firmata.h
Compiler: avr-gcc 3.4.2
Author: Integreight
Date: 2014.5
*/
/**
* @file firmata.h
* @brief This library handles all of the messages related to Firmata protocol.
* @author Integreight
* @version 1.1
*/
#ifndef FIRMATA_H_
#define FIRMATA_H_
#include "stdint.h"
#include "uart.h"
#include "gpio.h"
#include "eeprom.h"
#define ONESHEELD_MINOR_FIRMWARE_VERSION 6
#define ONESHEELD_MAJOR_FIRMWARE_VERSION 1
#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
#define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
#define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
// message command bytes (128-255/0x80-0xFF)
#define DIGITAL_MESSAGE 0x90 // send data for a digital pin
#define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
#define REPORT_ANALOG 0xC0 // enable analog input by pin #
#define REPORT_DIGITAL 0xD0 // enable digital input by port pair
#define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
#define REPORT_VERSION 0xF9 // report protocol version
#define SYSTEM_RESET 0xFF // reset from MIDI
#define START_SYSEX 0xF0 // start a MIDI Sysex message
#define END_SYSEX 0xF7 // end a MIDI Sysex message
#define FIRMATA_MUTE 0x64 // turn off firmata
#define FIRMATA_VERSION 0X63 // our firmata version
#define IS_ALIVE 0x62
#define RESET_BLUETOOTH 0x61
#define RESET_MICRO 0x60
#define REPORT_INPUT_PINS 0X5F
#define BLUETOOTH_RENAMING 0x5E
#define TESTING_FRAME 0x5D
#define QUERY_UART0_BAUD_RATE 0x5C
#define SET_UART0_BAUD_RATE 0x5B
// pin modes
#define ANALOG 0x02 // analog pin in analogInput mode
#define PWM 0x03 // digital pin in PWM output mode
#define SHIFT 0x05 // shiftIn/shiftOut mode
//uart
#define UART_COMMAND 0x65
#define UART_DATA 0x66
#define REGISTER_NOT_SPECIFIED -1
#define STX 0x02
#define ETX 0x03
#define UART_BEGIN 0x01
#define UART_END 0x00
//eeprom address
#define CURRENT_UART0_BAUD_RATE_EEPROM_ADDRESS 0
#define IS_PIN_REPORTING_ENABLED 1
#define TOTAL_PORTS 5
#define TOTAL_PINS 20
#define BLUETOOH_RESET_RESPONSE_INTERVAL 500UL
#define FRAME_GAP 15UL
#define APP_ISALIVE_RESPONSE_INTERVAL 2000UL
/* digital input ports */
uint8_t reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
uint8_t previousPINs[TOTAL_PORTS]; // previous 8 bits sent
/* pins configuration */
uint8_t pinConfig[TOTAL_PINS]; // configuration of every pin
uint8_t portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
int16_t pinState[TOTAL_PINS]; // any value that has been written
uint8_t muteFirmata;
/* input message handling */
uint8_t waitForData; // this flag says the next serial input will be data
uint8_t executeMultiByteCommand; // execute this after getting multi-byte data
uint8_t multiByteChannel; // channel data for multiByteCommands
uint8_t storedInputData[MAX_DATA_BYTES]; // multi-byte data
extern const uint8_t PROGMEM atNameArray[7];
uint8_t testAnswer;
uint32_t bluetoothResponseMillis;
uint32_t newMillis;
uint32_t isAliveMillis;
#ifdef PLUS_BOARD
/* Buffering data for IOS version */
uint32_t sentFramesMillis;
uint8_t txBufferIndex;
uint8_t UartTx1Buffer[20]; //to send frames of 20bytes each 15ms
uint8_t digitalPort0array[3];
uint8_t digitalPort1array[3];
uint8_t digitalPort2array[3];
uint8_t oldDigitalPort0array[3];
uint8_t oldDigitalPort1array[3];
uint8_t oldDigitalPort2array[3];
uint8_t toggelingIndicator;
uint8_t firstFrameToSend;
uint8_t resendDigitalPort;
uint8_t resendIsAlive;
uint8_t resendPrintVersion;
uint8_t port0StatusChanged;
uint8_t port1StatusChanged;
uint8_t port2StatusChanged;
uint8_t isPort0StatusEqual;
uint8_t isPort1StatusEqual;
uint8_t isPort2StatusEqual;
uint8_t arduinoStopped;
uint8_t resendTestingAnswer;
uint8_t resendCurrentBaudRate;
#endif
/* sysex */
uint8_t parsingSysex;
int16_t sysexBytesRead;
//for bluetooth reset
uint8_t bluetoothResetResponded;
uint8_t isAppResponded;
uint8_t notAliveSentToArduino;
/**
* @brief Initialize Firmata protocal variables.
* @param None.
* @return None.
*/
void initFirmata();
/**
* @brief Send a byte using the serial communication.
* @param data byte to be sent.
* @return None.
*/
void write(uint8_t data);
/**
* @brief Checks the availability of data in the serial buffer.
* @param None.
* @return number of data bytes in the serial buffer.
*/
int16_t available(void);
/**
* @brief process the data coming from 1Sheeld android app.
* @param None.
* @return None.
*/
void processInput(void);
/**
* @brief process the input data coming from the Arduino.
* @param None.
* @return None.
*/
void processUart0Input(void);
/**
* @brief Sending digital post status using Firmata's digital message.
* @param portNumber port number.
* @param portData Data to be put on the port.
* @return None.
*/
void sendDigitalPort(uint8_t portNumber, int16_t portData);
/**
* @brief Send an array of bytes using Firmata's sysex message format.
* @param command Command byte.
* @param bytec Length of data to be sent.
* @param *bytev Array carrying the data.
* @return None.
*/
void sendSysex(uint8_t command, uint8_t bytec, uint8_t* bytev);
/**
* @brief set the port before sending.
* @param portNumber port number.
* @param portValue data to be put on the port.
* @param forceSend boolean to send the port even if it didn't change.
* @return None.
*/
void outputPort(uint8_t portNumber, uint8_t portValue, uint8_t forceSend);
/**
* @brief Checks the values on all the digital inputs of 1Sheeld board.
* @param None.
* @return None.
*/
void checkDigitalInputs(void);
/**
* @brief sets the pin mode to the correct state and sets the relevant bits in the two bit-arrays that track Digital I/O and PWM status when a pin mode message is received.
* @param pin number of pin to be set.
* @param mode mode of the pin either INPUT, OUTPUT, ANALOG or PWM.
* @return None.
*/
void setPinModeCallback(uint8_t pin, int16_t mode);
/**
* @brief sets duty cycle to of an analog (PWM) pin when an analog message is received.
* @param pin number of pin to be set.
* @param duty cycle to be set on the pin.
* @return None.
*/
void analogWriteCallback(uint8_t pin, int16_t value);
/**
* @brief sets digital values to pins when a digital message is received.
* @param pin number of pin to be set.
* @param value digital value to be set on the pin.
* @return None.
*/
void digitalWriteCallback(uint8_t port, int16_t value);
/**
* @brief enables/disables reporting of changes of a digital input port when a digital reporting message is received.
* @param port number of port to be reported.
* @param value a value that determine the enabling or disabling.
* @return None.
*/
void reportDigitalCallback(uint8_t port, int16_t value);
/**
* @brief act upon the processed sysex messages.
* @param command command byte.
* @param argc length of the data.
* @param *argv Array of the enclosed sysex data.
* @return None.
*/
void sysexCallback(uint8_t command, uint8_t argc, uint8_t *argv);
/**
* @brief resets 1Sheeld pins to their default values and reset firmata values.
* @param None.
* @return None.
*/
void systemResetCallback();
/**
* @brief Sends a request to the app to reset the Bluetooth.
* @param None.
* @return None.
*/
void requestBluetoothReset();
/**
* @brief Flag ti know if the app responeded to the Bluetooth reset request.
* @param None.
* @return boolean.
*/
void processSysexMessage(void);
/**
* @brief Resets the whole firmata and init its variables.
* @param None.
* @return None.
*/
void systemReset(void);
/**
* @brief Send byte as two 7bit bytes.
* @param None.
* @return None.
*/
void sendValueAsTwo7bitBytes(int16_t value);
/**
* @brief sends start sysex byte.
* @param None.
* @return None.
*/
void startSysex(void);
/**
* @brief sends end sysex byte.
* @param None.
* @return None.
*/
void endSysex(void);
/**
* @brief force the Micro-controller to reset itself using the watchdog timer.
* @param None.
* @return None.
*/
void forceHardReset();
/**
* @brief send the firmware version to the app.
* @param None.
* @return None.
*/
void printVersion();
/**
* @brief Report digital ports status to app.
* @param None.
* @return None.
*/
void reportDigialPorts();
/**
* @brief Sends Frame each 500ms to check if app is connected.
* @param None.
* @return None.
*/
void sendIsAlive();
/**
* @brief Reset the Bluetooth using software
* @param None
* @return None
*/
void resetBluetooth();
/**
* @brief Send AT+NAME command to bluetooth to rename
* @param None
* @return None
*/
void sendATNameCommand();
/**
* @brief Send Confirmation when bluetooth is renamed
* @param None
* @return None
*/
void sendBluetoothRenameConfirmation();
/**
* @brief Send testing answer "SDK testing"
* @param None
* @return None
*/
void sendAnswerToApplication();
/**
* @brief send the current UART0 baudRate to applicaiton
* @param None
* @return None
*/
void getCurrentUart0BaudRate();
#endif /* FIRMATA_H_ */