├── Arduino └── libraries │ └── RBL_BLEMini │ ├── ble_mini.cpp │ ├── ble_mini.h │ └── examples │ ├── BLEControllerSketch │ ├── BLEControllerSketch.ino │ └── Boards.h │ ├── BLEFirmataSketch │ ├── BLEFirmata.cpp │ ├── BLEFirmata.h │ ├── BLEFirmataSketch.ino │ └── Boards.h │ ├── Chat │ └── Chat.ino │ └── SimpleControls │ └── SimpleControls.ino ├── Docs ├── 01FirmwareUpdate.pdf ├── 02ExternalAntenna.pdf ├── Coin-Cell │ ├── 01.JPG │ ├── 02.JPG │ ├── 03.JPG │ └── 04.JPG └── ExternalAntenna.jpg ├── Drivers ├── ccxxxx_usb_cdc.cat └── ccxxxx_usb_cdc.inf ├── Firmware ├── BLE2UART │ ├── Biscuit-UART_20140409.bin │ └── Biscuit-USBCDC_20140409.bin ├── BLERGB │ └── Biscuit-RGB_20140310.bin ├── Bootloader │ └── UBL-1.3.hex ├── HCI │ ├── HCI_UART_115200bps_20130429.bin │ ├── HCI_UART_57600bps_20130502.bin │ └── HCI_USBCDC_115200_20130429.bin └── MiniBeacon │ └── MiniBeacon-20140409.bin ├── PCB ├── BLE_Mini.dxf ├── BLE_Mini.pdf └── BLE_Mini_Schematic_v1.0.pdf └── README.md /Arduino/libraries/RBL_BLEMini/ble_mini.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ble_mini.h" 3 | 4 | // UNO 5 | // TX: pin 1 6 | // RX: pin 0 7 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328P__) 8 | #define BLEMINI Serial 9 | 10 | // other board 11 | // board TX RX 12 | // Leonardo 1 0 13 | // MEGA 18 19 14 | // DUE 18 19 15 | #else 16 | #define BLEMINI Serial1 17 | #endif 18 | 19 | void BLEMini_begin(unsigned long bound) 20 | { 21 | BLEMINI.begin(bound); 22 | } 23 | 24 | int BLEMini_available() 25 | { 26 | return BLEMINI.available(); 27 | } 28 | 29 | void BLEMini_write(unsigned char dat) 30 | { 31 | BLEMINI.write(dat); 32 | } 33 | 34 | void BLEMini_write_bytes(unsigned char *dat, unsigned char len) 35 | { 36 | delay(10); 37 | if(len > 0) 38 | BLEMINI.write(dat, len); 39 | } 40 | 41 | int BLEMini_read() 42 | { 43 | delay(10); 44 | return BLEMINI.read(); 45 | } 46 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/ble_mini.h: -------------------------------------------------------------------------------- 1 | #ifndef _BLE_MINI_H 2 | #define _BLE_MINI_H 3 | 4 | #include 5 | 6 | void BLEMini_begin(unsigned long bound); 7 | int BLEMini_available(); 8 | void BLEMini_write(unsigned char dat); 9 | void BLEMini_write_bytes(unsigned char *dat, unsigned char len); 10 | int BLEMini_read(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/examples/BLEControllerSketch/BLEControllerSketch.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * When use DUE board, the Arduino IDE should be the version of 1.5.4 or above. 3 | * Board BLEMini(TX, RX) 4 | * DUE (18, 19) 5 | * MEGA (18, 19) 6 | * UNO (1, 0) 7 | * LEONARDO (1, 0) 8 | */ 9 | 10 | #include 11 | #include "Boards.h" 12 | #include 13 | 14 | #define PROTOCOL_MAJOR_VERSION 0 // 15 | #define PROTOCOL_MINOR_VERSION 0 // 16 | #define PROTOCOL_BUGFIX_VERSION 2 // bugfix 17 | 18 | #define PIN_CAPABILITY_NONE 0x00 19 | #define PIN_CAPABILITY_DIGITAL 0x01 20 | #define PIN_CAPABILITY_ANALOG 0x02 21 | #define PIN_CAPABILITY_PWM 0x04 22 | #define PIN_CAPABILITY_SERVO 0x08 23 | #define PIN_CAPABILITY_I2C 0x10 24 | 25 | // pin modes 26 | //#define INPUT 0x00 // defined in wiring.h 27 | //#define OUTPUT 0x01 // defined in wiring.h 28 | #define ANALOG 0x02 // analog pin in analogInput mode 29 | #define PWM 0x03 // digital pin in PWM output mode 30 | #define SERVO 0x04 // digital pin in Servo output mode 31 | 32 | byte pin_mode[TOTAL_PINS]; 33 | byte pin_state[TOTAL_PINS]; 34 | byte pin_pwm[TOTAL_PINS]; 35 | byte pin_servo[TOTAL_PINS]; 36 | 37 | Servo servos[MAX_SERVOS]; 38 | 39 | /* timer variables */ 40 | unsigned long currentMillis; // store the current value from millis() 41 | unsigned long previousMillis; // for comparison with currentMillis 42 | int samplingInterval = 5; // how often to run the main loop (in ms) 43 | 44 | void setup() 45 | { 46 | BLEMini_begin(57600); 47 | 48 | #if !defined(__AVR_ATmega328P__) 49 | Serial.begin(57600); 50 | //while(!Serial); // Enable this line if you want to debug on Leonardo 51 | Serial.println("BLE Arduino Slave "); 52 | #endif 53 | 54 | /* Default all to digital input */ 55 | for (int pin = 0; pin < TOTAL_PINS; pin++) 56 | { 57 | // Set pin to input with internal pull up 58 | if(IS_PIN_DIGITAL(pin)) 59 | { 60 | pinMode(pin, INPUT); 61 | } 62 | digitalWrite(pin, HIGH); 63 | // Save pin mode and state 64 | pin_mode[pin] = INPUT; 65 | pin_state[pin] = LOW; 66 | } 67 | } 68 | 69 | static byte buf_len = 0; 70 | 71 | byte reportDigitalInput() 72 | { 73 | static byte pin = 0; 74 | byte report = 0; 75 | 76 | if (!IS_PIN_DIGITAL(pin)) 77 | { 78 | pin++; 79 | if (pin >= TOTAL_PINS) 80 | pin = 0; 81 | return 0; 82 | } 83 | 84 | if (pin_mode[pin] == INPUT) 85 | { 86 | byte current_state = digitalRead(pin); 87 | 88 | if (pin_state[pin] != current_state) 89 | { 90 | pin_state[pin] = current_state; 91 | byte buf[] = {'G', pin, INPUT, current_state}; 92 | BLEMini_write_bytes(buf, 4); 93 | 94 | report = 1; 95 | } 96 | } 97 | 98 | pin++; 99 | if (pin >= TOTAL_PINS) 100 | pin = 0; 101 | 102 | return report; 103 | } 104 | 105 | void reportPinCapability(byte pin) 106 | { 107 | byte buf[] = {'P', pin, 0x00}; 108 | byte pin_cap = 0; 109 | 110 | if (IS_PIN_DIGITAL(pin)) 111 | pin_cap |= PIN_CAPABILITY_DIGITAL; 112 | 113 | if (IS_PIN_ANALOG(pin)) 114 | pin_cap |= PIN_CAPABILITY_ANALOG; 115 | 116 | if (IS_PIN_PWM(pin)) 117 | pin_cap |= PIN_CAPABILITY_PWM; 118 | 119 | if (IS_PIN_SERVO(pin)) 120 | pin_cap |= PIN_CAPABILITY_SERVO; 121 | 122 | buf[2] = pin_cap; 123 | BLEMini_write_bytes(buf, 3); 124 | } 125 | 126 | void reportPinServoData(byte pin) 127 | { 128 | // if (IS_PIN_SERVO(pin)) 129 | // servos[PIN_TO_SERVO(pin)].write(value); 130 | // pin_servo[pin] = value; 131 | 132 | byte value = pin_servo[pin]; 133 | byte mode = pin_mode[pin]; 134 | byte buf[] = {'G', pin, mode, value}; 135 | BLEMini_write_bytes(buf, 4); 136 | } 137 | 138 | byte reportPinAnalogData() 139 | { 140 | static byte pin = 0; 141 | byte report = 0; 142 | 143 | if (!IS_PIN_DIGITAL(pin)) 144 | { 145 | pin++; 146 | if (pin >= TOTAL_PINS) 147 | pin = 0; 148 | return 0; 149 | } 150 | 151 | if (pin_mode[pin] == ANALOG) 152 | { 153 | uint16_t value = analogRead(pin); 154 | byte value_lo = value; 155 | byte value_hi = value>>8; 156 | 157 | byte mode = pin_mode[pin]; 158 | mode = (value_hi << 4) | mode; 159 | 160 | byte buf[] = {'G', pin, mode, value}; 161 | BLEMini_write_bytes(buf, 4); 162 | } 163 | 164 | pin++; 165 | if (pin >= TOTAL_PINS) 166 | pin = 0; 167 | 168 | return report; 169 | } 170 | 171 | void reportPinDigitalData(byte pin) 172 | { 173 | byte state = digitalRead(pin); 174 | byte mode = pin_mode[pin]; 175 | byte buf[] = {'G', pin, mode, state}; 176 | BLEMini_write_bytes(buf, 4); 177 | } 178 | 179 | void reportPinPWMData(byte pin) 180 | { 181 | byte value = pin_pwm[pin]; 182 | byte mode = pin_mode[pin]; 183 | byte buf[] = {'G', pin, mode, value}; 184 | BLEMini_write_bytes(buf, 4); 185 | } 186 | 187 | void sendCustomData(uint8_t *buf, uint8_t len) 188 | { 189 | uint8_t data[20] = "Z"; 190 | memcpy(&data[1], buf, len); 191 | BLEMini_write_bytes(data, len+1); 192 | } 193 | 194 | byte queryDone = false; 195 | 196 | void loop() 197 | { 198 | while(BLEMini_available()) 199 | { 200 | byte cmd; 201 | cmd = BLEMini_read(); 202 | 203 | #if !defined(__AVR_ATmega328P__) // don't print out on UNO 204 | Serial.write(cmd); 205 | #endif 206 | 207 | // Parse data here 208 | switch (cmd) 209 | { 210 | case 'V': // query protocol version 211 | { 212 | queryDone = false; 213 | 214 | byte buf[] = {'V', 0x00, 0x00, 0x01}; 215 | BLEMini_write_bytes(buf, 4); 216 | } 217 | break; 218 | 219 | case 'C': // query board total pin count 220 | { 221 | byte buf[2]; 222 | buf[0] = 'C'; 223 | buf[1] = TOTAL_PINS; 224 | BLEMini_write_bytes(buf, 2); 225 | } 226 | break; 227 | 228 | case 'M': // query pin mode 229 | { 230 | byte pin = BLEMini_read(); 231 | byte buf[] = {'M', pin, pin_mode[pin]}; // report pin mode 232 | BLEMini_write_bytes(buf, 3); 233 | } 234 | break; 235 | 236 | case 'S': // set pin mode 237 | { 238 | byte pin = BLEMini_read(); 239 | byte mode = BLEMini_read(); 240 | 241 | if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) 242 | servos[PIN_TO_SERVO(pin)].detach(); 243 | 244 | /* ToDo: check the mode is in its capability or not */ 245 | /* assume always ok */ 246 | if (mode != pin_mode[pin]) 247 | { 248 | pinMode(pin, mode); 249 | pin_mode[pin] = mode; 250 | 251 | if (mode == OUTPUT) 252 | { 253 | digitalWrite(pin, LOW); 254 | pin_state[pin] = LOW; 255 | } 256 | else if (mode == INPUT) 257 | { 258 | digitalWrite(pin, HIGH); 259 | pin_state[pin] = HIGH; 260 | } 261 | else if (mode == ANALOG) 262 | { 263 | if (IS_PIN_ANALOG(pin)) { 264 | if (IS_PIN_DIGITAL(pin)) { 265 | pinMode(PIN_TO_DIGITAL(pin), LOW); 266 | } 267 | } 268 | } 269 | else if (mode == PWM) 270 | { 271 | if (IS_PIN_PWM(pin)) 272 | { 273 | pinMode(PIN_TO_PWM(pin), OUTPUT); 274 | analogWrite(PIN_TO_PWM(pin), 0); 275 | pin_pwm[pin] = 0; 276 | pin_mode[pin] = PWM; 277 | } 278 | } 279 | else if (mode == SERVO) 280 | { 281 | if (IS_PIN_SERVO(pin)) 282 | { 283 | pin_servo[pin] = 0; 284 | pin_mode[pin] = SERVO; 285 | if (!servos[PIN_TO_SERVO(pin)].attached()) 286 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); 287 | } 288 | } 289 | } 290 | 291 | // if (mode == ANALOG) 292 | // reportPinAnalogData(pin); 293 | if ( (mode == INPUT) || (mode == OUTPUT) ) 294 | reportPinDigitalData(pin); 295 | else if (mode == PWM) 296 | reportPinPWMData(pin); 297 | else if (mode == SERVO) 298 | reportPinServoData(pin); 299 | } 300 | break; 301 | 302 | case 'G': // query pin data 303 | { 304 | byte pin = BLEMini_read(); 305 | reportPinDigitalData(pin); 306 | } 307 | break; 308 | 309 | case 'T': // set pin digital state 310 | { 311 | byte pin = BLEMini_read(); 312 | byte state = BLEMini_read(); 313 | 314 | digitalWrite(pin, state); 315 | reportPinDigitalData(pin); 316 | } 317 | break; 318 | 319 | case 'N': // set PWM 320 | { 321 | byte pin = BLEMini_read(); 322 | byte value = BLEMini_read(); 323 | 324 | analogWrite(PIN_TO_PWM(pin), value); 325 | pin_pwm[pin] = value; 326 | reportPinPWMData(pin); 327 | } 328 | break; 329 | 330 | case 'O': // set Servo 331 | { 332 | byte pin = BLEMini_read(); 333 | byte value = BLEMini_read(); 334 | 335 | if (IS_PIN_SERVO(pin)) 336 | servos[PIN_TO_SERVO(pin)].write(value); 337 | pin_servo[pin] = value; 338 | reportPinServoData(pin); 339 | } 340 | break; 341 | 342 | case 'A': // query all pin status 343 | for (int pin = 0; pin < TOTAL_PINS; pin++) 344 | { 345 | reportPinCapability(pin); 346 | if ( (pin_mode[pin] == INPUT) || (pin_mode[pin] == OUTPUT) ) 347 | reportPinDigitalData(pin); 348 | else if (pin_mode[pin] == PWM) 349 | reportPinPWMData(pin); 350 | else if (pin_mode[pin] == SERVO) 351 | reportPinServoData(pin); 352 | } 353 | 354 | queryDone = true; 355 | 356 | { 357 | uint8_t str[] = "ABC"; 358 | sendCustomData(str, 3); 359 | } 360 | 361 | break; 362 | 363 | case 'P': // query pin capability 364 | { 365 | byte pin = BLEMini_read(); 366 | reportPinCapability(pin); 367 | } 368 | break; 369 | 370 | case 'Z': 371 | { 372 | byte len = BLEMini_read(); 373 | byte buf[len]; 374 | for (int i=0;i"); 379 | Serial.print("Received: "); 380 | Serial.print(len); 381 | Serial.println(" byte(s)"); 382 | #endif 383 | } 384 | } 385 | 386 | return; // only do this task in this loop 387 | } 388 | 389 | // No input data, no commands, process analog data 390 | // if (!ble_connected()) 391 | // queryDone = false; // reset query state 392 | 393 | if (queryDone) // only report data after the query state 394 | { 395 | byte input_data_pending = reportDigitalInput(); 396 | if (input_data_pending) 397 | return; // only do this task in this loop 398 | 399 | currentMillis = millis(); 400 | if (currentMillis - previousMillis > samplingInterval) 401 | { 402 | previousMillis += samplingInterval; 403 | 404 | reportPinAnalogData(); 405 | } 406 | } 407 | } 408 | 409 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/examples/BLEControllerSketch/Boards.h: -------------------------------------------------------------------------------- 1 | /* Boards.h - Hardware Abstraction Layer for Firmata library */ 2 | 3 | #ifndef Firmata_Boards_h 4 | #define Firmata_Boards_h 5 | 6 | #include 7 | 8 | #if defined(ARDUINO) && ARDUINO >= 100 9 | #include "Arduino.h" // for digitalRead, digitalWrite, etc 10 | #else 11 | #include "WProgram.h" 12 | #endif 13 | 14 | // Normally Servo.h must be included before Firmata.h (which then includes 15 | // this file). If Servo.h wasn't included, this allows the code to still 16 | // compile, but without support for any Servos. Hopefully that's what the 17 | // user intended by not including Servo.h 18 | #ifndef MAX_SERVOS 19 | #define MAX_SERVOS 0 20 | #endif 21 | 22 | /* 23 | Firmata Hardware Abstraction Layer 24 | 25 | Firmata is built on top of the hardware abstraction functions of Arduino, 26 | specifically digitalWrite, digitalRead, analogWrite, analogRead, and 27 | pinMode. While these functions offer simple integer pin numbers, Firmata 28 | needs more information than is provided by Arduino. This file provides 29 | all other hardware specific details. To make Firmata support a new board, 30 | only this file should require editing. 31 | 32 | The key concept is every "pin" implemented by Firmata may be mapped to 33 | any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is 34 | best, but such mapping should not be assumed. This hardware abstraction 35 | layer allows Firmata to implement any number of pins which map onto the 36 | Arduino implemented pins in almost any arbitrary way. 37 | 38 | 39 | General Constants: 40 | 41 | These constants provide basic information Firmata requires. 42 | 43 | TOTAL_PINS: The total number of pins Firmata implemented by Firmata. 44 | Usually this will match the number of pins the Arduino functions 45 | implement, including any pins pins capable of analog or digital. 46 | However, Firmata may implement any number of pins. For example, 47 | on Arduino Mini with 8 analog inputs, 6 of these may be used 48 | for digital functions, and 2 are analog only. On such boards, 49 | Firmata can implement more pins than Arduino's pinMode() 50 | function, in order to accommodate those special pins. The 51 | Firmata protocol supports a maximum of 128 pins, so this 52 | constant must not exceed 128. 53 | 54 | TOTAL_ANALOG_PINS: The total number of analog input pins implemented. 55 | The Firmata protocol allows up to 16 analog inputs, accessed 56 | using offsets 0 to 15. Because Firmata presents the analog 57 | inputs using different offsets than the actual pin numbers 58 | (a legacy of Arduino's analogRead function, and the way the 59 | analog input capable pins are physically labeled on all 60 | Arduino boards), the total number of analog input signals 61 | must be specified. 16 is the maximum. 62 | 63 | VERSION_BLINK_PIN: When Firmata starts up, it will blink the version 64 | number. This constant is the Arduino pin number where a 65 | LED is connected. 66 | 67 | 68 | Pin Mapping Macros: 69 | 70 | These macros provide the mapping between pins as implemented by 71 | Firmata protocol and the actual pin numbers used by the Arduino 72 | functions. Even though such mappings are often simple, pin 73 | numbers received by Firmata protocol should always be used as 74 | input to these macros, and the result of the macro should be 75 | used with with any Arduino function. 76 | 77 | When Firmata is extended to support a new pin mode or feature, 78 | a pair of macros should be added and used for all hardware 79 | access. For simple 1:1 mapping, these macros add no actual 80 | overhead, yet their consistent use allows source code which 81 | uses them consistently to be easily adapted to all other boards 82 | with different requirements. 83 | 84 | IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero 85 | if a pin as implemented by Firmata corresponds to a pin 86 | that actually implements the named feature. 87 | 88 | PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as 89 | implemented by Firmata to the pin numbers needed as inputs 90 | to the Arduino functions. The corresponding IS_PIN macro 91 | should always be tested before using a PIN_TO macro, so 92 | these macros only need to handle valid Firmata pin 93 | numbers for the named feature. 94 | 95 | 96 | Port Access Inline Funtions: 97 | 98 | For efficiency, Firmata protocol provides access to digital 99 | input and output pins grouped by 8 bit ports. When these 100 | groups of 8 correspond to actual 8 bit ports as implemented 101 | by the hardware, these inline functions can provide high 102 | speed direct port access. Otherwise, a default implementation 103 | using 8 calls to digitalWrite or digitalRead is used. 104 | 105 | When porting Firmata to a new board, it is recommended to 106 | use the default functions first and focus only on the constants 107 | and macros above. When those are working, if optimized port 108 | access is desired, these inline functions may be extended. 109 | The recommended approach defines a symbol indicating which 110 | optimization to use, and then conditional complication is 111 | used within these functions. 112 | 113 | readPort(port, bitmask): Read an 8 bit port, returning the value. 114 | port: The port number, Firmata pins port*8 to port*8+7 115 | bitmask: The actual pins to read, indicated by 1 bits. 116 | 117 | writePort(port, value, bitmask): Write an 8 bit port. 118 | port: The port number, Firmata pins port*8 to port*8+7 119 | value: The 8 bit value to write 120 | bitmask: The actual pins to write, indicated by 1 bits. 121 | */ 122 | 123 | /*============================================================================== 124 | * Board Specific Configuration 125 | *============================================================================*/ 126 | 127 | #ifndef digitalPinHasPWM 128 | #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p) 129 | #endif 130 | 131 | // Arduino Duemilanove, Diecimila, and NG 132 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) 133 | #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 134 | #define TOTAL_ANALOG_PINS 6 135 | #define TOTAL_PINS 20 // 14 digital + 6 analog 136 | #else 137 | #define TOTAL_ANALOG_PINS 8 138 | #define TOTAL_PINS 22 // 14 digital + 8 analog 139 | #endif 140 | #define VERSION_BLINK_PIN 13 141 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) 142 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) 143 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 144 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) 145 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) 146 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 147 | #define PIN_TO_DIGITAL(p) (p) 148 | #define PIN_TO_ANALOG(p) ((p) - 14) 149 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 150 | #define PIN_TO_SERVO(p) ((p) - 2) 151 | #define ARDUINO_PINOUT_OPTIMIZE 1 152 | 153 | 154 | // Wiring (and board) 155 | #elif defined(WIRING) 156 | #define VERSION_BLINK_PIN WLED 157 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 158 | #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS)) 159 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 160 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 161 | #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) 162 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 163 | #define PIN_TO_DIGITAL(p) (p) 164 | #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN) 165 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 166 | #define PIN_TO_SERVO(p) (p) 167 | 168 | 169 | // old Arduinos 170 | #elif defined(__AVR_ATmega8__) 171 | #define TOTAL_ANALOG_PINS 6 172 | #define TOTAL_PINS 20 // 14 digital + 6 analog 173 | #define VERSION_BLINK_PIN 13 174 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) 175 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19) 176 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 177 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) 178 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) 179 | #define PIN_TO_DIGITAL(p) (p) 180 | #define PIN_TO_ANALOG(p) ((p) - 14) 181 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 182 | #define PIN_TO_SERVO(p) ((p) - 2) 183 | #define ARDUINO_PINOUT_OPTIMIZE 1 184 | 185 | 186 | // Arduino Mega 187 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 188 | #define TOTAL_ANALOG_PINS 16 189 | #define TOTAL_PINS 70 // 54 digital + 16 analog 190 | #define VERSION_BLINK_PIN 13 191 | #define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 13) || ((p) >= 20 && (p) < TOTAL_PINS)) 192 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) 193 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 194 | #define IS_PIN_SERVO(p) ((p) >= 2 && ((p) <= 13 && (p) - 2 < MAX_SERVOS)) || ((p) >= 20 && (p) - 2 < MAX_SERVOS) 195 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) 196 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 197 | #define PIN_TO_DIGITAL(p) (p) 198 | #define PIN_TO_ANALOG(p) ((p) - 54) 199 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 200 | #define PIN_TO_SERVO(p) ((p) - 2) 201 | 202 | 203 | // Arduino DUE 204 | #elif defined(__SAM3X8E__) 205 | #define TOTAL_ANALOG_PINS 12 206 | #define TOTAL_PINS 66 // 54 digital + 12 analog 207 | #define VERSION_BLINK_PIN 13 208 | #define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 13) || ((p) >= 20 && (p) < TOTAL_PINS)) 209 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) 210 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 211 | #define IS_PIN_SERVO(p) ((p) >= 2 && ((p) <= 13 && (p) - 2 < MAX_SERVOS)) || ((p) >= 20 && (p) - 2 < MAX_SERVOS) 212 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71 213 | #define PIN_TO_DIGITAL(p) (p) 214 | #define PIN_TO_ANALOG(p) ((p) - 54) 215 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 216 | #define PIN_TO_SERVO(p) ((p) - 2) 217 | 218 | 219 | // Teensy 1.0 220 | #elif defined(__AVR_AT90USB162__) 221 | #define TOTAL_ANALOG_PINS 0 222 | #define TOTAL_PINS 21 // 21 digital + no analog 223 | #define VERSION_BLINK_PIN 6 224 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 225 | #define IS_PIN_ANALOG(p) (0) 226 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 227 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 228 | #define IS_PIN_I2C(p) (0) 229 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 230 | #define PIN_TO_DIGITAL(p) (p) 231 | #define PIN_TO_ANALOG(p) (0) 232 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 233 | #define PIN_TO_SERVO(p) (p) 234 | 235 | 236 | // Teensy 2.0 237 | #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) 238 | #define TOTAL_ANALOG_PINS 12 239 | #define TOTAL_PINS 25 // 11 digital + 12 analog 240 | #define VERSION_BLINK_PIN 13 241 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 242 | #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22) 243 | #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13) 244 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 245 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6) 246 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 247 | #define PIN_TO_DIGITAL(p) (p) 248 | #define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11) 249 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 250 | #define PIN_TO_SERVO(p) (p) 251 | 252 | 253 | // Teensy 3.0 254 | #elif defined(__MK20DX128__) 255 | #define TOTAL_ANALOG_PINS 14 256 | #define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog 257 | #define VERSION_BLINK_PIN 13 258 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 34) 259 | #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38)) 260 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 261 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 262 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) 263 | #define PIN_TO_DIGITAL(p) (p) 264 | #define PIN_TO_ANALOG(p) (((p)<=23)?(p)-14:(p)-24) 265 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 266 | #define PIN_TO_SERVO(p) (p) 267 | 268 | 269 | // Teensy++ 1.0 and 2.0 270 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 271 | #define TOTAL_ANALOG_PINS 8 272 | #define TOTAL_PINS 46 // 38 digital + 8 analog 273 | #define VERSION_BLINK_PIN 6 274 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 275 | #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS) 276 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 277 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 278 | #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1) 279 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 280 | #define PIN_TO_DIGITAL(p) (p) 281 | #define PIN_TO_ANALOG(p) ((p) - 38) 282 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 283 | #define PIN_TO_SERVO(p) (p) 284 | 285 | 286 | // Leonardo 287 | #elif defined(__AVR_ATmega32U4__) 288 | #define TOTAL_ANALOG_PINS 12 289 | #define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header) 290 | #define VERSION_BLINK_PIN 13 291 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) 292 | #define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS) 293 | #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13) 294 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) < MAX_SERVOS) 295 | #define IS_PIN_I2C(p) ((p) == 2 || (p) == 3) 296 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 297 | #define PIN_TO_DIGITAL(p) (p) 298 | #define PIN_TO_ANALOG(p) (p) - 18 299 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 300 | #define PIN_TO_SERVO(p) (p) 301 | 302 | 303 | // Sanguino 304 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) 305 | #define TOTAL_ANALOG_PINS 8 306 | #define TOTAL_PINS 32 // 24 digital + 8 analog 307 | #define VERSION_BLINK_PIN 0 308 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) 309 | #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS) 310 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 311 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 312 | #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17) 313 | #define PIN_TO_DIGITAL(p) (p) 314 | #define PIN_TO_ANALOG(p) ((p) - 24) 315 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 316 | #define PIN_TO_SERVO(p) ((p) - 2) 317 | 318 | 319 | // Illuminato 320 | #elif defined(__AVR_ATmega645__) 321 | #define TOTAL_ANALOG_PINS 6 322 | #define TOTAL_PINS 42 // 36 digital + 6 analog 323 | #define VERSION_BLINK_PIN 13 324 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) 325 | #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS) 326 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 327 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 328 | #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5) 329 | #define PIN_TO_DIGITAL(p) (p) 330 | #define PIN_TO_ANALOG(p) ((p) - 36) 331 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 332 | #define PIN_TO_SERVO(p) ((p) - 2) 333 | 334 | 335 | // anything else 336 | #else 337 | #error "Please edit Boards.h with a hardware abstraction for this board" 338 | #endif 339 | 340 | // as long this is not defined for all boards: 341 | #ifndef IS_PIN_SPI(p) 342 | #define IS_PIN_SPI(p) 0 343 | #endif 344 | 345 | /*============================================================================== 346 | * readPort() - Read an 8 bit port 347 | *============================================================================*/ 348 | 349 | static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused)); 350 | static inline unsigned char readPort(byte port, byte bitmask) 351 | { 352 | #if defined(ARDUINO_PINOUT_OPTIMIZE) 353 | if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1 354 | if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask; 355 | if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask; 356 | return 0; 357 | #else 358 | unsigned char out=0, pin=port*8; 359 | if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01; 360 | if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02; 361 | if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04; 362 | if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08; 363 | if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10; 364 | if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20; 365 | if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40; 366 | if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80; 367 | return out; 368 | #endif 369 | } 370 | 371 | /*============================================================================== 372 | * writePort() - Write an 8 bit port, only touch pins specified by a bitmask 373 | *============================================================================*/ 374 | 375 | static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused)); 376 | static inline unsigned char writePort(byte port, byte value, byte bitmask) 377 | { 378 | #if defined(ARDUINO_PINOUT_OPTIMIZE) 379 | if (port == 0) { 380 | bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins 381 | byte valD = value & bitmask; 382 | byte maskD = ~bitmask; 383 | cli(); 384 | PORTD = (PORTD & maskD) | valD; 385 | sei(); 386 | } else if (port == 1) { 387 | byte valB = (value & bitmask) & 0x3F; 388 | byte valC = (value & bitmask) >> 6; 389 | byte maskB = ~(bitmask & 0x3F); 390 | byte maskC = ~((bitmask & 0xC0) >> 6); 391 | cli(); 392 | PORTB = (PORTB & maskB) | valB; 393 | PORTC = (PORTC & maskC) | valC; 394 | sei(); 395 | } else if (port == 2) { 396 | bitmask = bitmask & 0x0F; 397 | byte valC = (value & bitmask) << 2; 398 | byte maskC = ~(bitmask << 2); 399 | cli(); 400 | PORTC = (PORTC & maskC) | valC; 401 | sei(); 402 | } 403 | #else 404 | byte pin=port*8; 405 | if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01)); 406 | if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02)); 407 | if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04)); 408 | if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08)); 409 | if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10)); 410 | if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20)); 411 | if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40)); 412 | if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80)); 413 | #endif 414 | } 415 | 416 | 417 | 418 | 419 | #ifndef TOTAL_PORTS 420 | #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8) 421 | #endif 422 | 423 | 424 | #endif /* Firmata_Boards_h */ 425 | 426 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/examples/BLEFirmataSketch/BLEFirmata.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Firmata.cpp - Firmata library 3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | See file LICENSE.txt for further informations on licensing terms. 11 | */ 12 | 13 | //****************************************************************************** 14 | //* Includes 15 | //****************************************************************************** 16 | 17 | #include "BLEFirmata.h" 18 | #include "HardwareSerial.h" 19 | #include "ble_mini.h" 20 | 21 | extern "C" { 22 | #include 23 | #include 24 | } 25 | 26 | //****************************************************************************** 27 | //* Support Functions 28 | //****************************************************************************** 29 | 30 | void BleFirmataClass::sendValueAsTwo7bitBytes(int value) 31 | { 32 | BLEMini_write(value & B01111111); // LSB 33 | BLEMini_write(value >> 7 & B01111111); // MSB 34 | } 35 | 36 | void BleFirmataClass::startSysex(void) 37 | { 38 | BLEMini_write(START_SYSEX); 39 | } 40 | 41 | void BleFirmataClass::endSysex(void) 42 | { 43 | BLEMini_write(END_SYSEX); 44 | } 45 | 46 | //****************************************************************************** 47 | //* Constructors 48 | //****************************************************************************** 49 | 50 | BleFirmataClass::BleFirmataClass(Stream &s) : BleFirmataSerial(s) 51 | { 52 | firmwareVersionCount = 0; 53 | systemReset(); 54 | } 55 | 56 | //****************************************************************************** 57 | //* Public Methods 58 | //****************************************************************************** 59 | 60 | /* begin method for overriding default serial bitrate */ 61 | void BleFirmataClass::begin(void) 62 | { 63 | begin(57600); 64 | } 65 | 66 | /* begin method for overriding default serial bitrate */ 67 | void BleFirmataClass::begin(long speed) 68 | { 69 | // Serial.begin(speed); 70 | BleFirmataSerial = Serial; 71 | blinkVersion(); 72 | printVersion(); 73 | printFirmwareVersion(); 74 | } 75 | 76 | void BleFirmataClass::begin(Stream &s) 77 | { 78 | BleFirmataSerial = s; 79 | systemReset(); 80 | printVersion(); 81 | printFirmwareVersion(); 82 | } 83 | 84 | // output the protocol version message to the serial port 85 | void BleFirmataClass::printVersion(void) { 86 | BLEMini_write(REPORT_VERSION); 87 | BLEMini_write(FIRMATA_MAJOR_VERSION); 88 | BLEMini_write(FIRMATA_MINOR_VERSION); 89 | } 90 | 91 | void BleFirmataClass::blinkVersion(void) 92 | { 93 | // flash the pin with the protocol version 94 | pinMode(VERSION_BLINK_PIN,OUTPUT); 95 | pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210); 96 | delay(250); 97 | pin13strobe(FIRMATA_MINOR_VERSION, 40, 210); 98 | delay(125); 99 | } 100 | 101 | void BleFirmataClass::printFirmwareVersion(void) 102 | { 103 | byte i; 104 | 105 | if(firmwareVersionCount) { // make sure that the name has been set before reporting 106 | startSysex(); 107 | BLEMini_write(REPORT_FIRMWARE); 108 | BLEMini_write(firmwareVersionVector[0]); // major version number 109 | BLEMini_write(firmwareVersionVector[1]); // minor version number 110 | for(i=2; i 0) && (inputData < 128) ) { 198 | waitForData--; 199 | storedInputData[waitForData] = inputData; 200 | if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message 201 | switch(executeMultiByteCommand) { 202 | case ANALOG_MESSAGE: 203 | if(currentAnalogCallback) { 204 | (*currentAnalogCallback)(multiByteChannel, 205 | (storedInputData[0] << 7) 206 | + storedInputData[1]); 207 | } 208 | break; 209 | case DIGITAL_MESSAGE: 210 | if(currentDigitalCallback) { 211 | (*currentDigitalCallback)(multiByteChannel, 212 | (storedInputData[0] << 7) 213 | + storedInputData[1]); 214 | } 215 | break; 216 | case SET_PIN_MODE: 217 | if(currentPinModeCallback) 218 | (*currentPinModeCallback)(storedInputData[1], storedInputData[0]); 219 | break; 220 | case REPORT_ANALOG: 221 | if(currentReportAnalogCallback) 222 | (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]); 223 | break; 224 | case REPORT_DIGITAL: 225 | if(currentReportDigitalCallback) 226 | (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]); 227 | break; 228 | } 229 | executeMultiByteCommand = 0; 230 | } 231 | } else { 232 | // remove channel info from command byte if less than 0xF0 233 | if(inputData < 0xF0) { 234 | command = inputData & 0xF0; 235 | multiByteChannel = inputData & 0x0F; 236 | } else { 237 | command = inputData; 238 | // commands in the 0xF* range don't use channel data 239 | } 240 | switch (command) { 241 | case ANALOG_MESSAGE: 242 | case DIGITAL_MESSAGE: 243 | case SET_PIN_MODE: 244 | waitForData = 2; // two data bytes needed 245 | executeMultiByteCommand = command; 246 | break; 247 | case REPORT_ANALOG: 248 | case REPORT_DIGITAL: 249 | waitForData = 1; // two data bytes needed 250 | executeMultiByteCommand = command; 251 | break; 252 | case START_SYSEX: 253 | parsingSysex = true; 254 | sysexBytesRead = 0; 255 | break; 256 | case SYSTEM_RESET: 257 | systemReset(); 258 | break; 259 | case REPORT_VERSION: 260 | BleFirmata.printVersion(); 261 | break; 262 | } 263 | } 264 | } 265 | 266 | //------------------------------------------------------------------------------ 267 | // Serial Send Handling 268 | 269 | // send an analog message 270 | void BleFirmataClass::sendAnalog(byte pin, int value) 271 | { 272 | // pin can only be 0-15, so chop higher bits 273 | BLEMini_write(ANALOG_MESSAGE | (pin & 0xF)); 274 | sendValueAsTwo7bitBytes(value); 275 | } 276 | 277 | // send a single digital pin in a digital message 278 | void BleFirmataClass::sendDigital(byte pin, int value) 279 | { 280 | /* TODO add single pin digital messages to the protocol, this needs to 281 | * track the last digital data sent so that it can be sure to change just 282 | * one bit in the packet. This is complicated by the fact that the 283 | * numbering of the pins will probably differ on Arduino, Wiring, and 284 | * other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is 285 | * probably easier to send 8 bit ports for any board with more than 14 286 | * digital pins. 287 | */ 288 | 289 | // TODO: the digital message should not be sent on the serial port every 290 | // time sendDigital() is called. Instead, it should add it to an int 291 | // which will be sent on a schedule. If a pin changes more than once 292 | // before the digital message is sent on the serial port, it should send a 293 | // digital message for each change. 294 | 295 | // if(value == 0) 296 | // sendDigitalPortPair(); 297 | } 298 | 299 | 300 | // send 14-bits in a single digital message (protocol v1) 301 | // send an 8-bit port in a single digital message (protocol v2) 302 | void BleFirmataClass::sendDigitalPort(byte portNumber, int portData) 303 | { 304 | BLEMini_write(DIGITAL_MESSAGE | (portNumber & 0xF)); 305 | BLEMini_write((byte)portData % 128); // Tx bits 0-6 306 | BLEMini_write(portData >> 7); // Tx bits 7-13 307 | } 308 | 309 | 310 | void BleFirmataClass::sendSysex(byte command, byte bytec, byte* bytev) 311 | { 312 | byte i; 313 | startSysex(); 314 | BLEMini_write(command); 315 | for(i=0; i 3 | #include 4 | #include "BLEFirmata.h" 5 | #include 6 | /* 7 | * Firmata is a generic protocol for communicating with microcontrollers 8 | * from software on a host computer. It is intended to work with 9 | * any host computer software package. 10 | * 11 | * To download a host software package, please clink on the following link 12 | * to open the download page in your default browser. 13 | * 14 | * http://firmata.org/wiki/Download 15 | */ 16 | 17 | /* 18 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. 19 | Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. 20 | Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. 21 | Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved. 22 | 23 | This library is free software; you can redistribute it and/or 24 | modify it under the terms of the GNU Lesser General Public 25 | License as published by the Free Software Foundation; either 26 | version 2.1 of the License, or (at your option) any later version. 27 | 28 | See file LICENSE.txt for further informations on licensing terms. 29 | 30 | formatted using the GNU C formatting and indenting 31 | */ 32 | 33 | /* 34 | * TODO: use Program Control to load stored profiles from EEPROM 35 | */ 36 | 37 | // move the following defines to Firmata.h? 38 | #define I2C_WRITE B00000000 39 | #define I2C_READ B00001000 40 | #define I2C_READ_CONTINUOUSLY B00010000 41 | #define I2C_STOP_READING B00011000 42 | #define I2C_READ_WRITE_MODE_MASK B00011000 43 | #define I2C_10BIT_ADDRESS_MODE_MASK B00100000 44 | 45 | #define MAX_QUERIES 8 46 | #define MINIMUM_SAMPLING_INTERVAL 10 47 | 48 | #define REGISTER_NOT_SPECIFIED -1 49 | 50 | /*============================================================================== 51 | * GLOBAL VARIABLES 52 | *============================================================================*/ 53 | 54 | /* analog inputs */ 55 | int analogInputsToReport = 0; // bitwise array to store pin reporting 56 | 57 | /* digital input ports */ 58 | byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence 59 | byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent 60 | 61 | /* pins configuration */ 62 | byte pinConfig[TOTAL_PINS]; // configuration of every pin 63 | byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else 64 | int pinState[TOTAL_PINS]; // any value that has been written 65 | 66 | /* timer variables */ 67 | unsigned long currentMillis; // store the current value from millis() 68 | unsigned long previousMillis; // for comparison with currentMillis 69 | int samplingInterval = 38; // how often to run the main loop (in ms) 70 | 71 | /* i2c data */ 72 | struct i2c_device_info { 73 | byte addr; 74 | byte reg; 75 | byte bytes; 76 | }; 77 | 78 | /* for i2c read continuous more */ 79 | i2c_device_info query[MAX_QUERIES]; 80 | 81 | byte i2cRxData[32]; 82 | boolean isI2CEnabled = false; 83 | signed char queryIndex = -1; 84 | unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom() 85 | 86 | Servo servos[MAX_SERVOS]; 87 | /*============================================================================== 88 | * FUNCTIONS 89 | *============================================================================*/ 90 | 91 | void readAndReportData(byte address, int theRegister, byte numBytes) { 92 | // allow I2C requests that don't require a register read 93 | // for example, some devices using an interrupt pin to signify new data available 94 | // do not always require the register read so upon interrupt you call Wire.requestFrom() 95 | if (theRegister != REGISTER_NOT_SPECIFIED) { 96 | Wire.beginTransmission(address); 97 | #if ARDUINO >= 100 98 | Wire.write((byte)theRegister); 99 | #else 100 | Wire.send((byte)theRegister); 101 | #endif 102 | Wire.endTransmission(); 103 | delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck 104 | } else { 105 | theRegister = 0; // fill the register with a dummy value 106 | } 107 | 108 | Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom 109 | 110 | // check to be sure correct number of bytes were returned by slave 111 | if(numBytes == Wire.available()) { 112 | i2cRxData[0] = address; 113 | i2cRxData[1] = theRegister; 114 | for (int i = 0; i < numBytes; i++) { 115 | #if ARDUINO >= 100 116 | i2cRxData[2 + i] = Wire.read(); 117 | #else 118 | i2cRxData[2 + i] = Wire.receive(); 119 | #endif 120 | } 121 | } 122 | else { 123 | if(numBytes > Wire.available()) { 124 | BleFirmata.sendString("I2C Read Error: Too many bytes received"); 125 | } else { 126 | BleFirmata.sendString("I2C Read Error: Too few bytes received"); 127 | } 128 | } 129 | 130 | // send slave address, register and received bytes 131 | BleFirmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData); 132 | } 133 | 134 | void outputPort(byte portNumber, byte portValue, byte forceSend) 135 | { 136 | // pins not configured as INPUT are cleared to zeros 137 | portValue = portValue & portConfigInputs[portNumber]; 138 | 139 | // only send if the value is different than previously sent 140 | if(forceSend || previousPINs[portNumber] != portValue) { 141 | BleFirmata.sendDigitalPort(portNumber, portValue); 142 | previousPINs[portNumber] = portValue; 143 | } 144 | } 145 | 146 | /* ----------------------------------------------------------------------------- 147 | * check all the active digital inputs for change of state, then add any events 148 | * to the Serial output queue using Serial.print() */ 149 | void checkDigitalInputs(void) 150 | { 151 | /* Using non-looping code allows constants to be given to readPort(). 152 | * The compiler will apply substantial optimizations if the inputs 153 | * to readPort() are compile-time constants. */ 154 | if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false); 155 | if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false); 156 | if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false); 157 | if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false); 158 | if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false); 159 | if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false); 160 | if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false); 161 | if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false); 162 | if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false); 163 | if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false); 164 | if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false); 165 | if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false); 166 | if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false); 167 | if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false); 168 | if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false); 169 | if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false); 170 | } 171 | 172 | // ----------------------------------------------------------------------------- 173 | /* sets the pin mode to the correct state and sets the relevant bits in the 174 | * two bit-arrays that track Digital I/O and PWM status 175 | */ 176 | void setPinModeCallback(byte pin, int mode) 177 | { 178 | if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) { 179 | // disable i2c so pins can be used for other functions 180 | // the following if statements should reconfigure the pins properly 181 | disableI2CPins(); 182 | } 183 | if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { 184 | servos[PIN_TO_SERVO(pin)].detach(); 185 | } 186 | if (IS_PIN_ANALOG(pin)) { 187 | reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting 188 | } 189 | if (IS_PIN_DIGITAL(pin)) { 190 | if (mode == INPUT) { 191 | portConfigInputs[pin/8] |= (1 << (pin & 7)); 192 | } else { 193 | portConfigInputs[pin/8] &= ~(1 << (pin & 7)); 194 | } 195 | } 196 | pinState[pin] = 0; 197 | switch(mode) { 198 | case ANALOG: 199 | if (IS_PIN_ANALOG(pin)) { 200 | if (IS_PIN_DIGITAL(pin)) { 201 | pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 202 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups 203 | } 204 | pinConfig[pin] = ANALOG; 205 | } 206 | break; 207 | case INPUT: 208 | if (IS_PIN_DIGITAL(pin)) { 209 | pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 210 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups 211 | pinConfig[pin] = INPUT; 212 | 213 | // hack it only 214 | reportPINs[pin/8] |= (1 << (pin & 7)); 215 | } 216 | break; 217 | case OUTPUT: 218 | if (IS_PIN_DIGITAL(pin)) { 219 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM 220 | pinMode(PIN_TO_DIGITAL(pin), OUTPUT); 221 | pinConfig[pin] = OUTPUT; 222 | } 223 | break; 224 | case PWM: 225 | if (IS_PIN_PWM(pin)) { 226 | pinMode(PIN_TO_PWM(pin), OUTPUT); 227 | analogWrite(PIN_TO_PWM(pin), 0); 228 | pinConfig[pin] = PWM; 229 | } 230 | break; 231 | case SERVO: 232 | if (IS_PIN_SERVO(pin)) { 233 | pinConfig[pin] = SERVO; 234 | if (!servos[PIN_TO_SERVO(pin)].attached()) { 235 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); 236 | } 237 | } 238 | break; 239 | case I2C: 240 | if (IS_PIN_I2C(pin)) { 241 | // mark the pin as i2c 242 | // the user must call I2C_CONFIG to enable I2C for a device 243 | pinConfig[pin] = I2C; 244 | } 245 | break; 246 | default: 247 | BleFirmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM 248 | } 249 | // TODO: save status to EEPROM here, if changed 250 | } 251 | 252 | void analogWriteCallback(byte pin, int value) 253 | { 254 | if (pin < TOTAL_PINS) { 255 | switch(pinConfig[pin]) { 256 | case SERVO: 257 | if (IS_PIN_SERVO(pin)) 258 | servos[PIN_TO_SERVO(pin)].write(value); 259 | pinState[pin] = value; 260 | break; 261 | case PWM: 262 | if (IS_PIN_PWM(pin)) 263 | analogWrite(PIN_TO_PWM(pin), value); 264 | pinState[pin] = value; 265 | break; 266 | } 267 | } 268 | } 269 | 270 | void digitalWriteCallback(byte port, int value) 271 | { 272 | byte pin, lastPin, mask=1, pinWriteMask=0; 273 | 274 | if (port < TOTAL_PORTS) { 275 | // create a mask of the pins on this port that are writable. 276 | lastPin = port*8+8; 277 | if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS; 278 | for (pin=port*8; pin < lastPin; pin++) { 279 | // do not disturb non-digital pins (eg, Rx & Tx) 280 | if (IS_PIN_DIGITAL(pin)) { 281 | // only write to OUTPUT and INPUT (enables pullup) 282 | // do not touch pins in PWM, ANALOG, SERVO or other modes 283 | if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) { 284 | pinWriteMask |= mask; 285 | pinState[pin] = ((byte)value & mask) ? 1 : 0; 286 | } 287 | } 288 | mask = mask << 1; 289 | } 290 | writePort(port, (byte)value, pinWriteMask); 291 | } 292 | } 293 | 294 | 295 | // ----------------------------------------------------------------------------- 296 | /* sets bits in a bit array (int) to toggle the reporting of the analogIns 297 | */ 298 | //void FirmataClass::setAnalogPinReporting(byte pin, byte state) { 299 | //} 300 | void reportAnalogCallback(byte analogPin, int value) 301 | { 302 | if (analogPin < TOTAL_ANALOG_PINS) { 303 | if(value == 0) { 304 | analogInputsToReport = analogInputsToReport &~ (1 << analogPin); 305 | } else { 306 | analogInputsToReport = analogInputsToReport | (1 << analogPin); 307 | } 308 | } 309 | // TODO: save status to EEPROM here, if changed 310 | } 311 | 312 | void reportDigitalCallback(byte port, int value) 313 | { 314 | if (port < TOTAL_PORTS) { 315 | reportPINs[port] = (byte)value; 316 | } 317 | // do not disable analog reporting on these 8 pins, to allow some 318 | // pins used for digital, others analog. Instead, allow both types 319 | // of reporting to be enabled, but check if the pin is configured 320 | // as analog when sampling the analog inputs. Likewise, while 321 | // scanning digital pins, portConfigInputs will mask off values from any 322 | // pins configured as analog 323 | } 324 | 325 | /*============================================================================== 326 | * SYSEX-BASED commands 327 | *============================================================================*/ 328 | 329 | void sysexCallback(byte command, byte argc, byte *argv) 330 | { 331 | byte mode; 332 | byte slaveAddress; 333 | byte slaveRegister; 334 | byte data; 335 | unsigned int delayTime; 336 | 337 | switch(command) { 338 | case I2C_REQUEST: 339 | mode = argv[1] & I2C_READ_WRITE_MODE_MASK; 340 | if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { 341 | BleFirmata.sendString("10-bit addressing mode is not yet supported"); 342 | return; 343 | } 344 | else { 345 | slaveAddress = argv[0]; 346 | } 347 | 348 | switch(mode) { 349 | case I2C_WRITE: 350 | Wire.beginTransmission(slaveAddress); 351 | for (byte i = 2; i < argc; i += 2) { 352 | data = argv[i] + (argv[i + 1] << 7); 353 | #if ARDUINO >= 100 354 | Wire.write(data); 355 | #else 356 | Wire.send(data); 357 | #endif 358 | } 359 | Wire.endTransmission(); 360 | delayMicroseconds(70); 361 | break; 362 | case I2C_READ: 363 | if (argc == 6) { 364 | // a slave register is specified 365 | slaveRegister = argv[2] + (argv[3] << 7); 366 | data = argv[4] + (argv[5] << 7); // bytes to read 367 | readAndReportData(slaveAddress, (int)slaveRegister, data); 368 | } 369 | else { 370 | // a slave register is NOT specified 371 | data = argv[2] + (argv[3] << 7); // bytes to read 372 | readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data); 373 | } 374 | break; 375 | case I2C_READ_CONTINUOUSLY: 376 | if ((queryIndex + 1) >= MAX_QUERIES) { 377 | // too many queries, just ignore 378 | BleFirmata.sendString("too many queries"); 379 | break; 380 | } 381 | queryIndex++; 382 | query[queryIndex].addr = slaveAddress; 383 | query[queryIndex].reg = argv[2] + (argv[3] << 7); 384 | query[queryIndex].bytes = argv[4] + (argv[5] << 7); 385 | break; 386 | case I2C_STOP_READING: 387 | byte queryIndexToSkip; 388 | // if read continuous mode is enabled for only 1 i2c device, disable 389 | // read continuous reporting for that device 390 | if (queryIndex <= 0) { 391 | queryIndex = -1; 392 | } else { 393 | // if read continuous mode is enabled for multiple devices, 394 | // determine which device to stop reading and remove it's data from 395 | // the array, shifiting other array data to fill the space 396 | for (byte i = 0; i < queryIndex + 1; i++) { 397 | if (query[i].addr = slaveAddress) { 398 | queryIndexToSkip = i; 399 | break; 400 | } 401 | } 402 | 403 | for (byte i = queryIndexToSkip; i 0) { 421 | i2cReadDelayTime = delayTime; 422 | } 423 | 424 | if (!isI2CEnabled) { 425 | enableI2CPins(); 426 | } 427 | 428 | break; 429 | case SERVO_CONFIG: 430 | if(argc > 4) { 431 | // these vars are here for clarity, they'll optimized away by the compiler 432 | byte pin = argv[0]; 433 | int minPulse = argv[1] + (argv[2] << 7); 434 | int maxPulse = argv[3] + (argv[4] << 7); 435 | 436 | if (IS_PIN_SERVO(pin)) { 437 | if (servos[PIN_TO_SERVO(pin)].attached()) 438 | servos[PIN_TO_SERVO(pin)].detach(); 439 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); 440 | setPinModeCallback(pin, SERVO); 441 | } 442 | } 443 | break; 444 | case SAMPLING_INTERVAL: 445 | if (argc > 1) { 446 | samplingInterval = argv[0] + (argv[1] << 7); 447 | if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) { 448 | samplingInterval = MINIMUM_SAMPLING_INTERVAL; 449 | } 450 | } else { 451 | //Firmata.sendString("Not enough data"); 452 | } 453 | break; 454 | case EXTENDED_ANALOG: 455 | if (argc > 1) { 456 | int val = argv[1]; 457 | if (argc > 2) val |= (argv[2] << 7); 458 | if (argc > 3) val |= (argv[3] << 14); 459 | analogWriteCallback(argv[0], val); 460 | } 461 | break; 462 | case CAPABILITY_QUERY: 463 | BLEMini_write(START_SYSEX); 464 | BLEMini_write(CAPABILITY_RESPONSE); 465 | for (byte pin=0; pin < TOTAL_PINS; pin++) { 466 | if (IS_PIN_DIGITAL(pin)) { 467 | BLEMini_write((byte)INPUT); 468 | BLEMini_write(1); 469 | BLEMini_write((byte)OUTPUT); 470 | BLEMini_write(1); 471 | } 472 | if (IS_PIN_ANALOG(pin)) { 473 | BLEMini_write(ANALOG); 474 | BLEMini_write(10); 475 | } 476 | if (IS_PIN_PWM(pin)) { 477 | BLEMini_write(PWM); 478 | BLEMini_write(8); 479 | } 480 | if (IS_PIN_SERVO(pin)) { 481 | BLEMini_write(SERVO); 482 | BLEMini_write(14); 483 | } 484 | if (IS_PIN_I2C(pin)) { 485 | BLEMini_write(I2C); 486 | BLEMini_write(1); // to do: determine appropriate value 487 | } 488 | BLEMini_write(127); 489 | } 490 | BLEMini_write(END_SYSEX); 491 | break; 492 | case PIN_STATE_QUERY: 493 | if (argc > 0) { 494 | byte pin=argv[0]; 495 | BLEMini_write(START_SYSEX); 496 | BLEMini_write(PIN_STATE_RESPONSE); 497 | BLEMini_write(pin); 498 | if (pin < TOTAL_PINS) { 499 | BLEMini_write((byte)pinConfig[pin]); 500 | BLEMini_write((byte)pinState[pin] & 0x7F); 501 | if (pinState[pin] & 0xFF80) BLEMini_write((byte)(pinState[pin] >> 7) & 0x7F); 502 | if (pinState[pin] & 0xC000) BLEMini_write((byte)(pinState[pin] >> 14) & 0x7F); 503 | } 504 | BLEMini_write(END_SYSEX); 505 | } 506 | break; 507 | case ANALOG_MAPPING_QUERY: 508 | BLEMini_write(START_SYSEX); 509 | BLEMini_write(ANALOG_MAPPING_RESPONSE); 510 | for (byte pin=0; pin < TOTAL_PINS; pin++) { 511 | BLEMini_write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127); 512 | } 513 | BLEMini_write(END_SYSEX); 514 | break; 515 | } 516 | } 517 | 518 | void enableI2CPins() 519 | { 520 | byte i; 521 | // is there a faster way to do this? would probaby require importing 522 | // Arduino.h to get SCL and SDA pins 523 | for (i=0; i < TOTAL_PINS; i++) { 524 | if(IS_PIN_I2C(i)) { 525 | // mark pins as i2c so they are ignore in non i2c data requests 526 | setPinModeCallback(i, I2C); 527 | } 528 | } 529 | 530 | isI2CEnabled = true; 531 | 532 | // is there enough time before the first I2C request to call this here? 533 | Wire.begin(); 534 | } 535 | 536 | /* disable the i2c pins so they can be used for other functions */ 537 | void disableI2CPins() { 538 | isI2CEnabled = false; 539 | // disable read continuous mode for all devices 540 | queryIndex = -1; 541 | // uncomment the following if or when the end() method is added to Wire library 542 | // Wire.end(); 543 | } 544 | 545 | /*============================================================================== 546 | * SETUP() 547 | *============================================================================*/ 548 | 549 | void systemResetCallback() 550 | { 551 | // initialize a defalt state 552 | // TODO: option to load config from EEPROM instead of default 553 | if (isI2CEnabled) { 554 | disableI2CPins(); 555 | } 556 | for (byte i=0; i < TOTAL_PORTS; i++) { 557 | reportPINs[i] = false; // by default, reporting off 558 | portConfigInputs[i] = 0; // until activated 559 | previousPINs[i] = 0; 560 | } 561 | // pins with analog capability default to analog input 562 | // otherwise, pins default to digital output 563 | for (byte i=0; i < TOTAL_PINS; i++) { 564 | 565 | // skip pin 8, 9 for BLE Shield 566 | if ((i == 8) || (i == 9)) 567 | continue; 568 | 569 | // skip SPI pins 570 | if ( (i==MOSI) || (i==MISO) || (i==SCK) || (i==SS) ) 571 | continue; 572 | 573 | // Default all to digital pins 574 | // if (IS_PIN_ANALOG(i)) { 575 | // turns off pullup, configures everything 576 | // setPinModeCallback(i, ANALOG); 577 | // } else { 578 | // sets the output to 0, configures portConfigInputs 579 | setPinModeCallback(i, OUTPUT); 580 | // } 581 | } 582 | // by default, do not report any analog inputs 583 | analogInputsToReport = 0; 584 | 585 | /* send digital inputs to set the initial state on the host computer, 586 | * since once in the loop(), this firmware will only send on change */ 587 | /* 588 | TODO: this can never execute, since no pins default to digital input 589 | but it will be needed when/if we support EEPROM stored config 590 | for (byte i=0; i < TOTAL_PORTS; i++) { 591 | outputPort(i, readPort(i, portConfigInputs[i]), true); 592 | } 593 | */ 594 | } 595 | 596 | void setup() 597 | { 598 | // BleFirmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION); 599 | 600 | BleFirmata.attach(ANALOG_MESSAGE, analogWriteCallback); 601 | BleFirmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); 602 | BleFirmata.attach(REPORT_ANALOG, reportAnalogCallback); 603 | BleFirmata.attach(REPORT_DIGITAL, reportDigitalCallback); 604 | BleFirmata.attach(SET_PIN_MODE, setPinModeCallback); 605 | BleFirmata.attach(START_SYSEX, sysexCallback); 606 | BleFirmata.attach(SYSTEM_RESET, systemResetCallback); 607 | 608 | // BleFirmata.begin(57600); 609 | systemResetCallback(); // reset to default config 610 | 611 | BLEMini_begin(57600); 612 | } 613 | 614 | /*============================================================================== 615 | * LOOP() 616 | *============================================================================*/ 617 | void loop() 618 | { 619 | byte pin, analogPin; 620 | 621 | /* DIGITALREAD - as fast as possible, check for changes and output them to the 622 | * FTDI buffer using Serial.print() */ 623 | checkDigitalInputs(); 624 | 625 | /* SERIALREAD - processing incoming messagse as soon as possible, while still 626 | * checking digital inputs. */ 627 | while(BleFirmata.available()) 628 | BleFirmata.processInput(); 629 | 630 | /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over 631 | * 60 bytes. use a timer to sending an event character every 4 ms to 632 | * trigger the buffer to dump. */ 633 | 634 | currentMillis = millis(); 635 | if (currentMillis - previousMillis > samplingInterval) { 636 | previousMillis += samplingInterval; 637 | /* ANALOGREAD - do all analogReads() at the configured sampling interval */ 638 | for(pin=0; pin -1) { 651 | for (byte i = 0; i < queryIndex + 1; i++) { 652 | readAndReportData(query[i].addr, query[i].reg, query[i].bytes); 653 | } 654 | } 655 | } 656 | } 657 | 658 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/examples/BLEFirmataSketch/Boards.h: -------------------------------------------------------------------------------- 1 | /* Boards.h - Hardware Abstraction Layer for Firmata library */ 2 | 3 | #ifndef Firmata_Boards_h 4 | #define Firmata_Boards_h 5 | 6 | #include 7 | 8 | #if defined(ARDUINO) && ARDUINO >= 100 9 | #include "Arduino.h" // for digitalRead, digitalWrite, etc 10 | #else 11 | #include "WProgram.h" 12 | #endif 13 | 14 | // Normally Servo.h must be included before Firmata.h (which then includes 15 | // this file). If Servo.h wasn't included, this allows the code to still 16 | // compile, but without support for any Servos. Hopefully that's what the 17 | // user intended by not including Servo.h 18 | #ifndef MAX_SERVOS 19 | #define MAX_SERVOS 0 20 | #endif 21 | 22 | /* 23 | Firmata Hardware Abstraction Layer 24 | 25 | Firmata is built on top of the hardware abstraction functions of Arduino, 26 | specifically digitalWrite, digitalRead, analogWrite, analogRead, and 27 | pinMode. While these functions offer simple integer pin numbers, Firmata 28 | needs more information than is provided by Arduino. This file provides 29 | all other hardware specific details. To make Firmata support a new board, 30 | only this file should require editing. 31 | 32 | The key concept is every "pin" implemented by Firmata may be mapped to 33 | any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is 34 | best, but such mapping should not be assumed. This hardware abstraction 35 | layer allows Firmata to implement any number of pins which map onto the 36 | Arduino implemented pins in almost any arbitrary way. 37 | 38 | 39 | General Constants: 40 | 41 | These constants provide basic information Firmata requires. 42 | 43 | TOTAL_PINS: The total number of pins Firmata implemented by Firmata. 44 | Usually this will match the number of pins the Arduino functions 45 | implement, including any pins pins capable of analog or digital. 46 | However, Firmata may implement any number of pins. For example, 47 | on Arduino Mini with 8 analog inputs, 6 of these may be used 48 | for digital functions, and 2 are analog only. On such boards, 49 | Firmata can implement more pins than Arduino's pinMode() 50 | function, in order to accommodate those special pins. The 51 | Firmata protocol supports a maximum of 128 pins, so this 52 | constant must not exceed 128. 53 | 54 | TOTAL_ANALOG_PINS: The total number of analog input pins implemented. 55 | The Firmata protocol allows up to 16 analog inputs, accessed 56 | using offsets 0 to 15. Because Firmata presents the analog 57 | inputs using different offsets than the actual pin numbers 58 | (a legacy of Arduino's analogRead function, and the way the 59 | analog input capable pins are physically labeled on all 60 | Arduino boards), the total number of analog input signals 61 | must be specified. 16 is the maximum. 62 | 63 | VERSION_BLINK_PIN: When Firmata starts up, it will blink the version 64 | number. This constant is the Arduino pin number where a 65 | LED is connected. 66 | 67 | 68 | Pin Mapping Macros: 69 | 70 | These macros provide the mapping between pins as implemented by 71 | Firmata protocol and the actual pin numbers used by the Arduino 72 | functions. Even though such mappings are often simple, pin 73 | numbers received by Firmata protocol should always be used as 74 | input to these macros, and the result of the macro should be 75 | used with with any Arduino function. 76 | 77 | When Firmata is extended to support a new pin mode or feature, 78 | a pair of macros should be added and used for all hardware 79 | access. For simple 1:1 mapping, these macros add no actual 80 | overhead, yet their consistent use allows source code which 81 | uses them consistently to be easily adapted to all other boards 82 | with different requirements. 83 | 84 | IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero 85 | if a pin as implemented by Firmata corresponds to a pin 86 | that actually implements the named feature. 87 | 88 | PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as 89 | implemented by Firmata to the pin numbers needed as inputs 90 | to the Arduino functions. The corresponding IS_PIN macro 91 | should always be tested before using a PIN_TO macro, so 92 | these macros only need to handle valid Firmata pin 93 | numbers for the named feature. 94 | 95 | 96 | Port Access Inline Funtions: 97 | 98 | For efficiency, Firmata protocol provides access to digital 99 | input and output pins grouped by 8 bit ports. When these 100 | groups of 8 correspond to actual 8 bit ports as implemented 101 | by the hardware, these inline functions can provide high 102 | speed direct port access. Otherwise, a default implementation 103 | using 8 calls to digitalWrite or digitalRead is used. 104 | 105 | When porting Firmata to a new board, it is recommended to 106 | use the default functions first and focus only on the constants 107 | and macros above. When those are working, if optimized port 108 | access is desired, these inline functions may be extended. 109 | The recommended approach defines a symbol indicating which 110 | optimization to use, and then conditional complication is 111 | used within these functions. 112 | 113 | readPort(port, bitmask): Read an 8 bit port, returning the value. 114 | port: The port number, Firmata pins port*8 to port*8+7 115 | bitmask: The actual pins to read, indicated by 1 bits. 116 | 117 | writePort(port, value, bitmask): Write an 8 bit port. 118 | port: The port number, Firmata pins port*8 to port*8+7 119 | value: The 8 bit value to write 120 | bitmask: The actual pins to write, indicated by 1 bits. 121 | */ 122 | 123 | /*============================================================================== 124 | * Board Specific Configuration 125 | *============================================================================*/ 126 | 127 | #ifndef digitalPinHasPWM 128 | #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p) 129 | #endif 130 | 131 | // Arduino Duemilanove, Diecimila, and NG 132 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) 133 | #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6 134 | #define TOTAL_ANALOG_PINS 6 135 | #define TOTAL_PINS 20 // 14 digital + 6 analog 136 | #else 137 | #define TOTAL_ANALOG_PINS 8 138 | #define TOTAL_PINS 22 // 14 digital + 8 analog 139 | #endif 140 | #define VERSION_BLINK_PIN 13 141 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) 142 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS) 143 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 144 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) 145 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) 146 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 147 | #define PIN_TO_DIGITAL(p) (p) 148 | #define PIN_TO_ANALOG(p) ((p) - 14) 149 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 150 | #define PIN_TO_SERVO(p) ((p) - 2) 151 | #define ARDUINO_PINOUT_OPTIMIZE 1 152 | 153 | 154 | // Wiring (and board) 155 | #elif defined(WIRING) 156 | #define VERSION_BLINK_PIN WLED 157 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 158 | #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS)) 159 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 160 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 161 | #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL) 162 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 163 | #define PIN_TO_DIGITAL(p) (p) 164 | #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN) 165 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 166 | #define PIN_TO_SERVO(p) (p) 167 | 168 | 169 | // old Arduinos 170 | #elif defined(__AVR_ATmega8__) 171 | #define TOTAL_ANALOG_PINS 6 172 | #define TOTAL_PINS 20 // 14 digital + 6 analog 173 | #define VERSION_BLINK_PIN 13 174 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19) 175 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19) 176 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 177 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS) 178 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) 179 | #define PIN_TO_DIGITAL(p) (p) 180 | #define PIN_TO_ANALOG(p) ((p) - 14) 181 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 182 | #define PIN_TO_SERVO(p) ((p) - 2) 183 | #define ARDUINO_PINOUT_OPTIMIZE 1 184 | 185 | 186 | // Arduino Mega 187 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 188 | #define TOTAL_ANALOG_PINS 16 189 | #define TOTAL_PINS 70 // 54 digital + 16 analog 190 | #define VERSION_BLINK_PIN 13 191 | #define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 13) || ((p) >= 20 && (p) < TOTAL_PINS)) 192 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) 193 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 194 | #define IS_PIN_SERVO(p) ((p) >= 2 && ((p) <= 13 && (p) - 2 < MAX_SERVOS)) || ((p) >= 20 && (p) - 2 < MAX_SERVOS) 195 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) 196 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 197 | #define PIN_TO_DIGITAL(p) (p) 198 | #define PIN_TO_ANALOG(p) ((p) - 54) 199 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 200 | #define PIN_TO_SERVO(p) ((p) - 2) 201 | 202 | 203 | // Arduino DUE 204 | #elif defined(__SAM3X8E__) 205 | #define TOTAL_ANALOG_PINS 12 206 | #define TOTAL_PINS 66 // 54 digital + 12 analog 207 | #define VERSION_BLINK_PIN 13 208 | #define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 13) || ((p) >= 20 && (p) < TOTAL_PINS)) 209 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS) 210 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 211 | #define IS_PIN_SERVO(p) ((p) >= 2 && ((p) <= 13 && (p) - 2 < MAX_SERVOS)) || ((p) >= 20 && (p) - 2 < MAX_SERVOS) 212 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71 213 | #define PIN_TO_DIGITAL(p) (p) 214 | #define PIN_TO_ANALOG(p) ((p) - 54) 215 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 216 | #define PIN_TO_SERVO(p) ((p) - 2) 217 | 218 | 219 | // Teensy 1.0 220 | #elif defined(__AVR_AT90USB162__) 221 | #define TOTAL_ANALOG_PINS 0 222 | #define TOTAL_PINS 21 // 21 digital + no analog 223 | #define VERSION_BLINK_PIN 6 224 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 225 | #define IS_PIN_ANALOG(p) (0) 226 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 227 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 228 | #define IS_PIN_I2C(p) (0) 229 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 230 | #define PIN_TO_DIGITAL(p) (p) 231 | #define PIN_TO_ANALOG(p) (0) 232 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 233 | #define PIN_TO_SERVO(p) (p) 234 | 235 | 236 | // Teensy 2.0 237 | #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) 238 | #define TOTAL_ANALOG_PINS 12 239 | #define TOTAL_PINS 25 // 11 digital + 12 analog 240 | #define VERSION_BLINK_PIN 11 241 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 242 | #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22) 243 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 244 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 245 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6) 246 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 247 | #define PIN_TO_DIGITAL(p) (p) 248 | #define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11) 249 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 250 | #define PIN_TO_SERVO(p) (p) 251 | 252 | 253 | // Teensy 3.0 254 | #elif defined(__MK20DX128__) 255 | #define TOTAL_ANALOG_PINS 14 256 | #define TOTAL_PINS 38 // 24 digital + 10 analog-digital + 4 analog 257 | #define VERSION_BLINK_PIN 13 258 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) <= 34) 259 | #define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 23) || ((p) >= 34 && (p) <= 38)) 260 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 261 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 262 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19) 263 | #define PIN_TO_DIGITAL(p) (p) 264 | #define PIN_TO_ANALOG(p) (((p)<=23)?(p)-14:(p)-24) 265 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 266 | #define PIN_TO_SERVO(p) (p) 267 | 268 | 269 | // Teensy++ 1.0 and 2.0 270 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 271 | #define TOTAL_ANALOG_PINS 8 272 | #define TOTAL_PINS 46 // 38 digital + 8 analog 273 | #define VERSION_BLINK_PIN 6 274 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS) 275 | #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS) 276 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 277 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 278 | #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1) 279 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 280 | #define PIN_TO_DIGITAL(p) (p) 281 | #define PIN_TO_ANALOG(p) ((p) - 38) 282 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 283 | #define PIN_TO_SERVO(p) (p) 284 | 285 | 286 | // Leonardo 287 | #elif defined(__AVR_ATmega32U4__) 288 | #define TOTAL_ANALOG_PINS 12 289 | #define TOTAL_PINS 30 // 14 digital + 12 analog + 4 SPI (D14-D17 on ISP header) 290 | #define VERSION_BLINK_PIN 13 291 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) 292 | #define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < TOTAL_PINS) 293 | #define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13) 294 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) < MAX_SERVOS) 295 | #define IS_PIN_I2C(p) ((p) == 2 || (p) == 3) 296 | #define IS_PIN_SPI(p) ((p) == SS || (p) == MOSI || (p) == MISO || (p) == SCK) 297 | #define PIN_TO_DIGITAL(p) (p) 298 | #define PIN_TO_ANALOG(p) (p) - 18 299 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 300 | #define PIN_TO_SERVO(p) (p) 301 | 302 | 303 | // Sanguino 304 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) 305 | #define TOTAL_ANALOG_PINS 8 306 | #define TOTAL_PINS 32 // 24 digital + 8 analog 307 | #define VERSION_BLINK_PIN 0 308 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) 309 | #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS) 310 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 311 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 312 | #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17) 313 | #define PIN_TO_DIGITAL(p) (p) 314 | #define PIN_TO_ANALOG(p) ((p) - 24) 315 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 316 | #define PIN_TO_SERVO(p) ((p) - 2) 317 | 318 | 319 | // Illuminato 320 | #elif defined(__AVR_ATmega645__) 321 | #define TOTAL_ANALOG_PINS 6 322 | #define TOTAL_PINS 42 // 36 digital + 6 analog 323 | #define VERSION_BLINK_PIN 13 324 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS) 325 | #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS) 326 | #define IS_PIN_PWM(p) digitalPinHasPWM(p) 327 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS) 328 | #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5) 329 | #define PIN_TO_DIGITAL(p) (p) 330 | #define PIN_TO_ANALOG(p) ((p) - 36) 331 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p) 332 | #define PIN_TO_SERVO(p) ((p) - 2) 333 | 334 | 335 | // anything else 336 | #else 337 | #error "Please edit Boards.h with a hardware abstraction for this board" 338 | #endif 339 | 340 | // as long this is not defined for all boards: 341 | #ifndef IS_PIN_SPI(p) 342 | #define IS_PIN_SPI(p) 0 343 | #endif 344 | 345 | /*============================================================================== 346 | * readPort() - Read an 8 bit port 347 | *============================================================================*/ 348 | 349 | static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused)); 350 | static inline unsigned char readPort(byte port, byte bitmask) 351 | { 352 | #if defined(ARDUINO_PINOUT_OPTIMIZE) 353 | if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1 354 | if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask; 355 | if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask; 356 | return 0; 357 | #else 358 | unsigned char out=0, pin=port*8; 359 | if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01; 360 | if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02; 361 | if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04; 362 | if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08; 363 | if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10; 364 | if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20; 365 | if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40; 366 | if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80; 367 | return out; 368 | #endif 369 | } 370 | 371 | /*============================================================================== 372 | * writePort() - Write an 8 bit port, only touch pins specified by a bitmask 373 | *============================================================================*/ 374 | 375 | static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused)); 376 | static inline unsigned char writePort(byte port, byte value, byte bitmask) 377 | { 378 | #if defined(ARDUINO_PINOUT_OPTIMIZE) 379 | if (port == 0) { 380 | bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins 381 | byte valD = value & bitmask; 382 | byte maskD = ~bitmask; 383 | cli(); 384 | PORTD = (PORTD & maskD) | valD; 385 | sei(); 386 | } else if (port == 1) { 387 | byte valB = (value & bitmask) & 0x3F; 388 | byte valC = (value & bitmask) >> 6; 389 | byte maskB = ~(bitmask & 0x3F); 390 | byte maskC = ~((bitmask & 0xC0) >> 6); 391 | cli(); 392 | PORTB = (PORTB & maskB) | valB; 393 | PORTC = (PORTC & maskC) | valC; 394 | sei(); 395 | } else if (port == 2) { 396 | bitmask = bitmask & 0x0F; 397 | byte valC = (value & bitmask) << 2; 398 | byte maskC = ~(bitmask << 2); 399 | cli(); 400 | PORTC = (PORTC & maskC) | valC; 401 | sei(); 402 | } 403 | #else 404 | byte pin=port*8; 405 | if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01)); 406 | if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02)); 407 | if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04)); 408 | if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08)); 409 | if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10)); 410 | if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20)); 411 | if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40)); 412 | if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80)); 413 | #endif 414 | } 415 | 416 | 417 | 418 | 419 | #ifndef TOTAL_PORTS 420 | #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8) 421 | #endif 422 | 423 | 424 | #endif /* Firmata_Boards_h */ 425 | 426 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/examples/Chat/Chat.ino: -------------------------------------------------------------------------------- 1 | /******************************************* 2 | * This example is for Arduino board listed below working with BLEMini,chating with BLE app in ipod etc. 3 | * BLEMini's TX map the RX below and its RX map the TX below 4 | * 5 | * Board RX TX 6 | * UNO PIN8 PIN9 (PINs can be changed in file "document/library/AltSoftSerial/config/known_boards.h") 7 | * MEGA2560 PIN19 PIN18 (actually use the Serial1) 8 | * Leonardo PIN0 PIN1 (actually use the Serial1) 9 | *******************************************/ 10 | #include 11 | #include 12 | 13 | // For UNO, AltSoftSerial library is required, please get it from: 14 | // http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html 15 | #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328P__) 16 | AltSoftSerial BLEMini; 17 | #else 18 | #define BLEMini Serial1 19 | #endif 20 | 21 | void setup() 22 | { 23 | BLEMini.begin(57600); 24 | Serial.begin(57600); 25 | } 26 | 27 | unsigned char buf[16] = {0}; 28 | unsigned char len = 0; 29 | 30 | void loop() 31 | { 32 | if ( BLEMini.available() ) 33 | { 34 | delay(5); 35 | 36 | while ( BLEMini.available() ) 37 | Serial.write( BLEMini.read() ); 38 | 39 | Serial.println(); 40 | } 41 | 42 | if ( Serial.available() ) 43 | { 44 | delay(5); 45 | 46 | while ( Serial.available() ) 47 | BLEMini.write( Serial.read() ); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Arduino/libraries/RBL_BLEMini/examples/SimpleControls/SimpleControls.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2012, 2013 RedBearLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #define DIGITAL_OUT_PIN 2 17 | #define DIGITAL_IN_PIN A4 18 | #define PWM_PIN 3 19 | #define SERVO_PIN 5 20 | #define ANALOG_IN_PIN A5 21 | 22 | Servo myservo; 23 | 24 | unsigned long currentMillis; // store the current value from millis() 25 | unsigned long previousMillis; // for comparison with currentMillis 26 | int samplingInterval = 250; // how often to run the main loop (in ms) 27 | 28 | void setup() 29 | { 30 | BLEMini_begin(57600); 31 | 32 | pinMode(DIGITAL_OUT_PIN, OUTPUT); 33 | pinMode(DIGITAL_IN_PIN, INPUT); 34 | 35 | // Default to internally pull high, change it if you need 36 | digitalWrite(DIGITAL_IN_PIN, HIGH); 37 | //digitalWrite(DIGITAL_IN_PIN, LOW); 38 | 39 | myservo.attach(SERVO_PIN); 40 | } 41 | 42 | void loop() 43 | { 44 | static boolean analog_enabled = false; 45 | static byte old_state = LOW; 46 | 47 | // If data is ready 48 | while ( BLEMini_available() == 3 ) 49 | { 50 | // read out command and data 51 | byte data0 = BLEMini_read(); 52 | byte data1 = BLEMini_read(); 53 | byte data2 = BLEMini_read(); 54 | 55 | if (data0 == 0x01) // Command is to control digital out pin 56 | { 57 | if (data1 == 0x01) 58 | digitalWrite(DIGITAL_OUT_PIN, HIGH); 59 | else 60 | digitalWrite(DIGITAL_OUT_PIN, LOW); 61 | } 62 | else if (data0 == 0xA0) // Command is to enable analog in reading 63 | { 64 | if (data1 == 0x01) 65 | analog_enabled = true; 66 | else 67 | analog_enabled = false; 68 | } 69 | else if (data0 == 0x02) // Command is to control PWM pin 70 | { 71 | analogWrite(PWM_PIN, data1); 72 | } 73 | else if (data0 == 0x03) // Command is to control Servo pin 74 | { 75 | myservo.write(data1); 76 | } 77 | else if (data0 == 0x04) // Command is to reset 78 | { 79 | analog_enabled = false; 80 | myservo.write(0); 81 | analogWrite(PWM_PIN, 0); 82 | digitalWrite(DIGITAL_OUT_PIN, LOW); 83 | } 84 | } 85 | 86 | if (analog_enabled) // if analog reading enabled 87 | { 88 | currentMillis = millis(); 89 | if (currentMillis - previousMillis > samplingInterval) 90 | { 91 | previousMillis += millis(); 92 | 93 | // Read and send out 94 | uint16_t value = analogRead(ANALOG_IN_PIN); 95 | BLEMini_write(0x0B); 96 | BLEMini_write(value >> 8); 97 | BLEMini_write(value); 98 | } 99 | } 100 | 101 | // If digital in changes, report the state 102 | if (digitalRead(DIGITAL_IN_PIN) != old_state) 103 | { 104 | old_state = digitalRead(DIGITAL_IN_PIN); 105 | 106 | if (digitalRead(DIGITAL_IN_PIN) == HIGH) 107 | { 108 | BLEMini_write(0x0A); 109 | BLEMini_write(0x01); 110 | BLEMini_write(0x00); 111 | } 112 | else 113 | { 114 | BLEMini_write(0x0A); 115 | BLEMini_write(0x00); 116 | BLEMini_write(0x00); 117 | } 118 | } 119 | 120 | delay(100); 121 | } 122 | 123 | -------------------------------------------------------------------------------- /Docs/01FirmwareUpdate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/01FirmwareUpdate.pdf -------------------------------------------------------------------------------- /Docs/02ExternalAntenna.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/02ExternalAntenna.pdf -------------------------------------------------------------------------------- /Docs/Coin-Cell/01.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/Coin-Cell/01.JPG -------------------------------------------------------------------------------- /Docs/Coin-Cell/02.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/Coin-Cell/02.JPG -------------------------------------------------------------------------------- /Docs/Coin-Cell/03.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/Coin-Cell/03.JPG -------------------------------------------------------------------------------- /Docs/Coin-Cell/04.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/Coin-Cell/04.JPG -------------------------------------------------------------------------------- /Docs/ExternalAntenna.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Docs/ExternalAntenna.jpg -------------------------------------------------------------------------------- /Drivers/ccxxxx_usb_cdc.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Drivers/ccxxxx_usb_cdc.cat -------------------------------------------------------------------------------- /Drivers/ccxxxx_usb_cdc.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Texas Instruments CCxxxx USB Serial Port Setup File 3 | ; 4 | ; Based on Windows USB CDC ACM Setup File 5 | ; Copyright (c) 2000 Microsoft Corporation 6 | ; Copyright (c) 2013 Texas Instruments Inc 7 | 8 | [Version] 9 | Signature="$Windows NT$" 10 | Class=Ports 11 | ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 12 | Provider=%PROVIDER% 13 | DriverVer=04/05/2013,1.2.0.0 14 | CatalogFile=ccxxxx_usb_cdc.cat 15 | 16 | [Manufacturer] 17 | %MFGNAME%=DeviceList,NTx86,NTamd64 18 | 19 | 20 | [DeviceList.NTx86] 21 | %DESC_SRFEB% = DriverInstall, USB\VID_0451&PID_16B6 22 | %DESC_CC2511% = DriverInstall, USB\VID_0451&PID_16A4 23 | %DESC_CC1111% = DriverInstall, USB\VID_0451&PID_16A6 24 | %DESC_CC2531% = DriverInstall, USB\VID_0451&PID_16A8 25 | %DESC_CC2540% = DriverInstall, USB\VID_0451&PID_16AA 26 | %DESC_CC2544% = DriverInstall, USB\VID_0451&PID_16C5 27 | %DESC_CC2538% = DriverInstall, USB\VID_0451&PID_16C8 28 | %DESC_CCXXXXBL% = DriverInstall, USB\VID_0451&PID_16C7 29 | %DESC_REMOTINP% = DriverInstall, USB\VID_0451&PID_16B1 30 | 31 | [DeviceList.NTamd64] 32 | %DESC_SRFEB% = DriverInstall, USB\VID_0451&PID_16B6 33 | %DESC_CC2511% = DriverInstall, USB\VID_0451&PID_16A4 34 | %DESC_CC1111% = DriverInstall, USB\VID_0451&PID_16A6 35 | %DESC_CC2531% = DriverInstall, USB\VID_0451&PID_16A8 36 | %DESC_CC2540% = DriverInstall, USB\VID_0451&PID_16AA 37 | %DESC_CC2544% = DriverInstall, USB\VID_0451&PID_16C5 38 | %DESC_CC2538% = DriverInstall, USB\VID_0451&PID_16C8 39 | %DESC_CCXXXXBL% = DriverInstall, USB\VID_0451&PID_16C7 40 | %DESC_REMOTINP% = DriverInstall, USB\VID_0451&PID_16B1 41 | 42 | 43 | ;------------------------------------------------------------------------------ 44 | ; Windows 32-bit sections 45 | ;------------------------------------------------------------------------------ 46 | 47 | [DriverInstall.NTx86] 48 | include=mdmcpq.inf 49 | CopyFiles=FakeModemCopyFileSection 50 | AddReg=DriverRegistryKeys 51 | 52 | [DriverInstall.NTx86.Services] 53 | AddService=usbser, 0x00000002, DriverService 54 | 55 | 56 | ;------------------------------------------------------------------------------ 57 | ; Windows 64-bit sections 58 | ;------------------------------------------------------------------------------ 59 | 60 | [DriverInstall.NTamd64] 61 | include=mdmcpq.inf 62 | CopyFiles=FakeModemCopyFileSection 63 | AddReg=DriverRegistryKeys 64 | 65 | [DriverInstall.NTamd64.Services] 66 | AddService=usbser, 0x00000002, DriverService 67 | 68 | 69 | ;------------------------------------------------------------------------------ 70 | ; 71 | ;------------------------------------------------------------------------------ 72 | 73 | [DriverRegistryKeys] 74 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 75 | 76 | [DriverService] 77 | DisplayName = %SERVICE% 78 | ServiceType = 1 79 | StartType = 3 80 | ErrorControl = 1 81 | ServiceBinary = %12%\usbser.sys 82 | 83 | 84 | ;------------------------------------------------------------------------------ 85 | ; String Definitions 86 | ;------------------------------------------------------------------------------ 87 | 88 | [Strings] 89 | PROVIDER = "Texas Instruments" 90 | MFGNAME = "Texas Instruments" 91 | SERVICE = "TI USB CDC Driver" 92 | DESC_SRFEB = "TI SmartRFEB USB CDC Serial Port" 93 | DESC_CC1111 = "TI CC1111 USB CDC Serial Port" 94 | DESC_CC2511 = "TI CC2511 USB CDC Serial Port" 95 | DESC_CC2531 = "TI CC2531 USB CDC Serial Port" 96 | DESC_CC2538 = "TI CC2538 USB CDC Serial Port" 97 | DESC_CC2540 = "TI CC2540 USB CDC Serial Port" 98 | DESC_CC2544 = "TI CC2544 USB CDC Serial Port" 99 | DESC_CCXXXXBL = "TI CCxxxx Generic USB CDC Boot Loader" 100 | DESC_REMOTINP = "RemoTI Network Processor" 101 | -------------------------------------------------------------------------------- /Firmware/BLE2UART/Biscuit-UART_20140409.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/BLE2UART/Biscuit-UART_20140409.bin -------------------------------------------------------------------------------- /Firmware/BLE2UART/Biscuit-USBCDC_20140409.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/BLE2UART/Biscuit-USBCDC_20140409.bin -------------------------------------------------------------------------------- /Firmware/BLERGB/Biscuit-RGB_20140310.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/BLERGB/Biscuit-RGB_20140310.bin -------------------------------------------------------------------------------- /Firmware/Bootloader/UBL-1.3.hex: -------------------------------------------------------------------------------- 1 | :020000040000FA 2 | :10000000020529020823FFFFFFFFFF02082BFFFF65 3 | :10001000FFFFFF020833FFFFFFFFFF02083BFFFF68 4 | :10002000FFFFFF020843FFFFFFFFFF02084BFFFF38 5 | :10003000FFFFFF020853FFFFFFFFFF02085BFFFF08 6 | :10004000FFFFFF020863FFFFFFFFFF02086BFFFFD8 7 | :10005000FFFFFF020873FFFFFFFFFF02087BFFFFA8 8 | :10006000FFFFFF020883FFFFFFFFFF02088BFFFF78 9 | :10007000FFFFFF020893FFFFFFFFFF02089BFFFF48 10 | :10008000FFFFFF0208A3FFFFFFFFFF0208ABB10362 11 | :10009000E303E303E303E303E703EB3C904D534443 12 | :1000A0004F53352E3000020401000210000000F80A 13 | :1000B0000100000000000400000004000000000037 14 | :1000C00029000000004E4F204E414D4520202020A9 15 | :1000D000464154313220202000035F005F00300091 16 | :1000E00058000000000000000000000000000000B8 17 | :1000F0000000000000000000000000000000000000 18 | :10010000000074F71202C543C707E59D5418641038 19 | :10011000704275080475090078081204F17C9D7D11 20 | :10012000147A9C7B06790112066274021204A7906D 21 | :10013000149DE0F8A3E0F9A3E0687003A3E0697000 22 | :100140001390149DE0F47003A3E0F46007E84960A5 23 | :1001500003120650781075B60FE5B4A2E750FAE521 24 | :10016000BBC3944A40F018E870EC75A80075B8005D 25 | :10017000759A0075C6809062707408F079017F02EC 26 | :10018000020371E4CFC0E0E4CEC0E0E4CDC0E0E41F 27 | :10019000CCC0E075F020C3E633F608E633F608E697 28 | :1001A00033F608E633F6181818EC33FCED33FDEEA1 29 | :1001B00033FEEF33FFC3EC9709ED9709EE9709EF94 30 | :1001C00097191919400FFFEC97FC09ED97FD09EEFF 31 | :1001D00097FE191906D5F0BEECF709EDF709EEF711 32 | :1001E00009EFF7191919D0E0FCD0E0FDD0E0FED0FE 33 | :1001F000E0FF222518C582C0E0E51934FFC583C0A1 34 | :10020000E0E518C3958224F810AF0885831985822C 35 | :10021000188008858319858218D2AFCEF0A3E52017 36 | :10022000F0A37808E608F0A3DEFAEFF0A3E5812456 37 | :10023000FAF8E608F0A3E608F0A3E608F0A3080839 38 | :10024000E608F0A3E608F0A315811581D0E0FED002 39 | :10025000E0F8158115811581E8C0E0EEC0E02212BA 40 | :100260000102B900030202AFE479217807B8000265 41 | :100270008004F709D8FCE4900300782A7901800211 42 | :10028000F0A3D8FCD9FA900329AA82AB8390008E00 43 | :10029000787579018015E493A3AC82AD838A828B53 44 | :1002A00083F0A3AA82AB838C828D83D8E9D9E775CA 45 | :1002B00082027583D674071204547582A77583056C 46 | :1002C00074001204542518C582C0E0E51934FFC536 47 | :1002D00083C0E0E518C3958224F910AF088583191F 48 | :1002E0008582188008858319858218D2AFCEF0A345 49 | :1002F000E520F0A37808E608F0A3DEFAEFF0A3E526 50 | :100300008124FBF8E608F0A3E608F0A30808E60855 51 | :10031000F0A3E608F0A315811581D0E0FED0E0F847 52 | :1003200015811581E8C0E0EEC0E0228519838518AB 53 | :1003300082E0A3FEE0A3F5207808E0A3F608DFFA48 54 | :10034000E0A3FFE0A3C0E0E0A3C0E0E0A3C0E0E0E2 55 | :10035000A3C0E0E0A3C0E010AF0885821885831930 56 | :100360008008858218858319D2AFD083D082020499 57 | :100370005A851983851882E0A3FEE0A3F52078084A 58 | :10038000E0A3F608DFFAE0A3FFE0A3C0E0E0A3C02B 59 | :10039000E0E0A3C0E0E0A3C0E010AF0885821885CC 60 | :1003A00083198008858218858319D2AFD083D082C3 61 | :1003B0002212010002000000205104A816090001C9 62 | :1003C00002030109022000010100800F090400005E 63 | :1003D00002080650000705840240000007050402D9 64 | :1003E000400000CC03102074038000CCC0E0EDC0BE 65 | :1003F000E0E518C39CCCAD1950011D10AF068C1858 66 | :100400008D1980068C188D19D2AF120414D0E0FD1E 67 | :10041000D0E0FC22CAC0E0E0A3C582CCC582C5837F 68 | :10042000CDC583F0A3C582CCC582C583CDC583DA93 69 | :10043000E6D0E0CA227009080808226016181818C9 70 | :10044000C6C333C608C633C608C633C608C633C6D5 71 | :10045000D5E0EA22C09FF59FE473D09F22D083D0DD 72 | :1004600082C09FE493C0E0740193C0E0740293F5EE 73 | :100470009F222518F58210AF08F518400215198043 74 | :1004800008F51840021519D2AF85198322BB010265 75 | :10049000E722C082C08389828A83BB0003E0800296 76 | :1004A000E493D083D08222C0D0251810AF08F5186D 77 | :1004B000500205198008F51850020519D2AFD0D0A6 78 | :1004C00022BB000EC082C0838A838982F0D083D091 79 | :1004D0008222BB0101F722251810AF08F51840024F 80 | :1004E00015198008F51840021519D2AF227403803F 81 | :1004F0000474028000C0E0F404120472D0E012051B 82 | :100500007822C3E096F008A3E096F008A3E096F006 83 | :1005100008A3E096F022700422600D18C6C333C60B 84 | :1005200008C633C6D5E0F4182275D00075813F7532 85 | :100530001800751903759F0002025FC3E09608A3B7 86 | :10054000E09608A3E09608A3E09622600C08C6C3D4 87 | :1005500013C618C613C6D5E0F422E0F608A3E0F6E9 88 | :1005600008A3E0F608A3E0F622E6F008A3E6F00808 89 | :10057000A3E6F008A3E6F022CAC0E0E6F0A308DA9A 90 | :10058000FAD0E0FA22E0FAA3E0FBA3E0FCA3E0FD4E 91 | :1005900022EAF0A3EBF0A3ECF0A3EDF0222518F58E 92 | :1005A00082E43519F5832200000080FBE473120415 93 | :1005B0005DAAE30712045D48E40712045DDCE4076A 94 | :1005C00012045DF6E40712045DECE50712045D44D5 95 | :1005D000E80712045DE7E90712045DAEEA071204BA 96 | :1005E0005DAAEC0712045D91ED0712045DFEED07B4 97 | :1005F00012045D32EE0712045DA9EE0712045DBC21 98 | :10060000F00712045DEBF10712045DEDF10712042F 99 | :100610005D2AF20712045D2CF20712045D2EF20728 100 | :1006200012045D3FF20712045D41F20712045D44BB 101 | :10063000F20712045D24D10712045D77D10712047A 102 | :100640005D7CD10712045D43D20712045D5AD307C3 103 | :1006500012045DB3D40712045DC0D40712045D0F09 104 | :10066000D50712045D19D60712045D9CD607120443 105 | :100670005D0BD70712045D86D70712045DA5D70767 106 | :1006800012045DEAD70712045D20D80712045DC486 107 | :10069000D80712045DFCD80712045D1BD9071204A9 108 | :1006A0005D4BDB0712045D80DB0712045DAADB07EC 109 | :1006B00012045DE5DB0712045DCDDC0712045DB7B3 110 | :1006C000DD0712045DC9DD0712045DDBDD071204DE 111 | :1006D0005D21DE0712045DB6DF0712045D16E10737 112 | :1006E00012045D4EE10712045DF8E10712045D5546 113 | :1006F000E20712045DCBE20712045D09E30712046E 114 | :100700005D10070012045D66070012045DAC07006F 115 | :1007100074F71201F3740912059DE0F8A3E0801547 116 | :10072000A3AA82AB838C828D83A3AC82AD83E824A1 117 | :10073000FF18E934FFF9E84960238A828B83E0FEE1 118 | :100740008C828D83E06E8A828B8360D4E0F88C8209 119 | :100750008D83E0FAE8C39AFA95E0FB80047A007B87 120 | :10076000007F0102032B74F61201F3740A12059D37 121 | :10077000E0FEA3E0FFEAF8EBF980188C828D83E0BD 122 | :1007800088828983F0A3A882A9838C828D83A3ACFD 123 | :1007900082AD838E088F09E50824FF1EE50934FF2A 124 | :1007A000FFE508450970D47F0202032B74F712019C 125 | :1007B000F3740912059DE0F8A3E0F98A828B838027 126 | :1007C00003ECF0A3E8FEE9FFEE24FF18EF34FFF995 127 | :1007D000EE4F70ED7F0102032BFFFFFFFFFFFFFFD6 128 | :1007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 129 | :1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 130 | :020000040003F7 131 | :10D00000240342004C00450020004D0049004E0022 132 | :10D010004900200055005300420020004D005300FD 133 | :10D0200044002000240352006500640020004200F8 134 | :10D0300065006100720020004C0061006200200069 135 | :10D040002000200020002000008002021F000000BD 136 | :10D0500047656E657269632055534220466C617363 137 | :10D0600068204469736B2020302E3030444546419F 138 | :10D07000554C5420434647200015095A473F473F27 139 | :10D0800000008656473F020064000000FFFFFFFFDC 140 | :10D09000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 141 | :10D0A000FFFFFFFFFFFFFFFFFFFFFFFF000000008C 142 | :10D0B0000000000000000000000000000000000070 143 | :10D0C000000000000000000000000000303132339A 144 | :10D0D000343536373839414243444546000000086C 145 | :10D0E0000000000002000200FFFFFFFFFFFFFFFF44 146 | :10D0F000000000000000020003000000000000002B 147 | :10D1000043464700FFFFFFFF00000000040309043F 148 | :10D11000FFFFFFFF55534253555342437D0000002C 149 | :10D120000000017774F61201F375080475090078A0 150 | :10D13000081204F17C9D7D147A9C7B06790112060D 151 | :10D140006274021204A790149D12D761A3E8F0A3A1 152 | :10D15000E9F090149D74FFF0A3F0750801780812AF 153 | :10D1600004F17C9D7D147AA77B0312066874021279 154 | :10D1700004A7790102D706790102045A74F6120154 155 | :10D18000F374FC1204D7EAFEEBFF901500E0607F19 156 | :10D1900075082075090078081204F1EE2408FCEFE8 157 | :10D1A0003400FD7AA57B141206FE74021204A78BCC 158 | :10D1B00009EA450960599014FDE0F87901701112EF 159 | :10D1C0000656C2AF75C9AB75C95B80FEE9C333F9BA 160 | :10D1D000E95860F8E069F090D104C0828518828532 161 | :10D1E0001983AC82AD837583D1D082740412041488 162 | :10D1F00012D49A1204F1740212059DAC82AD837AA6 163 | :10D20000BF7B0312066874021204A77900802C9079 164 | :10D210001500E4F0750858F50978081204F1EE24B9 165 | :10D2200004FCEF3400FD7AA17B141207047402128F 166 | :10D2300004A790149FE4F0A3F0790174041204A7EA 167 | :10D2400002D70674F41201F374FC1204D78007901D 168 | :10D25000149FE4F0A3F01205B4E9640190149D70EA 169 | :10D260000302D33212D4AC7003A3E06970E89014C7 170 | :10D270009DE0F47003A3E0F460DCE84960D890140A 171 | :10D28000A312E14860D09014F5E0A2E0403DA2E195 172 | :10D290005004D2F08002C2F0A2F0E433FA75080123 173 | :10D2A00075090090159DE07808120516901595E017 174 | :10D2B000F8A3E0F5838882E055086004D2F080028C 175 | :10D2C000C2F0EAA2E020F001B34084E5958518821F 176 | :10D2D000851983F0659570F3E596C0E07401120539 177 | :10D2E0009DD0E0F0E597C0E0740212059DD0E0F01B 178 | :10D2F000740312059DE4F0901589780812055A858B 179 | :10D3000018828519837808120502740312059DE4BA 180 | :10D31000F0901591C08285188285198378081205CE 181 | :10D320005A758315D082780812053B400302D25605 182 | :10D33000801A12D4AC7003A3E069701690149DE0BB 183 | :10D34000F47003A3E0F4600AE84960061205BA121B 184 | :10D35000065074041204A702D81B74F01201F3746F 185 | :10D36000FC1204D775086475090078081204F17C72 186 | :10D370009D7D147A9C7B0679011206627402120468 187 | :10D38000A775082078081204F17C8C7DD07AA57BE3 188 | :10D39000141206FE74021204A78B09EA45097005EF 189 | :10D3A000901500E4F090149D12D4AC7003A3E069D2 190 | :10D3B000600302D47790149DE0F47003A3E0F4704E 191 | :10D3C0000302D477E849700302D4779014F9E0F8A7 192 | :10D3D000604E79018004E9C333F9E95860F8E069E7 193 | :10D3E000F0700990149FE4F0A302D47690D110C09D 194 | :10D3F00082851882851983AC82AD837583D1D082F2 195 | :10D40000740412041412D49A1204F1740212059DC9 196 | :10D41000AC82AD837ABE7B0312066874021204A745 197 | :10D420009014F5E0A2E0400612065CE97049901401 198 | :10D43000A312D6F9E508450970051206508038E4B4 199 | :10D44000F50AF50B740C780812043590D11C780C91 200 | :10D4500012055A7808790C120183901591780812F8 201 | :10D460000569E595901589F0659570F6E596A3F048 202 | :10D47000E597A3F0A3E4F0781075B60FE5B4A2E742 203 | :10D4800050FAE5BBC3944E40F018E870EC1205AEBC 204 | :10D4900074041204A77F0802032B85188285198360 205 | :10D4A000E069F075080175090078082212D765A3B4 206 | :10D4B000E06822020820C2AF75C9AB75C95B80FE67 207 | :10D4C000C082C0837C02E9702974075CF87401B8DB 208 | :10D4D00000028004C333D8FCC0E0EC131313541FC4 209 | :10D4E000FA74C52AF582741412DCC8D0E0F8E0584A 210 | :10D4F000600EECC333906272F0906270E0D2E0F0A4 211 | :10D500000CECC3947840BF906272740202D7967498 212 | :10D51000F61201F39014F6E0F8131313541FF97484 213 | :10D520000758FCE970047AF3800B74016970047A7F 214 | :10D53000F480027AF57B70ECF87401B80002800484 215 | :10D54000C333D8FCFDF4FE8A828B83E05EF0E97081 216 | :10D55000047AFD800B74016970047AFE80027AFF00 217 | :10D560008A82E05EF0E970047A8F800B7401697042 218 | :10D57000047AF680027AF79014F5E0A2E25025755D 219 | :10D5800008017509007405297808120516A808E035 220 | :10D59000A2E3E85005F452F7800242F78A828B83B7 221 | :10D5A000E05E80068A828B83E04DF0EC90159DF062 222 | :10D5B000E970079015957480800E74016990159537 223 | :10D5C00070047490800274A0F0A37470F09014F54D 224 | :10D5D000E0C313F8901595E0FAA3E0F5838A82E0A2 225 | :10D5E0005D6004D2F08002C2F0E8A2E020F001B356 226 | :10D5F000500B90149FE4F0A3F079018002790002AF 227 | :10D60000D7067415F5D575D48112064A120644C2A0 228 | :10D61000AF75C9AB75C95B80FE74F41201F389085C 229 | :10D62000740C12059DE0FEA3E0FF740F5508F50A87 230 | :10D63000750B00740B780A120516EA2400F8EB3417 231 | :10D6400080F9E82400E9350BF9E5C7F509A2AFE454 232 | :10D6500033F50AC2AFE508C4540FFAE5C754F84AD7 233 | :10D66000F5C7801C88828983E08C828D83F0888254 234 | :10D670008983A3A882A9838C828D83A3AC82AD8386 235 | :10D68000EEFAEFFBEA24FF1EEB34FFFFEA4B70D407 236 | :10D690008509C7E50AA2E092AF02D81B74F6120111 237 | :10D6A000F3740A12059D12D6F9ED901581F0ECA3E2 238 | :10D6B000F0A37462F0A37473F0A3E0541FF0E508C4 239 | :10D6C000333354FCA3F07406780812054BE5089038 240 | :10D6D0001585F09015877412F0A37442F075D1FE91 241 | :10D6E00075D601EA906271F0EBA3F0906270E0D21F 242 | :10D6F000E1F0E0A2E740FB800DE0F508A3E0F509CA 243 | :10D7000022758B00C2E87F0202032BC082C083E92E 244 | :10D71000FCEAFD7A007B00800818900305E012D730 245 | :10D720006B90030412D76190032BE0687003A3E0B1 246 | :10D73000696029900304E0240108A3E03400F9881B 247 | :10D74000828983E4936C700C90030412DB451812F9 248 | :10D75000D76B8008E4936D70C0ED60BD804090038E 249 | :10D760001D12D76522E0F8A3E0F922F5838882E450 250 | :10D7700093F8900304E028F8A3E03400F990030440 251 | :10D78000E8F0A3E9F022C082C08312D7DB7A0079E7 252 | :10D790000112066E8008F0906270E0D2E0F0D08353 253 | :10D7A000D08202045A74F61201F3E9FEEAFF12D79E 254 | :10D7B000DB7A00790212066EEA4B601CEE60108A7A 255 | :10D7C000828B83A3A3A3A3A3E4936E70E48009EFE9 256 | :10D7D000F874FF281F0470D902D70690032912D7C6 257 | :10D7E00065900304E8F0A3E9F02274F41201F3EA6F 258 | :10D7F000FF8B087A0012067A7A02790412066EEA22 259 | :10D800004B60188A828B83A3A3E4936F70EA8A82A9 260 | :10D810008B83A3A3A3E493650870DD7F0402032B2D 261 | :10D8200074F61201F374F81204D7E97A007B0060F1 262 | :10D830000C14600F14601214601502D8BF7A0C7BB0 263 | :10D84000D1807C7A247BD080767A007BD0807090E7 264 | :10D850000373E07066851882851983AC82AD837589 265 | :10D8600083D07582E874081204147C28FD8D088525 266 | :10D870001882851983E5822508F582E58312DCC3C9 267 | :10D88000FF8C0874732508F874033400F9EF12DC78 268 | :10D89000B988828983F0EFC412DCB9C0E0E824FEC5 269 | :10D8A000F582E934FFF583D0E0F00D74FC2CFCED3B 270 | :10D8B000C3940840B8900373742AF07A737B03749E 271 | :10D8C0000802D23DC082C0837A00790112067A8AAA 272 | :10D8D000828B83A3A3A3A3A3A3A3E493A2E69003B1 273 | :10D8E00019500474018001E4F0900318E4F0906290 274 | :10D8F0000F7403F0E0A2E750FB02D79EC082C08302 275 | :10D900009003067402F0A3E4F090030DF079031283 276 | :10D91000069E75210075220002D79E74F51201F350 277 | :10D9200090620EE0FEE4F0906211E0F50AA2E4508D 278 | :10D930001D7480F090030D7407F0E5214522600905 279 | :10D940008521828522831205AC90030DE4F0E50A5F 280 | :10D95000A2E2500B906211E4F090030DF0807390FE 281 | :10D96000030DE0F87402687052906216E0FF9003B5 282 | :10D970001A1203E7EFF97A207B621206A4740312ED 283 | :10D9800004A78F0890031D12DB1C12DB2712E1484D 284 | :10D990006004744080027448906211F0E849701489 285 | :10D9A000E521452260098521828522831205AC90FC 286 | :10D9B000030DE4F0EE90620E02DBA47406687009B9 287 | :10D9C0008521828522831205AC90030DE06003025D 288 | :10D9D000DAB8E50AA2E050DC75081F750903750A7C 289 | :10D9E0000078081204ED79087A207B621206A4748C 290 | :10D9F000031204A775210075220090031FE054E074 291 | :10DA0000601C24E0700302DA9224E0606F24C0609E 292 | :10DA10004524E0700302DA9D24E0606B8030A3E0CF 293 | :10DA200014601C24FE601324FE600A24FC6015248C 294 | :10DA3000FE601680191206C8806C1206C28067123A 295 | :10DA400006BC80621206E0805D1206EC80589003EE 296 | :10DA50000D7404F08058A3E0600E24FA600F24FED9 297 | :10DA6000601024FE601180E61206B080391206CEE6 298 | :10DA700080341206DA802F1206E6802A75210E7590 299 | :10DA8000220612060E801F75211475220612061436 300 | :10DA9000801475210275220612060280097521087C 301 | :10DAA00075220612060890030DE064047004746089 302 | :10DAB00080027440906211F090030DE0F8740168E8 303 | :10DAC0007046750A0212D75EC3E89420E9940050AC 304 | :10DAD00007E8FF750A0A80027F2090031A1203E705 305 | :10DAE000EFF97A207B621206AA74031204A78F084A 306 | :10DAF00012DB2712DB1CE50A906211F0EFC39420C1 307 | :10DB0000400302D9B402D9A0740568600302D9B4F5 308 | :10DB10008521828522831205AC02D9B4C3E0950821 309 | :10DB2000F0A3E09400F02290031AE0F9A312DB4581 310 | :10DB3000E92508F9EA3400FA90031AE9F0A3EAF0BB 311 | :10DB4000A3EBF0A322E0FAA3E0FB2274F61201F3A8 312 | :10DB500078008808740E2508F582740312DB75407E 313 | :10DB6000F17800880874132508F582740312DB75B8 314 | :10DB700040F102D70612DCC8E9F008E8C394052298 315 | :10DB800074F51201F3EAFCEBFDE9F8740B12059D44 316 | :10DB900012DBD9600D8C828D83E01204C112DBCEC2 317 | :10DBA00070F38001F07F0302032B74F51201F3EA96 318 | :10DBB000FCEBFDE9F8740B12059D12DBD9600D1228 319 | :10DBC000048D8C828D83F012DBCE70F380D7E92434 320 | :10DBD0000109EA3400FA18E82212D6F9A3E0A908EC 321 | :10DBE000AA09FBE82274F61201F312E1457011A3B1 322 | :10DBF000E0F8A3E0700AA3E064027002A3E060080A 323 | :10DC000090030D740402DCB590031FE024806008CB 324 | :10DC100014602A14603780E8E870E5900319E0602A 325 | :10DC200004780180027800900327E8F0A3E4F090E4 326 | :10DC30000318E06065900327E044028059900306D2 327 | :10DC4000E0640470BB900327E4F0A3804CE8547FA9 328 | :10DC5000F508900306E0640470A6E508C394065036 329 | :10DC60009F74062508F582740312DCC8E8548060AE 330 | :10DC700010A3A3A3A3A3A3A3E0640370137801805C 331 | :10DC800011E582240CF582E58312DCC3640360EDA8 332 | :10DC90007800900327E8F0A3E4F090030DE064041B 333 | :10DCA000601490031A7427F0A37403F0A3E4F0A3A4 334 | :10DCB000740212E24CF002D706540FFA74CC2AF523 335 | :10DCC0008274D012DCC8E0223400F5832274F6128C 336 | :10DCD00001F3E9FE90032512E1487010900306E07D 337 | :10DCE0006404601090032312E148600890030D74EF 338 | :10DCF0000402DDB190031FE0541F600814600D148E 339 | :10DD0000602480E8900321E064016005790002DD71 340 | :10DD1000B4EE900318F060047905800279067A0069 341 | :10DD200012062602DDB2900323E0547FFA9003210D 342 | :10DD3000E070D9EAC3940650B3EA90620EF08A0804 343 | :10DD400074062508F874033400F9900323E0548026 344 | :10DD5000602CEE6004741080027440906211F0EE4A 345 | :10DD6000600474038001E488828983A3A3A3A3A32E 346 | :10DD7000A3A3F0EE6004790880307907802CEE6070 347 | :10DD800004742080027480906214F0EE60047403C6 348 | :10DD90008001E4C0E0E8240CF582E912DCC8D0E0A0 349 | :10DDA000F0EE6004790A8002790912062690620E6C 350 | :10DDB000E4F0790102D706C082C08379001206B66A 351 | :10DDC000E9700312061A02D79EC082C0837901123D 352 | :10DDD00006B6E9700312062002D79EC082C0839067 353 | :10DDE000032312E1487015A312E148700F9003213C 354 | :10DDF00012DFB15480FAE9FBEA4B600790030D741F 355 | :10DE000004801AE8906200F09003066009E0640262 356 | :10DE1000700C74038007E0640370037402F002D78F 357 | :10DE20009E74F21201F3900321E0FAA3E01460085B 358 | :10DE3000146019146047805C12067412DF8EA37B95 359 | :10DE40008012048DA3F0A3E4F002DF4F79001206E4 360 | :10DE50007A12DF8E7B80E924020909EA3400FA1283 361 | :10DE6000048DFC1919E0FAA3E92403090909EA342D 362 | :10DE700000FA12048DF9ECA3F0A3E980CBEAF912C1 363 | :10DE8000068690031AEAF0A3EBF0A3E412DF9DA349 364 | :10DE90007B0080AD90031AE4F0A3F0A3F0F50B90A3 365 | :10DEA000032D12DB4502DF2A75090074037808127E 366 | :10DEB0000516EA2508F8EB3509F990032112DFA7CA 367 | :10DEC000E493C0E0EFFCD0E06C705DA3E4936E706F 368 | :10DED0005790032312DFA7A3A3E493C0E0EFFCD085 369 | :10DEE000E06C704488828983A3A3A3E4936E7038A6 370 | :10DEF00088828983A3A3A3A3E493F508740193F50F 371 | :10DF00000990031AE508F0A3E509F0A37480F088EE 372 | :10DF1000828983A3A3A3A3A3A3E493F8740193F931 373 | :10DF200090031DE8F0A3E9F0050B850B0890032F83 374 | :10DF300012DFB1C39AF50CE99BF50D7403780C124E 375 | :10DF4000054BC3E508950CE4950D500302DEA8903F 376 | :10DF5000031AE0FCA3E0FDA3E0FEEC4D4E90030DA0 377 | :10DF6000700474048022E06404601E90032512DBB8 378 | :10DF70004512D75EC3EA98EB99500890031DEAF06A 379 | :10DF8000A3EBF090030D7401F07F0602032B9003C6 380 | :10DF90001AEAF0A3EBF0A3748012DF9D22F0900345 381 | :10DFA0001AE0F9A3E0FA22E0FEA3E0FF8882898369 382 | :10DFB0002212D765E82274ED1201F3EA2404F50871 383 | :10DFC000EB3400F509850882F583E493602590031E 384 | :10DFD0003112DFB1FEE98007EE2404FEEF3400FFCA 385 | :10DFE0008E828F83E493F8740193F9EA687002EBF0 386 | :10DFF0006970E5750C00803F9062147490F07410A5 387 | :10E0000012E10A7003750D408E828F83A3A3A3E4EF 388 | :10E010009355106006E50DD2E0F50DE50D90621503 389 | :10E02000F0EA906213F0EC240CF582ED12DCC8E407 390 | :10E03000F090620EF0050C850882850983E493F860 391 | :10E04000E50CC398400302E1057A00790512066EDB 392 | :10E050008A0E8B0FEA450F60DCEA2402F8EB3400ED 393 | :10E06000F9880A890B8882F583E493540FF512909E 394 | :10E07000620EF0750D008A828B83A3A3A3A3E493A1 395 | :10E080002407F510A3E4933400F5117403781012FB 396 | :10E09000054BAA1085121074062510F8740334007D 397 | :10E0A000F9E8FCE9FD751001751100E51278101210 398 | :10E0B0000516E50E2403F8EB3400F9850A82850B7A 399 | :10E0C00083E493A2E7400302DFF89062117448F002 400 | :10E0D000740812E10A7003750D408E828F83A3A32A 401 | :10E0E000E49355106006E50DD2E0F50DE50D906264 402 | :10E0F00012F0EA906210F08C828D83A3A3A3A3A3F5 403 | :10E10000A3A302E02F7F0B02032BF088828983E414 404 | :10E11000935403640122C082C08312E1457010A3AE 405 | :10E1200012E148700AA3E064017002A3E060079066 406 | :10E13000030D7404800C90031A7407F0A374031287 407 | :10E14000E24202D79D90032112D765E8492274F478 408 | :10E150001201F3900306E06402601490032312E1BD 409 | :10E1600048700CA312E1487006900322E06008900A 410 | :10E17000030D7404F0807E7A007901120626900364 411 | :10E1800021E0FE605B7A00F912067A8A088B09EAC0 412 | :10E19000450960449003067404F0EEA3F07E008508 413 | :10E1A0000882850983A3A3A3A3E493F8EEC3985040 414 | :10E1B0003D8E0A7408250AF582740312DCC8E4F067 415 | :10E1C0007A00790412066E8A828B83A3A3A3E49358 416 | :10E1D00070EE1206D40E80C790030D7404F0800E0A 417 | :10E1E000900307F09003067403F0F912069E7A007C 418 | :10E1F000790212062602D81B74F51201F390030669 419 | :10E20000E06404701990031FE06481701112E1450D 420 | :10E21000700C900325E064017002A3E06007900396 421 | :10E220000D7404801A900323E02408F508A3E03459 422 | :10E2300003F50990031AE508F0A3E50912E242028A 423 | :10E24000DBA4F0A3E4F0A30412E24C22F0A3E4F078 424 | :10E2500090030D042274F41201F3900306E06404A9 425 | :10E26000701090031FE06401700890032512E148CC 426 | :10E27000600890030D7404F0804E900323E0FE903C 427 | :10E280000321E0FBEEFA900307E0F91206808A080A 428 | :10E290008B09EA450960DBEEFA7903120626900342 429 | :10E2A00021E0C0E0900323E02408F8A3E03403F960 430 | :10E2B00088828983D0E0F0AA08AB091206D49003C3 431 | :10E2C00023E0FA790412062602D81B74F61201F331 432 | :10E2D0007523007524007525008A268B27EA906235 433 | :10E2E0000BF08A088B097404780812054BE5089036 434 | :10E2F0006207F08A088B097409780812054BE50853 435 | :10E30000543E906209F002D70174F61201F3E59DC4 436 | :10E31000A2E650FA906206E0FAA2E25035A826E89A 437 | :10E3200090620BF0F5088527097404780812054BF4 438 | :10E33000E508906207F085260885270974097808A2 439 | :10E3400012054BE508543E906209F0906201E0D25C 440 | :10E35000E0F07823EA46F6906202E0F508750900DD 441 | :10E36000740478081205167823E50846F608E509CE 442 | :10E3700046F6906204E0F508750900740978081201 443 | :10E3800005167824E50946F6EAA2E0500375250152 444 | :10E3900074065A6003752500E58BA2E55006758B5F 445 | :10E3A000DF75250012062C02D70174F61201F31254 446 | :10E3B000EC9CF50895E0F50974027808120516E55D 447 | :10E3C00008240CF8E5093400F9901599E8F0A3E960 448 | :10E3D000F0E8FCE9FD900355ECF0A3ED12F224F017 449 | :10E3E000750804F50978081204F17C147DD17A745B 450 | :10E3F0007B1512EC521204A775082078081204F15C 451 | :10E4000012EC4A1204A77508007509017808120475 452 | :10E41000F17C9D7D137A007B0790D122E0F91206F2 453 | :10E420006274021204A790149CE0F4700B78081236 454 | :10E4300004F112ED831204A71205E412068C7AFF90 455 | :10E440007BFF1206F202EAA174F51201F3800312B7 456 | :10E4500006F8A2E840F990620E7404F0A823E8548C 457 | :10E460000460097823E654FBF6120692A823E854C8 458 | :10E470001060097823E654EFF6120698906214E0D3 459 | :10E48000A2E050031205F0906211E0A2E0403A9041 460 | :10E490000301E0700D900300E06402702C7403F03F 461 | :10E4A000802F64027023E4F0750874750915F50A6D 462 | :10E4B00078081204ED790D7A287B621206AA74039B 463 | :10E4C0001204A79062117401F0900300E0640370DD 464 | :10E4D000047901800279007F0302032BC082C0838C 465 | :10E4E00075AC00759A0012ED7A90620FE4F0E0A22C 466 | :10E4F000E740FB02F23874F61201F375080475095F 467 | :10E500000078081204F17C457D157A787B1512ECB1 468 | :10E51000521204A790D0FC12058590157C1205912B 469 | :10E52000901580E4F075081478081204F17C007DE1 470 | :10E53000007A607B1512ED8B1204A7901560E054F1 471 | :10E5400080F8A3E0F9E84470901560F0A3E9F0903A 472 | :10E550001569740AF090154912058590158D1205FC 473 | :10E56000911205C6E9F8901550E0642A700512056D 474 | :10E57000F680769003017402F01468600E90158D99 475 | :10E5800012058590157C120591805E901550E0640F 476 | :10E5900028704A906211E0A2E040F812F06A120579 477 | :10E5A0001612F052901512F0E9901511F075D60878 478 | :10E5B000E5D6A2E350FA75D70890159BE014F070E9 479 | :10E5C0000512F09D602390159CE004F0642070C358 480 | :10E5D000E4F090159EE004F01205D280B690158DFF 481 | :10E5E000E060069062117401F002EAA974F512016C 482 | :10E5F000F374E71204D77F01901550E0604B24FDBF 483 | :10E60000607024F1700302E6A924F8700302E6F0BA 484 | :10E6100014700302E71D24FE700302E82E14700339 485 | :10E6200002E72F24FB700302E73B24FE700302E79E 486 | :10E630009E24FD700302E7DB24FE700302E7DB2467 487 | :10E640008A700302E7E002E821900300E0600D9089 488 | :10E650001580EFF090030004F002E82E900302E032 489 | :10E66000700302E82E14F0600302E82E1205DE02A9 490 | :10E67000E82E901549E0FAA3E0FBC3EA9415EB9469 491 | :10E680000040027A14750860750915750A0078084B 492 | :10E690001204EDEAF97A287B621206AA74031204C6 493 | :10E6A000A7901560E0547F80AF901549E0F8A3E093 494 | :10E6B000F9C3E89425E994004017E824DCF8E9342C 495 | :10E6C000FFF9E8FAE9FB90157CEAF0A3EB12F224DB 496 | :10E6D000F07508487509D0750A0078081204ED79BC 497 | :10E6E000247A287B621206AA74031204A702E82E79 498 | :10E6F000740912059DAC82AD837583D07582F87460 499 | :10E7000004120414740912059DA982AA8389088A37 500 | :10E7100009750A0078081204ED790480C490155434 501 | :10E72000E06402600302E82E900300EF02E658A3C3 502 | :10E73000E0700302E82E90158080F0740D12059DA4 503 | :10E74000AC82AD837583D07582DC740C1204149096 504 | :10E75000159AE0C0E0741312059DD0E0F090159971 505 | :10E76000E0C0E0741412059DD0E012E838940DED7D 506 | :10E77000940040027C0C906215E0D2E7F0906212A7 507 | :10E78000E0D2E7F0740D12059DA982AA8389088A58 508 | :10E7900009750A0078081204EDECF902E6E1EF12BF 509 | :10E7A000059DAC82AD837583D07582F07408120428 510 | :10E7B0001490159AE0C0E0740312059DD0E0F0902B 511 | :10E7C0001599E0C0E0740412059DD0E012E8389479 512 | :10E7D00009ED940040027C08EF80AB1205FC804EEE 513 | :10E7E000901549E0FAA3E0FB851882851983AC8275 514 | :10E7F000AD837583D1758220EF120414C3EA9402AD 515 | :10E80000EB940040027A01851882851983AC82ADB1 516 | :10E81000838C088D09750A0078081204EDEA02E776 517 | :10E820009A901580EF12F1D2742012F1C91FEFF9FE 518 | :10E8300074191204A702E4D7F0901549E0FCA3E094 519 | :10E84000FDC3EC2274F61201F390159EE064807013 520 | :10E850002F900D5B7480F0900D5F7401F0900D634C 521 | :10E860007404F0901599E0900D67F090159AE0907F 522 | :10E870000D68F0900D9B7455F0A374AAF002E9CFD7 523 | :10E88000E06481600302E9CF75083E7509007808ED 524 | :10E890001204F17C357D037A9D7B0B12EC5212043D 525 | :10E8A000A7900D9B7455F0A374AAF0A374F8F0A37D 526 | :10E8B00074FFF0A3F090153BE0900DA07021E4F000 527 | :10E8C000A3F0F50875090178081204F17C9D7D1309 528 | :10E8D0007A9D7B1112EC521204A790129C8039741D 529 | :10E8E000FFF0A3740FF075082078081204F17C2162 530 | :10E8F0007D157A9D7B1112EC521204A775080075E4 531 | :10E90000090178081204F17C9D7D137ABD7B1112F8 532 | :10E91000EC521204A79012BCE4F090149CE0700337 533 | :10E9200002E9B612EC932404FEE93400FF7A047B7A 534 | :10E93000007C047D0280227AFF7B0FEAC0E012E9AE 535 | :10E94000D2D0E012E9DDEB540FC0E012E9D2D0E002 536 | :10E95000F0EA24010AEB3400FBC3EE9AEF9B405629 537 | :10E96000EE6A7002EF6B70047AFF7B0FECF8EDF942 538 | :10E97000E824010CE93400FDEAC454F0F508749D64 539 | :10E9800028F582740B39F583E04508F08A088B0975 540 | :10E990007404780812054B12E9D2E50812E9DDEAA1 541 | :10E9A00024010AEB3400FBEE6A7002EF6B6088C34F 542 | :10E9B000EE9AEF9B508575080075090278081204DD 543 | :10E9C000F17C9D7D0D7A9D7B0F12EC521204A70203 544 | :10E9D000EAA9749D2CF582740B3DF58322F0EC249A 545 | :10E9E000010CED3400FD2274F61201F374FF1204E1 546 | :10E9F000D790159EE0C39480503290149CE0602C18 547 | :10EA000090159EE05407F87401B800028004C333E7 548 | :10EA1000D8FCC0E0E0131313541FF874E528F58206 549 | :10EA2000741412F065D0E0F8E058603785188285DC 550 | :10EA30001983E4F0E58290151AF0851983E5839037 551 | :10EA40001519F09015207412F075D610E5D6A2E4D1 552 | :10EA500050FA75D71090159EE0C39480403E120581 553 | :10EA6000CC8039E5C7FA90151A12F08B12051624DE 554 | :10EA700000E5093480901519F090152012F0787592 555 | :10EA8000D610E5D6A2E450FA75D710E5D6A2E44038 556 | :10EA9000FA8AC77A9D7B0BE0F9120638740102EC02 557 | :10EAA0004453F4FED29043FE017F0202032B74F61E 558 | :10EAB0001201F374FC1204D790159CE0C394195012 559 | :10EAC0000302EBFF851882851983AC82AD837583C1 560 | :10EAD000D175820874041204147EBD7F118008EE83 561 | :10EAE0002420FEEF3400FF75082075090078081215 562 | :10EAF00004F17CAC7DD0EEFAEF12EC741204A78B1B 563 | :10EB000009EA450970D9EE24E0FEEF34FFFF7508ED 564 | :10EB10000375090078081204F17C007DD1EE240809 565 | :10EB200012EC6C1204A78B09EA45097508047509F3 566 | :10EB300000780870551204F1740212059D12EC65FC 567 | :10EB40001204A78B09EA4509900303700A7404F0C4 568 | :10EB500090153BE402EC3B740212F05E740212EC7E 569 | :10EB60007B7464F0EE241D12EC5BEE241E12EC5B51 570 | :10EB700012EC58750820F50978081204F1EEFCEF44 571 | :10EB8000FD12EC4E1204A702EC3C1204F1740212C6 572 | :10EB9000059D12EC651204A78B09EA4509700B90DC 573 | :10EBA00003037403F090149C80A912EC932401F5E4 574 | :10EBB00008E93400F5097403780812051690030378 575 | :10EBC0000412F05E740312EC7BE4F0EE241D12F0EC 576 | :10EBD00062E508F0EE241E12F062E509F012EC582E 577 | :10EBE000F50875090178081204F17CBD7D117A9D44 578 | :10EBF0007B1312EC521204A790149C7401803CE029 579 | :10EC0000C394114037900FA0E0701B90153BE0605B 580 | :10EC100015E4F09003037404F090149CE0701D79E7 581 | :10EC2000011206568016900FA1E054F0700E901459 582 | :10EC30009CE06008E4F09003037403F09003027416 583 | :10EC400008F074041204A702EAA97C6C7DD07A2132 584 | :10EC50007B15120704740222EE241FF582EF3400A4 585 | :10EC6000F583E4F022AC82AD83EE241CFAEF34008D 586 | :10EC700012EC7422FB1206FE740222F0EE241BF545 587 | :10EC800082EF3400F583E4F0EE241CF582EF3400CB 588 | :10EC9000F5832212EC9CF895E0F9E82290D123E06C 589 | :10ECA000F890D122E0FAE8C39A2274F61201F31226 590 | :10ECB000ED7A900303E014600A24FE604E14607144 591 | :10ECC00002ED6B901500E0600302ED6B120632E975 592 | :10ECD000700302ED6B75084075090078081204F1A5 593 | :10ECE0007C9D7D1390D122E0F50874097808120507 594 | :10ECF0001624C0FAE5093401FB12066874021204F6 595 | :10ED0000A7C2AF75C9AB75C95B80FE901500E070F6 596 | :10ED1000047900800890153BE060167901120656D0 597 | :10ED200075080075090178081204F112ED831204C8 598 | :10ED3000A790149FE4F0A3F090149CE0702D901520 599 | :10ED40003BE0702775082075090078081204F1125D 600 | :10ED5000EC4A1204A775086478081204F17CFF7D60 601 | :10ED6000007A9D7B1412ED8B1204A7900303E4F04C 602 | :10ED70007AD07B071205EA02EAA153F4FEC290435F 603 | :10ED8000FE01227C007D007A9D7B1312070A74022B 604 | :10ED900022C082C0837415F5D375D2019015027418 605 | :10EDA00028F09015017462F090150512EDF27412BE 606 | :10EDB000F090150C749DF0740390150BF090150DE8 607 | :10EDC00012F2227420F09015147428F09015137428 608 | :10EDD00062F090151512EDF27442F090151C749DBE 609 | :10EDE000F0740B90151BF090151D12F22274200286 610 | :10EDF000F237E4F0A37440F0A37420F0A322EBC335 611 | :10EE000013FBEA13FAEAF8EBF9E824FFFAE934FF16 612 | :10EE1000FBE849601A00000000000000000000004C 613 | :10EE20000000000000000000000000000080D6028A 614 | :10EE3000045A74F61201F3906216E0FA741F6A70B5 615 | :10EE40005578417915906228E088828983F0A3A8DB 616 | :10EE500082A9831AEA70EE75080475090078081211 617 | :10EE600004F17C187DD17A417B1512EC751204A750 618 | :10EE70008B09EA4509702A90154EE0702490154DD3 619 | :10EE8000E060046480701A90154FE014C394105031 620 | :10EE9000101205C0800B9062147410F0E0A2E440E0 621 | :10EEA000FB906214E4F002EAA974F61201F3906296 622 | :10EEB00014E4F0906214E0A2E0400302F03912F092 623 | :10EEC0006A12051612F052901504F0E9901503F03D 624 | :10EED00075D602E5D6A2E150FA75D702906214E425 625 | :10EEE000F090159BE014F0700B12F09D70069003EB 626 | :10EEF000017402F090159CE004F06420600812F0A8 627 | :10EF0000B1600302F03990159EE06481700C120527 628 | :10EF1000D890159EE004F002F034900303E0640200 629 | :10EF2000702F90159EE064826006E0C394805021AB 630 | :10EF30007A9D7B0B12063EE9600302F034750820CF 631 | :10EF400075090078081204F112EC4A1204A702F0C5 632 | :10EF50003490159EE0C39480400302F03490150075 633 | :10EF6000E0600302F0347A9D7B0B90159EE0F9126D 634 | :10EF70000638E9700512F04480FE75080075090234 635 | :10EF800078081204F17C9D7D0B90159EE0F50875C4 636 | :10EF9000090074097808120516FAAB09120668749C 637 | :10EFA000021204A7E5C7FA90150A12F08B12051693 638 | :10EFB0002400E5093480901509F090151012F078BE 639 | :10EFC00075D604E5D6A2E250FA75D704E5D6A2E2DA 640 | :10EFD00040FA8AC775090878081204F17C9D7D0300 641 | :10EFE0007A9D7B0B12EC751204A78B09EA45096028 642 | :10EFF0000512F04480FE12F0B1603990159EE004D5 643 | :10F00000F0C39478400512F04480FEE05407F87491 644 | :10F0100001B800028004C333D8FCC0E0E01313132E 645 | :10F02000541FF874D528F582741412F065D0E0F8F6 646 | :10F03000E05860C790159CE4F012F0B1600302EE56 647 | :10F04000B302EAA97901120656C2AF75C9AB75C9F8 648 | :10F050005B22749D2508F8740B3509F9E822F0EE5F 649 | :10F06000241AF582EF3400F5832290159CE0F50810 650 | :10F0700075090074067808227452F090159EE0C459 651 | :10F08000540FF8E5C754F848F5C722E4F090159EF0 652 | :10F09000E0540FF508750900740B7808227408F025 653 | :10F0A000901597E024FFF0F8A3E034FFF0F9E84969 654 | :10F0B00022901597E0F8A3E0F9E8492274F61201CE 655 | :10F0C000F374FC1204D7901558E0FA901557E0F944 656 | :10F0D000EA901597F0A3E9F0901552E0C0E07403B0 657 | :10F0E00012059DD0E0F0901553E0C0E074021205C7 658 | :10F0F0009DD0E0F0901554E0C0E0740112059DD061 659 | :10F10000E0F0901555E0851882851983F07402129D 660 | :10F11000059D12F0B47028851882851983E0F8A344 661 | :10F12000E0F9901597E028FAA3E039FB901599E0F3 662 | :10F13000240CF8A3E03400F9C3EA98EB99401C9042 663 | :10F140001580740112F1D27421F0A3E412F1C99078 664 | :10F15000158D12058590157C12059190159B7408EC 665 | :10F16000F0851882851983E0FAA3E0FBC3EA940CCA 666 | :10F17000EB94004008EA24F4FAEB34FFFB8A088B96 667 | :10F18000097402780812054BA808E8333354FCF9D7 668 | :10F19000EAC39933333354F890159CF0851882856F 669 | :10F1A0001983C3E0940CA3E094005004748080049D 670 | :10F1B00090D122E028F8E890159EF0901550E06478 671 | :10F1C0002870031205D202EC42F0901560E04480F2 672 | :10F1D000F022F0901563E054F0F8A3E0F9E844055C 673 | :10F1E000901563F0A3E9F090156E228041C082C0B3 674 | :10F1F00083900320E064FE702190030DE07017906F 675 | :10F20000031A7421F0A374D112F22404F0A3E4F0E1 676 | :10F2100090030D0480096401600690030D7404F0EE 677 | :10F2200080167408F0A3E4F0A32280028000C0825C 678 | :10F23000C08390030D7404F0D083D08202045A80FE 679 | :10F24000ED02045A02045AFFFFFFFFFFFFFFFFFF1A 680 | :10F25000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE 681 | :10F26000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE 682 | :10F27000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E 683 | :10F28000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E 684 | :10F29000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E 685 | :10F2A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E 686 | :10F2B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E 687 | :10F2C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E 688 | :10F2D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E 689 | :10F2E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E 690 | :10F2F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E 691 | :10F30000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D 692 | :10F31000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD 693 | :10F32000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED 694 | :10F33000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD 695 | :10F34000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD 696 | :10F35000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD 697 | :10F36000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD 698 | :10F37000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D 699 | :10F38000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D 700 | :10F39000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D 701 | :10F3A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D 702 | :10F3B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D 703 | :10F3C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D 704 | :10F3D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D 705 | :10F3E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D 706 | :10F3F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D 707 | :10F40000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C 708 | :10F41000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC 709 | :10F42000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC 710 | :10F43000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC 711 | :10F44000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC 712 | :10F45000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC 713 | :10F46000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC 714 | :10F47000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C 715 | :10F48000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C 716 | :10F49000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C 717 | :10F4A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C 718 | :10F4B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C 719 | :10F4C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C 720 | :10F4D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C 721 | :10F4E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C 722 | :10F4F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C 723 | :10F50000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B 724 | :10F51000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB 725 | :10F52000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB 726 | :10F53000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB 727 | :10F54000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB 728 | :10F55000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB 729 | :10F56000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB 730 | :10F57000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B 731 | :10F58000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B 732 | :10F59000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B 733 | :10F5A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B 734 | :10F5B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B 735 | :10F5C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B 736 | :10F5D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B 737 | :10F5E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B 738 | :10F5F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B 739 | :10F60000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A 740 | :10F61000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA 741 | :10F62000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA 742 | :10F63000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA 743 | :10F64000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA 744 | :10F65000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA 745 | :10F66000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA 746 | :10F67000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A 747 | :10F68000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A 748 | :10F69000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A 749 | :10F6A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A 750 | :10F6B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A 751 | :10F6C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A 752 | :10F6D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A 753 | :10F6E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A 754 | :10F6F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A 755 | :10F70000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 756 | :10F71000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 757 | :10F72000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 758 | :10F73000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 759 | :10F74000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 760 | :10F75000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 761 | :10F76000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 762 | :10F77000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 763 | :10F78000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 764 | :10F79000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 765 | :10F7A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 766 | :10F7B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 767 | :10F7C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 768 | :10F7D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 769 | :10F7E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 770 | :10F7F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 771 | :0400000500000529C9 772 | :00000001FF 773 | -------------------------------------------------------------------------------- /Firmware/HCI/HCI_UART_115200bps_20130429.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/HCI/HCI_UART_115200bps_20130429.bin -------------------------------------------------------------------------------- /Firmware/HCI/HCI_UART_57600bps_20130502.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/HCI/HCI_UART_57600bps_20130502.bin -------------------------------------------------------------------------------- /Firmware/HCI/HCI_USBCDC_115200_20130429.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/HCI/HCI_USBCDC_115200_20130429.bin -------------------------------------------------------------------------------- /Firmware/MiniBeacon/MiniBeacon-20140409.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/Firmware/MiniBeacon/MiniBeacon-20140409.bin -------------------------------------------------------------------------------- /PCB/BLE_Mini.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/PCB/BLE_Mini.pdf -------------------------------------------------------------------------------- /PCB/BLE_Mini_Schematic_v1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RedBearLab/BLEMini/1fdc40b672e6b275a5f40840d0b7e8a2de3389e8/PCB/BLE_Mini_Schematic_v1.0.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BLEMini 2 | ======= 3 | 4 | BLE Mini is a small, certified BLE development board for makers to do their innovative projects. It can be used for BLE development using TI CC254x SDK. 5 | 6 | We also provide some examples to show how to integrate this board to other platform such as Arduino. It can also be run independently. 7 | 8 | You can write your own firmware for the BLE Mini, get TI CC254x SDK and IAR 8051 C compiler from their website. The current version for CC254x SDK is v1.4.0 and IAR 8051 C compiler is v8.20.2. 9 | 10 | Note: 11 | 12 | 1. For firmware update, since TI's bootloader (UBL) on the BLE Mini does not work on Windows 8.1 or later, OSX and Linux. It only works fine on Windows 7. 13 | 14 | 2. The CC254x SDK can only work on Windows platform (using IAR C Compiler). Suggest you using TI's CC Debugger for doing your own firmware. 15 | 16 | 3. If you are using Windows 8.1 or later, Linux or Mac, highly recommend you to install a copy of Windows 7 using Virtual Box or Parallels Desktop. 17 | 18 | 19 | Dependency 20 | ========== 21 | 22 | BLE Mini requires different firmwares to function, so it depends on some opensource projects:
23 | - [Biscuit Firmware](https://github.com/RedBearLab/Biscuit) (a BLE to UART firmware, factory default) 24 | - [MiniBeacon Firmware](https://github.com/RedBearLab/MiniBeacon) 25 | - [BLE_HCI](https://github.com/RedBearLab/BLE_HCI) 26 | 27 | All are hosted at https://github.com/RedBearLab 28 | 29 | Please refers to those repositories for source code and details. 30 | 31 | 32 | Examples 33 | ======== 34 | 35 | Samples show how to connect iOS/Mac to your Arduino via BLE link (with the Biscuit firmware). More interesting resource will be added soon. 36 | 37 | SimpleControls 38 | - This demo shows how to create controls for common Arduino pin settings 39 | - Please refer to "Readme_SimpleControls.txt" for details 40 | 41 | Chat 42 | - A simple chat demo for iOS to talk to Arduino 43 | - Please refer to "Readme_Chat.txt" for details 44 | 45 | MiniBeacon 46 | - Implemented Apple's iBeacon spec. 47 | - Use our MiniBeacon iOS App to set the parameters. 48 | 49 | 50 | Update Firmawre 51 | =============== 52 | 53 | Only work on Windows PC, press and hold the button on the board and connect it to an USB port, a MSD drive will be mounted and then drag and drop the firmware file (.bin) to the drive. 54 | 55 | 56 | Resources 57 | ========= 58 | 59 | 1. TI CC254x SDK
60 | http://www.ti.com/tool/ble-stack 61 | 62 | 2. TI CC254x forum
63 | http://e2e.ti.com/support/low_power_rf/f/538.aspx 64 | 65 | 3. TI CC2540 Datasheet 66 | http://www.ti.com/lit/ds/symlink/cc2540.pdf 67 | 68 | 4. TI CC254x Software Developer's Guide 69 | http://www.ti.com/lit/swru271 70 | 71 | 5. IAR C compiler for 8051 (CC254x is based on 8051)
72 | http://www.iar.com/Products/IAR-Embedded-Workbench/8051/ 73 | 74 | 6. RBL BLE Mini
75 | http://redbearlab.com/blemini/ 76 | 77 | 7. RBL BLE Mini Forum - Discussion and sharing
78 | https://redbearlab.zendesk.com/forums 79 | 80 | 81 | License 82 | ======= 83 | 84 | Copyright (c) 2013-2014 RedBearLab 85 | 86 | Permission is hereby granted, free of charge, to any person obtaining a copy 87 | of this software and associated documentation files (the "Software"), to deal 88 | in the Software without restriction, including without limitation the rights 89 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 90 | copies of the Software, and to permit persons to whom the Software is 91 | furnished to do so, subject to the following conditions: 92 | 93 | The above copyright notice and this permission notice shall be included in all 94 | copies or substantial portions of the Software. 95 | 96 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 97 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 98 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 99 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 100 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 101 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 102 | SOFTWARE. 103 | --------------------------------------------------------------------------------