eBoard 🐉  ①⑧⑨
Written for SIA 2017/2018
eBoard.h
Go to the documentation of this file.
1 //This was created by EagleoutIce 'document creator: create_doc' using doxygen 1.8.15 and python 3.5.2
2 //Created: 14.04.2018 23:58:08
3 #pragma GCC diagnostic push
4  #pragma GCC diagnostic ignored "-Wall"
5  #pragma GCC diagnostic ignored "-Wextra"
6  #pragma pack(push)
7  #pragma pack(16)
8 
9  #define EBOARD_VERSION "3.0c"
10  #define VALUE_TO_STRING(x) #x
11  #define VALUE(x) VALUE_TO_STRING(x)
12  #ifndef PREPROCESS_DEBUG
13  #define PREPROCESS_DEBUG 0
14  #endif
15  #define PPERFORM_PRAGMA(str) _Pragma(#str)
16  #if PREPROCESS_DEBUG == 1
17  #define DEBUG_MSG(str) PPERFORM_PRAGMA(message ("" #str))
18  #define MACRO_MSG(mac,str) PPERFORM_PRAGMA(message("You set " #mac " to " VALUE(mac) ": " #str))
19  #else
20  #define DEBUG_MSG(str) ;
21  #define MACRO_MSG(mac,str) ;
22  #endif
23  DEBUG_MSG("If you do not want any preprocessing information from this eBoard-Header set PREPROCESS_DEBUG to 0");
24  DEBUG_MSG("You are using eBoard-header v3.0c written by EagleoutIce");
25 
26 
27 
28 //i am a guard... leave me alone :D
29 #ifndef EBOARD_HEADER_GUARD
30  #define EBOARD_HEADER_GUARD
31  #ifdef DOC
32  DEBUG_MSG("Documentation macro SET => Full doc features enabled");
33  #define ARDUINO 200
34 
35  #define EBOARD_I2C 0x1
36 
37  #define EBOARD_LCD 0x1
38 
39  #define EBOARD_SHIFT_REGISTER 0x1
40 
41  #define EBOARD_BLUETOOTH 0x1
42 
43  #define REPT_TASK
44 
45  #define __AVR_ATmega2560__
46 
47  #define __AVR_ATmega328P__
48 
49  #define EBOARD_NEO 0x1
50 
51  #define HIGHSPEED
52 
53  #define __AVR__
54  #endif
55  #include <avr/pgmspace.h>
56 
57  namespace eagle_impl {}
58  using namespace eagle_impl;
59  #ifndef EBOARD_GUESSPATH
60  DEBUG_MSG("You are using Guesspath! Necessary libraries for eBoard will be included automatically");
61 
62  #define EBOARD_GUESSPATH 0x1
63  #else
64  DEBUG_MSG("You are not using Guesspath! Necessary libraries for eBoard have to be included manually");
65  #endif
66  #if defined(ARDUINO) //general platform-check [No tab]
67 
68  #define main eVirtual_main //main has a different meaning^^
69  #if ARDUINO >= 100 //this could be only Arduino.h but this snippet is portable :D
70  #include "Arduino.h"
71  #else
72  #include <wiring.h>
73  #endif
74  #if not ( defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__))
75  #error "This library was build for ARDUINO UNO R3 Aand ARDUINO MEGA 2560!"
76  #endif
77  #if defined(__AVR_ATmega2560__)
78  DEBUG_MSG("Building for Arduino Mega with ATmega2560");
79 
80  #define PIN_MAX 0x32 //53 pins to address - 4 !!53 is SS
81  #else
82  DEBUG_MSG("Building for Arduino Uno or Nano with ATmega328P");
83  #define PIN_MAX 0xA // 13 Pins to address - 4 !!10 is SS
84  #endif
85  #include <avr/io.h>
86  #include <avr/interrupt.h>
87  #if EBOARD_I2C > 0x0 && EBOARD_GUESSPATH > 0x0
88  DEBUG_MSG("You enabled I²C feature"s);
89 
90  #define twi_h
91  //#define ATMEGA8
92  #ifndef TWI_FREQ
93  #define TWI_FREQ 100000L
94  #endif
95  # ifndef TWI_BUFFER_LENGTH
96  #define TWI_BUFFER_LENGTH 32
97  #endif
98  #define TWI_READY 0
99  #define TWI_MRX 1
100  #define TWI_MTX 2
101  #define TWI_SRX 3
102  #define TWI_STX 4
103  //#include <inttypes.h>
104  //#include <avr/io.h>
105  #include <avr/interrupt.h>
106  #include <compat/twi.h>
107  #ifndef cbi
108  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
109  #endif
110  #ifndef sbi
111  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
112  #endif
113  #include "pins_arduino.h"
114  static volatile uint8_t twi_state;
115  static volatile uint8_t twi_slarw;
116  static volatile uint8_t twi_sendStop;
117  static volatile uint8_t twi_inRepStart;
118  static void (*twi_onSlaveTransmit)(void);
119  static void (*twi_onSlaveReceive)(uint8_t*, int);
121  static volatile uint8_t twi_masterBufferIndex;
122  static volatile uint8_t twi_masterBufferLength;
124  static volatile uint8_t twi_txBufferIndex;
125  static volatile uint8_t twi_txBufferLength;
127  static volatile uint8_t twi_rxBufferIndex;
128  static volatile uint8_t twi_error;
129  void twi_init(void) {
131  twi_sendStop = true;
132  twi_inRepStart = false;
133  digitalWrite(SDA, 1);
134  digitalWrite(SCL, 1);
135  cbi(TWSR, TWPS0);
136  cbi(TWSR, TWPS1);
137  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
138  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
139  }
140  inline void twi_setAddress(uint8_t address) {
141  TWAR = address << 1;
142  }
143  uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) {
144  uint8_t i;
145  if(TWI_BUFFER_LENGTH < length) return 0;
146  while(TWI_READY != twi_state) continue;
147  twi_state = TWI_MRX;
148  twi_sendStop = sendStop;
149  twi_error = 0xFF;
151  twi_masterBufferLength = length-1;
152  twi_slarw = TW_READ;
153  twi_slarw |= address << 1;
154  if (true == twi_inRepStart) {
155  twi_inRepStart = false;
156  TWDR = twi_slarw;
157  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
158  }
159  else
160  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
161  while(TWI_MRX == twi_state) continue;
162  if (twi_masterBufferIndex < length)
163  length = twi_masterBufferIndex;
164  for(i = 0; i < length; ++i) data[i] = twi_masterBuffer[i];
165  return length;
166  }
167  uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) {
168  uint8_t i;
169  if(TWI_BUFFER_LENGTH < length) return 1;
170  while(TWI_READY != twi_state) continue;
171  twi_state = TWI_MTX;
172  twi_sendStop = sendStop;
173  twi_error = 0xFF;
175  twi_masterBufferLength = length;
176  for(i = 0; i < length; ++i) twi_masterBuffer[i] = data[i];
177  twi_slarw = TW_WRITE;
178  twi_slarw |= address << 1;
179  if (true == twi_inRepStart) {
180  twi_inRepStart = false;
181  TWDR = twi_slarw;
182  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
183  }
184  else
185  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
186  while(wait && (TWI_MTX == twi_state)) continue;
187  if (twi_error == 0xFF) return 0;
188  else if (twi_error == TW_MT_SLA_NACK) return 2;
189  else if (twi_error == TW_MT_DATA_NACK) return 3;
190  else return 4;
191  }
192  uint8_t twi_transmit(const uint8_t* data, uint8_t length) {
193  uint8_t i;
194  if(TWI_BUFFER_LENGTH < length) return 1;
195  if(TWI_STX != twi_state) return 2;
196  twi_txBufferLength = length;
197  for(i = 0; i < length; ++i) twi_txBuffer[i] = data[i];
198  return 0;
199  }
200  void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) {
201  twi_onSlaveReceive = function;
202  }
203  void twi_attachSlaveTxEvent( void (*function)(void) ) {
204  twi_onSlaveTransmit = function;
205  }
206  void twi_reply(uint8_t ack) {
207  if(ack){
208  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
209  }else{
210  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
211  }
212  }
213  void twi_stop(void) {
214  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
215  while(TWCR & _BV(TWSTO)) continue;
217  }
218  void twi_releaseBus(void){
219  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
221  }
222  ISR(TWI_vect) {
223  switch(TW_STATUS){
224  case TW_START:
225  case TW_REP_START:
226  TWDR = twi_slarw;
227  twi_reply(1);
228  break;
229  case TW_MT_SLA_ACK:
230  case TW_MT_DATA_ACK:
233  twi_reply(1);
234  }else{
235  if (twi_sendStop) twi_stop();
236  else {
237  twi_inRepStart = true;
238  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
240  }
241  }
242  break;
243  case TW_MT_SLA_NACK:
244  twi_error = TW_MT_SLA_NACK;
245  twi_stop();
246  break;
247  case TW_MT_DATA_NACK:
248  twi_error = TW_MT_DATA_NACK;
249  twi_stop();
250  break;
251  case TW_MT_ARB_LOST:
252  twi_error = TW_MT_ARB_LOST;
253  twi_releaseBus();
254  break;
255  case TW_MR_DATA_ACK:
257  case TW_MR_SLA_ACK:
259  else twi_reply(0);
260  break;
261  case TW_MR_DATA_NACK:
263  if (twi_sendStop) twi_stop();
264  else {
265  twi_inRepStart = true;
266  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
268  }
269  break;
270  case TW_MR_SLA_NACK:
271  twi_stop();
272  break;
273  case TW_SR_SLA_ACK:
274  case TW_SR_GCALL_ACK:
275  case TW_SR_ARB_LOST_SLA_ACK:
276  case TW_SR_ARB_LOST_GCALL_ACK:
277  twi_state = TWI_SRX;
278  twi_rxBufferIndex = 0;
279  twi_reply(1);
280  break;
281  case TW_SR_DATA_ACK:
282  case TW_SR_GCALL_DATA_ACK:
285  twi_reply(1);
286  } else twi_reply(0);
287  break;
288  case TW_SR_STOP:
290  twi_stop();
292  twi_rxBufferIndex = 0;
293  twi_releaseBus();
294  break;
295  case TW_SR_DATA_NACK:
296  case TW_SR_GCALL_DATA_NACK:
297  twi_reply(0);
298  break;
299  case TW_ST_SLA_ACK:
300  case TW_ST_ARB_LOST_SLA_ACK:
301  twi_state = TWI_STX;
302  twi_txBufferIndex = 0;
303  twi_txBufferLength = 0;
305  if(0 == twi_txBufferLength){
306  twi_txBufferLength = 1;
307  twi_txBuffer[0] = 0x00;
308  }
309  case TW_ST_DATA_ACK:
312  else twi_reply(0);
313  break;
314  case TW_ST_DATA_NACK:
315  case TW_ST_LAST_DATA:
316  twi_reply(1);
318  break;
319  case TW_NO_INFO:
320  break;
321  case TW_BUS_ERROR:
322  twi_error = TW_BUS_ERROR;
323  twi_stop();
324  break;
325  }
326  }
327 
328  #include <inttypes.h>
329  #include "Stream.h"
330  #define BUFFER_LENGTH 32
331  namespace eagle_impl {
332 
333  class TwoWire : public Stream {
334  private:
335 
336  static uint8_t rxBuffer[];
337 
338  static uint8_t rxBufferIndex;
339 
340  static uint8_t rxBufferLength;
341 
342  static uint8_t txAddress;
343 
344  static uint8_t txBuffer[];
345 
346  static uint8_t txBufferIndex;
347 
348  static uint8_t txBufferLength;
349 
350  static uint8_t transmitting;
351 
352  static void (*user_onRequest)(void);
353 
354  static void (*user_onReceive)(int numBytes);
355 
356  static void onRequestService(void);
357 
358  static void onReceiveService(uint8_t* inBytes, int numBytes);
359  public:
360 
361  TwoWire();
362 
363  void begin();
364 
365  void begin(uint8_t address);
366 
367  inline void begin(int address);
368 
369  void beginTransmission(uint8_t address);
370 
371  inline void beginTransmission(int address);
372 
373  inline uint8_t endTransmission(void);
374 
375  uint8_t endTransmission(uint8_t sendStop);
376 
377  inline uint8_t requestFrom(uint8_t address, uint8_t quantity);
378 
379  uint8_t requestFrom(uint8_t address , uint8_t quantity, uint8_t sendStop);
380 
381  inline uint8_t requestFrom(int address, int quantity);
382 
383  inline uint8_t requestFrom(int address, int quantity, int sendStop);
384 
385  virtual size_t write(uint8_t data);
386 
387  virtual size_t write(const uint8_t *data, size_t quantity);
388 
389  virtual int available(void);
390 
391  virtual int read(void);
392 
393  virtual int peek(void);
394 
395  void onReceive( void (*function)(int) );
396 
397  void onRequest( void (*function)(void) );
398 
399  using Print::write;
400  };
401  }
402  extern "C" {
403  #include <stdlib.h>
404  #include <string.h>
405  #include <inttypes.h>
406  //#include "twi.h"
407  }
408 
410  uint8_t TwoWire::rxBufferIndex = 0;
411  uint8_t TwoWire::rxBufferLength = 0;
412  uint8_t TwoWire::txAddress = 0;
414  uint8_t TwoWire::txBufferIndex = 0;
415  uint8_t TwoWire::txBufferLength = 0;
416  uint8_t TwoWire::transmitting = 0;
417  void (*TwoWire::user_onRequest)(void);
418  void (*TwoWire::user_onReceive)(int);
420  void TwoWire::begin(void) {
421  rxBufferIndex = 0;
422  rxBufferLength = 0;
423  txBufferIndex = 0;
424  txBufferLength = 0;
425  twi_init();
426  }
427  void TwoWire::begin(uint8_t address) {
428  twi_setAddress(address);
431  begin();
432  }
433  void TwoWire::begin(int address) {
434  begin((uint8_t)address);
435  }
436  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
437  if(quantity > BUFFER_LENGTH){
438  quantity = BUFFER_LENGTH;
439  }
440  uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
441  rxBufferIndex = 0;
443  return read;
444  }
445  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
446  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
447  }
448  uint8_t TwoWire::requestFrom(int address, int quantity) {
449  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
450  }
451  uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
452  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
453  }
454  void TwoWire::beginTransmission(uint8_t address) {
455  transmitting = 1;
456  txAddress = address;
457  txBufferIndex = 0;
458  txBufferLength = 0;
459  }
460  void TwoWire::beginTransmission(int address) {
461  beginTransmission((uint8_t)address);
462  }
463  uint8_t TwoWire::endTransmission(uint8_t sendStop) {
464  int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
465  txBufferIndex = 0;
466  txBufferLength = 0;
467  transmitting = 0;
468  return ret;
469  }
471  return endTransmission(true);
472  }
473  size_t TwoWire::write(uint8_t data) {
474  if(transmitting) {
476  setWriteError();
477  return 0;
478  }
479  txBuffer[txBufferIndex] = data;
480  ++txBufferIndex;
482  }else{
483  twi_transmit(&data, 1);
484  }
485  return 1;
486  }
487  size_t TwoWire::write(const uint8_t *data, size_t quantity) {
488  if(transmitting){
489  for(size_t i = 0; i < quantity; ++i) {
490  write(data[i]);
491  }
492  }else{
493  twi_transmit(data, quantity);
494  }
495  return quantity;
496  }
497  int TwoWire::available(void) {
498  return rxBufferLength - rxBufferIndex;
499  }
500  int TwoWire::read(void) {
501  int8_t value = -1;
503  value = rxBuffer[rxBufferIndex];
504  ++rxBufferIndex;
505  }
506  return value;
507  }
508  int TwoWire::peek(void) {
509  int value = -1;
511  value = rxBuffer[rxBufferIndex];
512  }
513  return value;
514  }
515  void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) {
516  if(!user_onReceive){
517  return;
518  }
520  return;
521  }
522  for(uint8_t i = 0; i < numBytes; ++i) {
523  rxBuffer[i] = inBytes[i];
524  }
525  rxBufferIndex = 0;
526  rxBufferLength = numBytes;
527  user_onReceive(numBytes);
528  }
530  if(!user_onRequest) return;
531  txBufferIndex = 0;
532  txBufferLength = 0;
533  user_onRequest();
534  }
535  void TwoWire::onReceive( void (*function)(int) ) {
536  user_onReceive = function;
537  }
538  void TwoWire::onRequest( void (*function)(void) ) {
539  user_onRequest = function;
540  }
541 
542 
544  #else
545  DEBUG_MSG("You disabled I²C");
546  #endif
547 
548  #ifndef EBOARD_USE_SPI
549  #define EBOARD_USE_SPI 0x1
550  #endif
551  #if EBOARD_USE_SPI > 0x0
552  DEBUG_MSG("You enabled SPI");
553 
554  #define _SPI_H_INCLUDED
555  #include <stdio.h>
556 
557  #define SPI_CLOCK_DIV4 0x00
558 
559  #define SPI_CLOCK_DIV16 0x01
560 
561  #define SPI_CLOCK_DIV64 0x02
562 
563  #define SPI_CLOCK_DIV128 0x03
564 
565  #define SPI_CLOCK_DIV2 0x04
566 
567  #define SPI_CLOCK_DIV8 0x05
568 
569  #define SPI_CLOCK_DIV32 0x06
570 
571  #define SPI_MODE0 0x00
572 
573  #define SPI_MODE1 0x04
574 
575  #define SPI_MODE2 0x08
576 
577  #define SPI_MODE3 0x0C
578 
579  #define SPI_MODE_MASK 0x0C
580 
581  #define SPI_CLOCK_MASK 0x03
582 
583  #define SPI_2XCLOCK_MASK 0x01
584  namespace eagle_impl {
585 
586  struct SPIClass {
587 
588  inline static byte transfer(byte _data);
589 
590  inline static void attachInterrupt(void);
591 
592  inline static void detachInterrupt(void); // Default
593 
594  static void begin(void); // Default
595 
596  inline static void end(void);
597 
598  inline static void setBitOrder(uint8_t bitOrder);
599 
600  inline static void setDataMode(uint8_t mode);
601 
602  inline static void setClockDivider(uint8_t rate);
603  };
604  }
605 
606  byte SPIClass::transfer(byte _data) {
607  SPDR = _data;
608  while (!(SPSR & _BV(SPIF)));
609  return SPDR;
610  }
611  void SPIClass::attachInterrupt() { SPCR |= _BV(SPIE);}
612  void SPIClass::detachInterrupt() { SPCR &= ~_BV(SPIE);}
614  digitalWrite(SS, HIGH);
615  pinMode(SS, OUTPUT); //doesn't block common use as_ OUTPUT!
616  SPCR |= _BV(MSTR);
617  SPCR |= _BV(SPE);
618  pinMode(SCK, OUTPUT);
619  pinMode(MOSI, OUTPUT);
620  }
621  void SPIClass::end() {SPCR &= ~_BV(SPE);}
622  void SPIClass::setBitOrder(uint8_t bitOrder) {
623  if(bitOrder == LSBFIRST) SPCR |= _BV(DORD);
624  else SPCR &= ~(_BV(DORD));
625  }
626  void SPIClass::setDataMode(uint8_t mode) { SPCR = (SPCR & ~SPI_MODE_MASK) | mode; }
627  void SPIClass::setClockDivider(uint8_t rate) {
628  SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
629  SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
630  }
631 
633  #else
634  DEBUG_MSG("You disabled SPI");
635  #endif
636  #if (EBOARD_I2C > 0x0) && (EBOARD_LCD > 0x0)
637  #include <avr/pgmspace.h>
638  DEBUG_MSG("You enabled LCD");
639  #endif
640 
641  static bool STOP = false;
642 
643  #ifdef IGNORE_SIZE
644  DEBUG_MSG("You defined IGNORE_SIZE: byte will be used");
645  typedef byte optVAL_t;
646  #else
647  DEBUG_MSG("You did not define IGNORE_SIZE: int will be used");
648  typedef int optVAL_t;
649  #endif
650 
651  #ifndef EBOARD_DEBUG_MODE
652  #define EBOARD_DEBUG_MODE 0x1
653  #endif
654  #if EBOARD_DEBUG_MODE > 0x0
655  MACRO_MSG(EBOARD_DEBUG_MODE,"Serial feedback will be send to Computer");
656  #else
657  MACRO_MSG(EBOARD_DEBUG_MODE, "No Serial feedback!");
658  #endif
659 
660  #ifndef EBOARD_NANO
661  #define EBOARD_NANO 0x0
662  #endif
663  #if EBOARD_NANO > 0x0
664  #ifndef EBOARD_NANO_STEER
665  #define EBOARD_NANO_STEER 12
666  #endif
667  #ifndef EBOARD_NANO_MAIN
668  #define EBOARD_NANO_MAIN 13
669  #endif
670  MACRO_MSG(EBOARD_NANO,"Using Arduino NANO environment [e.g. remove SoccerBoard]");
671  #if PREPROCESS_DEBUG > 0x1
672  #pragma message("Using " VALUE(EBOARD_NANO_STEER) " as data pin for STEERING MOTOR")
673  #pragma message("Using " VALUE(EBOARD_NANO_MAIN) " as data pin for MAIN (Driving) MOTOR")
674  #endif
675  #else
676  MACRO_MSG(EBOARD_NANO,"Using Arduino UNO/MEGA environment");
677  #endif
678 
679  #ifndef EBOARD_CHECK_PINS
680  #define EBOARD_CHECK_PINS 0x1
681  #endif
682  #if EBOARD_CHECK_PINS > 0x0
683  MACRO_MSG(EBOARD_CHECK_PINS,"Check for Pins enabled");
684  #else
685  MACRO_MSG(EBOARD_CHECK_PINS,"Check for Pins disabled");
686  #endif
687  #ifndef EBOARD_SHIFT_REGISTER
688 
689  #define EBOARD_SHIFT_REGISTER 0x0
690  #endif
691  #if EBOARD_SHIFT_REGISTER > 0x0
692  MACRO_MSG(EBOARD_SHIFT_REGISTER,"Shiftregister enabled");
693  #else
694  MACRO_MSG(EBOARD_SHIFT_REGISTER,"Shiftregister disabled");
695  #endif
696 
697  #ifndef EBOARD_CHECK_PINS_PWM
698  #define EBOARD_CHECK_PINS_PWM 0x1
699  #endif
700  #if EBOARD_CHECK_PINS_PWM > 0x0
701  MACRO_MSG(EBOARD_CHECK_PINS_PWM,"Check for PWM-Pins enabled");
702  #else
703  MACRO_MSG(EBOARD_CHECK_PINS_PWM,"Check for PWM-Pins disabled");
704  #endif
705 
706  #ifndef EBOARD_DEBUG_SPEED
707  #define EBOARD_DEBUG_SPEED 9600
708  #endif
709  #if PREPROCESS_DEBUG > 0x0
710  #pragma message("Set Debugging speed to " VALUE(EBOARD_DEBUG_SPEED))
711  #endif
712 
713  #ifndef EBOARD_SPI_SERVO_MAX
714  #define EBOARD_SPI_SERVO_MAX 2
715  #endif
716  #if PREPROCESS_DEBUG > 0x0
717  #pragma message("Set amount of used Servos to " VALUE(EBOARD_SPI_SERVO_MAX))
718  #endif
719 
720  #ifndef EBOARD_USE_UTILITY
721  #define EBOARD_USE_UTILITY 0x1
722  #endif
723  #if EBOARD_USE_UTILITY > 0x0
724  MACRO_MSG(EBOARD_USE_UTILITY,"Utility features will be implemented");
725  #else
726  MACRO_MSG(EBOARD_USE_UTILITY,"Utility features will not be implemented");
727  #endif
728 
729  #define EBOARD_COPY_AND_PASTE 0x1
730 
731  #ifndef EBOARD_PWM_SPE
732  #define EBOARD_PWM_SPE 1
733  #endif
734  #if PREPROCESS_DEBUG > 0x0
735  #pragma message("Set PWM interval to " VALUE(EBOARD_PWM_SPE) "s")
736  #endif
737  #ifndef EBOARD_I2C
738 
739  #define EBOARD_I2C 0x0 //disabled by default
740  #endif
741  #ifndef EBOARD_BLUETOOTH
742 
743  #define EBOARD_BLUETOOTH 0x0
744  #endif
745  #if EBOARD_BLUETOOTH > 0x0
746  MACRO_MSG(EBOARD_BLUETOOTH,"Bluetooth controls enabled");
747  #else
748  MACRO_MSG(EBOARD_BLUETOOTH,"Bluetooth controls disabled");
749  #endif
750 
751  #ifndef EBOARD_CLAMP
752  #define EBOARD_CLAMP 0x1
753  #endif
754  #if EBOARD_CLAMP > 0x0
755  MACRO_MSG(EBOARD_CLAMP,"Motor Range is set to [0;1023]");
756  #else
757  MACRO_MSG(EBOARD_CLAMP,"Motor Range is set to [-300;300]");
758  #endif
759  #ifndef EBOARD_NEO
760 
761  #define EBOARD_NEO 0x0
762  #endif
763  #if EBOARD_NEO > 0x0
764  MACRO_MSG(EBOARD_NEO,"Adafruit Neo-Pixel support enabled");
765  #else
766  MACRO_MSG(EBOARD_NEO,"Adafruit Neo-Pixel support disabled");
767  #endif
768 
769  #ifndef EBOARD_USE_RESET
770  #define EBOARD_USE_RESET 0x1
771  #endif
772  #if EBOARD_USE_RESET > 0x0
773  #include <avr/wdt.h>
774  MACRO_MSG(EBOARD_USE_RESET,"Software-Reset is available" );
775  #else
776  MACRO_MSG(EBOARD_USE_RESET,"Software-Reset is not available" );
777  #endif
778 
779  #ifndef PIN_BLUETOOTH_STATE
780  #if defined(__AVR_ATmega2560__)
781  #define PIN_BLUETOOTH_STATE 0x13 // 19
782  #else
783  #define PIN_BLUETOOTH_STATE 0x2
784  #endif
785  #endif
786 
787  #ifndef PIN_BLUETOOTH_RX
788  #if defined(__AVR_ATmega2560__)
789  #define PIN_BLUETOOTH_RX 0x13 // 19
790  #else
791  #define PIN_BLUETOOTH_RX 0x2
792  #endif
793  #endif
794 
795  #ifndef PIN_BLUETOOTH_TX
796  #if defined(__AVR_ATmega2560__)
797  #define PIN_BLUETOOTH_TX 0x12 // 18
798  #else
799  #define PIN_BLUETOOTH_TX 0x3
800  #endif
801  #endif
802 
803  #ifndef PIN_MOTOR_DIR
804  #define PIN_MOTOR_DIR 0x4
805  #endif
806 
807  #ifndef PIN_MOTOR_SPE
808  #define PIN_MOTOR_SPE 0x5
809  #endif
810 
811  #ifndef PIN_SHIFT_CLK
812  #define PIN_SHIFT_CLK 0x6
813  #endif
814 
815  #ifndef PIN_SHIFT_DAT
816  #define PIN_SHIFT_DAT 0x7
817  #endif
818 
819  #ifndef PIN_SHIFT_LAT
820  #define PIN_SHIFT_LAT 0x8
821  #endif
822  //done by arduino
823  //if this has an effect... something went wrong :D
824  #ifndef HIGH
825  #define HIGH 1
826  #endif
827  #ifndef LOW
828  #define LOW 0
829  #endif
830  #if (EBOARD_BLUETOOTH > 0x0) && defined(__AVR_ATmega328P__)
831  #if EBOARD_GUESSPATH > 0x0
832  //again to resolve including errors we'll include the SoftwareSerial cpp file
833  #define _SS_MAX_RX_BUFF 64 // RX buffer size
834  #ifndef GCC_VERSION
835  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
836  #endif
837  namespace eagle_impl {
838 
839  class SoftwareSerial : public Stream {
840  private:
841 
842  uint8_t _receivePin;
843 
845 
846  volatile uint8_t *_receivePortRegister;
847 
849 
850  volatile uint8_t *_transmitPortRegister;
851 
853 
855 
857 
858  uint16_t _tx_delay;
859 
860  uint16_t _buffer_overflow:1;
861 
862  uint16_t _inverse_logic:1;
863 
865 
866  static volatile uint8_t _receive_buffer_tail;
867 
868  static volatile uint8_t _receive_buffer_head;
869 
871 
872  void recv(void);
873 
874  inline uint8_t rx_pin_read(void);
875 
876  inline void tx_pin_write(uint8_t pin_state);
877 
878  void setTX(uint8_t transmitPin);
879 
880  void setRX(uint8_t receivePin);
881 
882  static inline void tunedDelay(uint16_t delay);
883  public:
884  // public methods
885 
886  SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
887 
888  ~SoftwareSerial(void);
889 
890  void begin(long speed);
891 
892  bool listen(void);
893 
894  inline void end(void);
895 
896  inline bool isListening(void);
897 
898  inline bool overflow(void);
899 
900  int peek(void);
901 
902  virtual size_t write(uint8_t byte);
903 
904  virtual int read(void);
905 
906  virtual int available(void);
907 
908  virtual void flush(void);
909  //used to save codespace
910  using Print::write;
911 
912  static inline void handle_interrupt(void);
913  };
914  }
915 
917  return this == active_object;
918  }
920  bool ret = _buffer_overflow;
921  _buffer_overflow = false;
922  return ret;
923  }
924 
925  #if EBOARD_DEBUG_MODE > 0x0
926  #define _DEBUG 0
927  #define _DEBUG_PIN1 11
928  #define _DEBUG_PIN2 13
929  #endif
930  typedef struct _DELAY_TABLE {
931  long baud;
932  unsigned short rx_delay_centering;
933  unsigned short rx_delay_intrabit;
934  unsigned short rx_delay_stopbit;
935  unsigned short tx_delay;
936  } DELAY_TABLE;
937  #if F_CPU == 16000000
938  static const DELAY_TABLE PROGMEM table[] = {
939  // baud rxcenter rxintra rxstop tx
940  { 115200, 1, 17, 17, 12, },
941  { 57600, 10, 37, 37, 33, },
942  { 38400, 25, 57, 57, 54, },
943  { 31250, 31, 70, 70, 68, },
944  { 28800, 34, 77, 77, 74, },
945  { 19200, 54, 117, 117, 114, },
946  { 14400, 74, 156, 156, 153, },
947  { 9600, 114, 236, 236, 233, },
948  { 4800, 233, 474, 474, 471, },
949  { 2400, 471, 950, 950, 947, },
950  { 1200, 947, 1902, 1902, 1899, },
951  { 600, 1902, 3804, 3804, 3800, },
952  { 300, 3804, 7617, 7617, 7614, },
953  };
954  const int XMIT_START_ADJUSTMENT = 5;
955  #elif F_CPU == 8000000
956  static const DELAY_TABLE table[] PROGMEM = {
957  // baud rxcenter rxintra rxstop tx
958  { 115200, 1, 5, 5, 3, },
959  { 57600, 1, 15, 15, 13, },
960  { 38400, 2, 25, 26, 23, },
961  { 31250, 7, 32, 33, 29, },
962  { 28800, 11, 35, 35, 32, },
963  { 19200, 20, 55, 55, 52, },
964  { 14400, 30, 75, 75, 72, },
965  { 9600, 50, 114, 114, 112, },
966  { 4800, 110, 233, 233, 230, },
967  { 2400, 229, 472, 472, 469, },
968  { 1200, 467, 948, 948, 945, },
969  { 600, 948, 1895, 1895, 1890, },
970  { 300, 1895, 3805, 3805, 3802, },
971  };
972  const int XMIT_START_ADJUSTMENT = 4;
973  #elif F_CPU == 20000000
974  static const DELAY_TABLE PROGMEM table[] = {
975  // baud rxcenter rxintra rxstop tx
976  { 115200, 3, 21, 21, 18, },
977  { 57600, 20, 43, 43, 41, },
978  { 38400, 37, 73, 73, 70, },
979  { 31250, 45, 89, 89, 88, },
980  { 28800, 46, 98, 98, 95, },
981  { 19200, 71, 148, 148, 145, },
982  { 14400, 96, 197, 197, 194, },
983  { 9600, 146, 297, 297, 294, },
984  { 4800, 296, 595, 595, 592, },
985  { 2400, 592, 1189, 1189, 1186, },
986  { 1200, 1187, 2379, 2379, 2376, },
987  { 600, 2379, 4759, 4759, 4755, },
988  { 300, 4759, 9523, 9523, 9520, },
989  };
990  const int XMIT_START_ADJUSTMENT = 6;
991  #else
992  #error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
993  #endif
996  volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
997  volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
998  #if EBOARD_DEBUG_MODE > 0x0
999  inline void DebugPulse(uint8_t pin, uint8_t count) {
1000  #if _DEBUG
1001  volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
1002  uint8_t val = *pport;
1003  while (count--)
1004  {
1005  *pport = val | digitalPinToBitMask(pin);
1006  *pport = val;
1007  }
1008  #endif
1009  }
1010  #endif
1011  inline void SoftwareSerial::tunedDelay(uint16_t delay) {
1012  uint8_t tmp=0;
1013  asm volatile("sbiw %0, 0x01 \n\t"
1014  "ldi %1, 0xFF \n\t"
1015  "cpi %A0, 0xFF \n\t"
1016  "cpc %B0, %1 \n\t"
1017  "brne .-10 \n\t"
1018  : "+r" (delay), "+a" (tmp)
1019  : "0" (delay)
1020  );
1021  }
1023  if (active_object != this)
1024  {
1025  _buffer_overflow = false;
1026  uint8_t oldSREG = SREG;
1027  cli();
1029  active_object = this;
1030  SREG = oldSREG;
1031  return true;
1032  }
1033  return false;
1034  }
1036  #if GCC_VERSION < 40302
1037  asm volatile(
1038  "push r18 \n\t"
1039  "push r19 \n\t"
1040  "push r20 \n\t"
1041  "push r21 \n\t"
1042  "push r22 \n\t"
1043  "push r23 \n\t"
1044  "push r26 \n\t"
1045  "push r27 \n\t"
1046  ::);
1047  #endif
1048  uint8_t d = 0;
1049  if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) {
1050  // Wait approximately 1/2 of a bit width to "center" the sample
1052  #if EBOARD_DEBUG_MODE > 0x0
1053  DebugPulse(_DEBUG_PIN2, 1);
1054  #endif
1055  // Read each of the 8 bits
1056  for (uint8_t i=0x1; i; i <<= 1)
1057  {
1059  #if EBOARD_DEBUG_MODE > 0x0
1060  DebugPulse(_DEBUG_PIN2, 1);
1061  #endif
1062  uint8_t noti = ~i;
1063  if (rx_pin_read())
1064  d |= i;
1065  else
1066  d &= noti;
1067  }
1068  // skip the stop bit
1070  #if EBOARD_DEBUG_MODE > 0x0
1071  DebugPulse(_DEBUG_PIN2, 1);
1072  #endif
1073  if (_inverse_logic)
1074  d = ~d;
1076  _receive_buffer[_receive_buffer_tail] = d; // save new byte
1078  }
1079  else {
1080  #if EBOARD_DEBUG_MODE > 0x0
1081  #if _DEBUG // for scope: pulse pin as overflow indictator
1082  DebugPulse(_DEBUG_PIN1, 1);
1083  #endif
1084  #endif
1085  _buffer_overflow = true;
1086  }
1087  }
1088  #if GCC_VERSION < 40302
1089  asm volatile(
1090  "pop r27 \n\t"
1091  "pop r26 \n\t"
1092  "pop r23 \n\t"
1093  "pop r22 \n\t"
1094  "pop r21 \n\t"
1095  "pop r20 \n\t"
1096  "pop r19 \n\t"
1097  "pop r18 \n\t"
1098  ::);
1099  #endif
1100  }
1101  void SoftwareSerial::tx_pin_write(uint8_t pin_state) {
1102  if (pin_state == LOW)
1104  else
1106  }
1109  }
1111  if (active_object) {
1112  active_object->recv();
1113  }
1114  }
1115  #if defined(PCINT0_vect)
1116  ISR(PCINT0_vect) {
1118  }
1119  #endif
1120  #if defined(PCINT1_vect)
1121  ISR(PCINT1_vect) {
1123  }
1124  #endif
1125  #if defined(PCINT2_vect)
1126  ISR(PCINT2_vect) {
1128  }
1129  #endif
1130  #if defined(PCINT3_vect)
1131  ISR(PCINT3_vect) {
1133  }
1134  #endif
1135  SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic ) :
1136  _rx_delay_centering(0),
1137  _rx_delay_intrabit(0),
1138  _rx_delay_stopbit(0),
1139  _tx_delay(0),
1140  _buffer_overflow(false),
1141  _inverse_logic(inverse_logic) {
1142  setTX(transmitPin);
1143  setRX(receivePin);
1144  }
1146  end();
1147  }
1148  void SoftwareSerial::setTX(uint8_t tx) {
1149  pinMode(tx, OUTPUT);
1150  digitalWrite(tx, HIGH);
1151  _transmitBitMask = digitalPinToBitMask(tx);
1152  uint8_t port = digitalPinToPort(tx);
1153  _transmitPortRegister = portOutputRegister(port);
1154  }
1155  void SoftwareSerial::setRX(uint8_t rx) {
1156  pinMode(rx, INPUT);
1157  if (!_inverse_logic)
1158  digitalWrite(rx, HIGH);
1159  _receivePin = rx;
1160  _receiveBitMask = digitalPinToBitMask(rx);
1161  uint8_t port = digitalPinToPort(rx);
1162  _receivePortRegister = portInputRegister(port);
1163  }
1164  void SoftwareSerial::begin(long speed) {
1166  for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
1167  long baud = pgm_read_dword(&table[i].baud);
1168  if (baud == speed) {
1169  _rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
1170  _rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
1171  _rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
1172  _tx_delay = pgm_read_word(&table[i].tx_delay);
1173  break;
1174  }
1175  }
1176  if (_rx_delay_stopbit) {
1177  if (digitalPinToPCICR(_receivePin)) {
1178  *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
1179  *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
1180  }
1182  }
1183  #if _DEBUG
1184  pinMode(_DEBUG_PIN1, OUTPUT);
1185  pinMode(_DEBUG_PIN2, OUTPUT);
1186  #endif
1187  listen();
1188  }
1190  if (digitalPinToPCMSK(_receivePin))
1191  *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
1192  }
1194  if (!isListening())
1195  return -1;
1197  return -1;
1198  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
1200  return d;
1201  }
1203  if (!isListening())
1204  return 0;
1206  }
1207  size_t SoftwareSerial::write(uint8_t b) {
1208  if (_tx_delay == 0) {
1209  setWriteError();
1210  return 0;
1211  }
1212  uint8_t oldSREG = SREG;
1213  cli();
1214  tx_pin_write(_inverse_logic ? HIGH : LOW);
1215  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
1216  if (_inverse_logic) {
1217  for (byte mask = 0x01; mask; mask <<= 1) {
1218  if (b & mask)
1219  tx_pin_write(LOW);
1220  else
1221  tx_pin_write(HIGH);
1223  }
1224  tx_pin_write(LOW);
1225  }
1226  else {
1227  for (byte mask = 0x01; mask; mask <<= 1) {
1228  if (b & mask)
1229  tx_pin_write(HIGH);
1230  else
1231  tx_pin_write(LOW);
1233  }
1234  tx_pin_write(HIGH);
1235  }
1236  SREG = oldSREG;
1238  return 1;
1239  }
1241  if (!isListening())
1242  return;
1243  uint8_t oldSREG = SREG;
1244  cli();
1246  SREG = oldSREG;
1247  }
1249  if (!isListening())
1250  return -1;
1252  return -1;
1254  }
1255 
1256  #endif
1257 
1259  #endif
1260  #if EBOARD_DEBUG_MODE > 0x0
1261 
1262  #define __ASSERT_USE_STDERR
1263  #include <assert.h>
1264 
1265  void __assert (const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp);
1266 
1267  void __assert (const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp){
1268  Serial.print("Error with: "); Serial.print(__func);
1269  Serial.print(" in "); Serial.print(__file);
1270  Serial.print(" >>");
1271  Serial.println(__sexp);
1272  if(strcmp(__func,"checkIdx")==0){
1273  Serial.println(" This happens if an out of bounds exception");
1274  Serial.println(" has occured. Following pins shouldn't be used:");
1275  Serial.print(" D" + PIN_BLUETOOTH_RX);Serial.print("&");
1276  Serial.print("D");Serial.print(PIN_BLUETOOTH_TX);
1277  Serial.println(" : Used for Bluetooth communication");
1278  Serial.print(" D");Serial.print(PIN_MOTOR_DIR);Serial.print("&");
1279  Serial.print("D");Serial.print(PIN_MOTOR_SPE);
1280  Serial.println(" : Used for main motor control");
1281  #if EBOARD_USE_SPI > 0x0
1282  Serial.print(" D10-13");
1283  Serial.println(": Used for smart-servo-shield");
1284  #endif
1285  } else if (strcmp(__func,"readPin")==0){
1286  Serial.println("You've tried to access an analogPin that isn't present on the board you're currently working on!");
1287  }
1288  Serial.flush();
1289  abort(); // halt after outputting information
1290  }
1291 
1292  #endif
1293 
1294  inline void checkIdx(optVAL_t idx);
1295 
1296  inline void checkIdx(optVAL_t idx){
1297  #if EBOARD_DEBUG_MODE > 0x0
1298  assert(idx>=0x0 && idx < PIN_MAX); //changed pins? change me! (didn't want to use macros)
1299  assert(idx!=PIN_BLUETOOTH_RX&&idx!=PIN_BLUETOOTH_TX);
1300  #endif
1301  }
1302 
1303  #if EBOARD_COPY_AND_PASTE > 0x0
1304  #if EBOARD_CHECK_PINS_PWM > 0x0
1305 
1307 
1309  optVAL_t count; //dont't want to overuse global space^^
1310  for (count = 0; x; count++)
1311  x &= x - 1;
1312  return count;
1313  }
1314 
1315  #endif
1316  #if EBOARD_CHECK_PINS > 0x0
1317 
1318  #if defined(__AVR_ATmega328P__) && not defined(__AVR_ATmega2560__)
1319  uint16_t pin_out = 0x0;
1320  #elif defined(__AVR_ATmega2560__)
1321  uint64_t pin_out = 0x0;
1322  #endif
1323 
1324  #if defined(__AVR_ATmega328P__) && not defined(__AVR_ATmega2560__)
1325  uint16_t pin_in = 0x0;
1326  #elif defined(__AVR_ATmega2560__)
1327  uint64_t pin_in = 0x0;
1328  #endif
1329 
1330  inline bool checkPin(optVAL_t idx, optVAL_t mode = OUTPUT);
1331 
1332  inline bool checkPin(optVAL_t idx, optVAL_t mode){
1333  checkIdx(idx);
1334  return (mode == OUTPUT)? ((pin_out & (1<<idx))>0x0):((pin_in & (1<<idx))>0x0);
1335  }
1336 
1337  #endif
1338 
1339  void setPin(optVAL_t idx, optVAL_t mode = OUTPUT);
1340 
1341  void setPin(optVAL_t idx, optVAL_t mode){
1342  #if EBOARD_CHECK_PINS > 0x0
1343  checkIdx(idx);
1344  if(mode==OUTPUT) { //possible to read from OUTPUT digital ... we won't do it
1345  pin_out |= (1<<idx);
1346  pin_in &= ~(1<<idx);
1347  }
1348  else {
1349  pin_in |= (1<<idx);
1350  pin_out &= ~(1<<idx);
1351  }
1352  #endif
1353  pinMode(idx, mode);
1354  }
1355 
1356  #endif
1357  #if EBOARD_BLUETOOTH > 0x0
1358 
1359  inline char readVal(char oF = '.');
1360 
1361  inline bool checkOverflow(void);
1362 
1363  template <typename T>
1364  inline void writeVal(const T& val);
1365 
1366  inline bool isConnected(void);
1367 
1368  inline bool checkOverflow(void) {
1369  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
1370  return false; //there is no hardware provided control for hardwareserial overflow
1371  #else
1372  return (_serial.overflow());
1373  #endif
1374  }
1375  inline char readVal(char oF) {
1376  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
1377  return ((Serial1.available())?(Serial1.read()):(oF));
1378  #else
1379  return ((_serial.available())?(_serial.read()):(oF));
1380  #endif
1381  }
1382  template<typename T>
1383  inline void writeVal(const T& val){
1384  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
1385  Serial1.write(val);
1386  #else
1387  _serial.write(val);
1388  #endif
1389  }
1390  inline bool isConnected(void) {
1391  #if PIN_BLUETOOTH_RX != PIN_BLUETOOTH_STATE
1392  return digitalRead(PIN_BLUETOOTH_STATE);
1393  #else
1394  return true;
1395  #endif
1396  }
1397 
1398  #endif
1399  #if EBOARD_SHIFT_REGISTER > 0x0
1400 
1401  long store_bits = 0L;
1402 
1403  inline void shiftSingle(optVAL_t idx, bool val);
1404 
1405  void shiftAll(void);
1406 
1407  inline void shiftSingle(optVAL_t idx, bool val) {
1408  bitWrite(store_bits,idx,val);
1409  shiftAll();
1410  }
1411  void shiftAll(void){
1412  digitalWrite(PIN_SHIFT_LAT,LOW);
1413  for(optVAL_t c = 0; (c<32 && !STOP); c++){
1414  digitalWrite(PIN_SHIFT_CLK,LOW);
1415  shiftOut(PIN_SHIFT_DAT,PIN_SHIFT_CLK,MSBFIRST,bitRead(store_bits,c));
1416  }
1417  digitalWrite(PIN_SHIFT_LAT,LOW);
1418  }
1419 
1420  #endif
1421 
1423 
1424  inline void writePWM (optVAL_t val);
1425 
1426  inline void writePWM(optVAL_t val){
1427  val = min(val,0xFF); val = max(0x0,val);
1428  _pwmValue = val;
1429  }
1430  #ifdef REPT_TASK
1431  extern void rept_task(void);
1432  #endif
1433 
1434 
1435  inline void writePin(optVAL_t idx,bool val);
1436 
1437  inline void writePin(optVAL_t idx,bool val){
1438  #if EBOARD_SHIFT_REGISTER > 0x0
1439  if(idx>0x63) {
1440  idx -= 0x64;
1441  shiftSingle(idx,val);
1442  return;
1443  }
1444  #endif
1445  #if EBOARD_CHECK_PINS > 0x0
1446  checkIdx(idx);
1447  if(!checkPin(idx))
1448  #endif
1449  #if EBOARD_COPY_AND_PASTE > 0x0
1450  setPin(idx);
1451  #else
1452  pinMode(idx,OUTPUT);
1453  #endif
1454  digitalWrite(idx,val);
1455  }
1456 
1457 
1458  inline optVAL_t readPin(optVAL_t idx,bool dig = true);
1459 
1460  inline optVAL_t readPin(optVAL_t idx,bool dig){
1461  #if EBOARD_CHECK_PINS > 0x0
1462  if(dig) checkIdx(idx);
1463  #if defined (__AVR_ATmega2560__)
1464  else if (idx<0||idx>0xF){ //use I2C? change => Wire
1465  #else
1466  else if (idx<0||idx>0x7){ //use I2C? change => Wire
1467  #endif
1468  #if EBOARD_DEBUG_MODE > 0x0
1469  assert(false);
1470  #endif
1471  return 0;
1472  }
1473  if(dig && !checkPin(idx,INPUT))
1474  #endif
1475  #if EBOARD_COPY_AND_PASTE > 0x0
1476  setPin(idx,INPUT);
1477  #else
1478  pinMode(idx,INPUT);
1479  #endif
1480  return((dig)? digitalRead(idx) : analogRead(idx));
1481  }
1482 
1483  #if EBOARD_USE_SPI > 0x0 && (EBOARD_NANO == 0x0)
1484 
1485  //won't be commented
1486  struct ServoCds55 {
1487  public:
1488  #if defined(__AVR_ATmega2560__)
1489  ServoCds55(int CS=53);
1490  #else
1491  ServoCds55(int CS=10);
1492  #endif
1493  void begin();
1494  void WritePos(int ID,int Pos);
1495  void write(int ID,int Pos);
1496  inline void setVelocity(int velocity);
1497  inline void setPoslimit(int posLimit);
1498  void rotate(int ID,int velocity);
1499  void SetServoLimit(int ID,int upperLimit);
1500  void SetMotormode(int ID, int velocity);
1501  void SetID(int ID, int newID);
1502  void Reset(int ID);
1503  byte sendWait (const byte what);
1506  int cs;
1507  };
1508  ServoCds55::ServoCds55 (int CS):cs(CS) {
1509  velocity_temp = 150;
1510  upperLimit_temp = 300;
1511  }
1513  pinMode(cs,OUTPUT);
1514  digitalWrite(cs,HIGH);
1515  SPI.begin ();
1517  }
1518  byte ServoCds55::sendWait (const byte what) {
1519  byte a = SPI.transfer (what);
1520  delayMicroseconds (20);
1521  return a;
1522  }
1523  void ServoCds55::setVelocity(int velocity){ //set servo velocity
1524  velocity_temp = velocity;
1525  }
1526  void ServoCds55::setPoslimit(int posLimit){ // set servo pos limit
1527  upperLimit_temp = posLimit;
1528  }
1529  void ServoCds55::write(int ID,int Pos){ // Servo Mode
1531  WritePos(ID,Pos);// default velocity:150
1532  }
1533  void ServoCds55::rotate(int ID,int velocity){ // Motor Mode
1534  SetServoLimit(ID,0);
1535  delay(100);
1536  SetMotormode(ID,velocity);
1537  }
1538  void ServoCds55::WritePos(int ID,int Pos){
1539  int PosB = (Pos>>8 & 0xff);//low
1540  int PosS = (Pos & 0xff);//high
1541  int velocityB = (velocity_temp>>8 & 0xff);
1542  int velocityS = (velocity_temp & 0xff);
1543  digitalWrite(cs, LOW);
1544  sendWait ('p'); sendWait (ID);
1545  sendWait (PosB); sendWait (PosS);
1546  sendWait (velocityB); sendWait (velocityS);
1547  sendWait ('\t'); sendWait ('\r'); sendWait ('\n');
1548  digitalWrite(cs, HIGH);
1549  delay(10);
1550  }
1551  void ServoCds55::SetServoLimit(int ID,int upperLimit_temp){
1552  int upperLimitB = (upperLimit_temp>>8 & 0xff);
1553  int upperLimitS = (upperLimit_temp & 0xff);
1554  digitalWrite(cs, LOW);
1555  sendWait ('s'); sendWait (ID);
1556  sendWait (upperLimitB); sendWait (upperLimitS);
1557  sendWait ('\t'); sendWait ('\r'); sendWait ('\n');
1558  digitalWrite(cs, HIGH);
1559  delay(10);
1560  }
1561  void ServoCds55::SetMotormode(int ID, int velocity){
1562  int velocityB = (velocity>>8 & 0xff);
1563  int velocityS = (velocity & 0xff);
1564  digitalWrite(cs, LOW);
1565  sendWait ('m'); sendWait (ID);
1566  sendWait (velocityB); sendWait (velocityS);
1567  sendWait ('\t'); sendWait ('\r'); sendWait ('\n');
1568  digitalWrite(cs, HIGH);
1569  delay(10);
1570  }
1571  void ServoCds55::SetID(int ID, int newID){
1572  digitalWrite(cs, LOW);
1573  sendWait ('i'); sendWait (ID);
1574  sendWait (newID);
1575  sendWait ('\t'); sendWait ('\r'); sendWait ('\n');
1576  digitalWrite(cs, HIGH);
1577  delay(10);
1578  }
1579  void ServoCds55::Reset(int ID){
1580  digitalWrite(cs, LOW);
1581  sendWait ('r'); sendWait (ID);
1582  sendWait ('\t'); sendWait ('\r'); sendWait ('\n');
1583  digitalWrite(cs, HIGH);
1584  delay(10);
1585  }
1586 
1587 
1589  #endif
1590  #if EBOARD_COPY_AND_PASTE > 0x0 && EBOARD_NANO == 0
1591 
1592  struct SoccerBoard {
1593 
1594  inline SoccerBoard(void);
1595  //inline ~SoccerBoard(void) {}
1596  #if EBOARD_USE_UTILITY > 0x0 or defined(__AVR_ATmega2560__) //won't shrink space... just speed things up
1597 
1598  inline void led(int idx,bool state);
1599 
1600  inline void ledOn(int idx);
1601 
1602  inline void ledOff(int idx);
1603 
1604  inline void ledsOff(void);
1605 
1606  inline void ledMeter(int);
1607  #endif
1608  #if EBOARD_USE_UTILITY > 0x0
1609 
1610  inline void button(int);
1611 
1612  inline void waitForButton(int);
1613  #endif
1614 
1615  inline void motor(uint8_t id,int16_t val);
1616 
1617  inline void motorsOff(void);
1618  //ARDUINO UNO PINOUT
1619  //D0,D1 => Bluetooth connection
1620  //D4,D5 => MotorControl (D5: 980Hz)
1621  //D10,D13 => SPI
1622 
1623  inline void power(optVAL_t id, bool state);
1624 
1625  inline void powerOn(optVAL_t id);
1626 
1627  inline void powerOff(optVAL_t id);
1628 
1629  inline void sleep(uint16_t t);
1630 
1631  inline void msleep(uint16_t t);
1632 
1633  inline bool digital (optVAL_t id);
1634 
1635  inline optVAL_t analog (optVAL_t id);
1636 
1637  inline void reset(void);
1638  };
1639 
1641  #if defined(__AVR_ATmega2560__)
1642  inline void SoccerBoard::led(int idx, bool state) {writePin(13,state);}
1643  void SoccerBoard::ledOn(int) {writePin(13,HIGH);}
1644  void SoccerBoard::ledOff(int) {writePin(13,LOW);}
1645  void SoccerBoard::ledsOff(void) {writePin(13,LOW);}
1646  void SoccerBoard::ledMeter(int) {writePin(13,HIGH);}
1647  #elif EBOARD_USE_UTILITY > 0x0
1648  void SoccerBoard::led(int, bool) {}
1649  void SoccerBoard::ledOn(int) {}
1650  void SoccerBoard::ledOff(int) {}
1651  void SoccerBoard::ledsOff(void) {}
1652  void SoccerBoard::ledMeter(int) {}
1653  #endif
1654  #if EBOARD_USE_UTILITY > 0x0
1655  void SoccerBoard::button(int) {}
1657  #endif
1658  void SoccerBoard::motor(uint8_t id,int16_t val) {
1659  if(id==0&&(val>-256 && val < 256)) {setPin(PIN_MOTOR_DIR,val<0); writePWM(abs(val));}
1660  else if(id>0&&id<3&&(val>-0 && val < 1024)) {_servoHandler.write((id-1),(val *600/1023 - 300));}
1661  }
1663  void SoccerBoard::reset(void) {
1664  #if EBOARD_USE_RESET > 0x0
1665  wdt_enable(WDTO_15MS);
1666  while(true) {}
1667  #endif
1668  }
1669  void SoccerBoard::power(optVAL_t id, bool state) {writePin(id,state);}
1670  void SoccerBoard::powerOn(optVAL_t id) {this->power(id,1);}
1671  void SoccerBoard::powerOff(optVAL_t id) {this->power(id,0);}
1672  void SoccerBoard::sleep(uint16_t t) {delay(1000*t);}
1673  void SoccerBoard::msleep(uint16_t t) {delay(t);}
1674  bool SoccerBoard::digital (optVAL_t id) {return readPin(id);}
1676 
1677  //To avoid not_found issues
1678 
1679  #define DIGITAL_IN 0x0
1680 
1681  #define DIGITAL_IN_INV 0x1
1682 
1683  #define DIGITAL_IN_PULLUP 0x2
1684 
1685  #define DIGITAL_IN_PULLUP_INV 0x3
1686 
1687  #define DIGITAL_OUT 0x4
1688 
1689  #define DIGITAL_OUT_INV 0x5
1690 
1691  #define DIGITAL_OUT_LOW 0x6
1692 
1693  #define DIGITAL_OUT_HIGH 0x7
1694 
1695  #define ANALOG_IN_8_BIT 0x8
1696 
1697  #define ANALOG_IN_10_BIT 0x9
1698 
1699  #define ANALOG_IN_MEAN_8_BIT 0xA
1700 
1701  #define ANALOG_IN_MEAN_10_BIT 0xB
1702 
1703  #define COUNTER_8_BIT 0xC
1704 
1705  #define COUNTER_16_BIT 0xD
1706 
1707  #define COUNTER_RISE_8_BIT 0xE
1708 
1709  #define COUNTER_RISE_16_BIT 0xF
1710 
1711  #define PWM_SLOW 0x8
1712 
1713  #define PWM_FAST 0x9
1714 
1715  #define FREQ_LOW 0xA
1716 
1717  #define FREQ_HIGH 0xB
1718 
1719  #define COUNTER_B_DIR 0xC
1720 
1721  #define COUNTER_B_DIR_PULLUP 0xD
1722 
1723  #define COUNTER_MEAN_8_BIT 0xE
1724 
1725  #define COUNTER_MEAN_16_BIT 0xF
1726 
1727  struct I2CInOut{
1728 
1730  #if EBOARD_USE_UTILITY > 0x0
1731 
1732  inline void read(void);
1733 
1734  inline void changeAddress(optVAL_t);
1735 
1736  inline void changeModes(optVAL_t,optVAL_t,optVAL_t);
1737  #endif
1738 
1739  inline void write(void);
1740 
1741  optVAL_t A; //if you've used uint16_t values you'll have to replace it here
1742  //we only have B - DiOut and C - AO [OUT]
1743 
1745 
1747  };
1748 
1750  this->A=0x0;this->B=0x0;this->C=0x0;
1751  }
1752  #if EBOARD_USE_UTILITY > 0x0
1753  void I2CInOut::read(void) {}
1754  void I2CInOut::changeAddress(optVAL_t){}
1756  #endif
1757  void I2CInOut::write(void){
1758  setPin(PIN_MOTOR_DIR,((this->B)!=0x0));
1759  writePWM(this->C);
1760  }
1761 
1762 
1763  struct DynamixelBoard;
1764 
1765 
1766  struct AX12Servo {
1767 
1768  AX12Servo(void);
1769 
1770  AX12Servo(DynamixelBoard &dBoard, optVAL_t servoID); //if borders => setPosLimit
1772  #if EBOARD_USE_UTILITY > 0x0
1773 
1774  inline void setID(optVAL_t newID);
1775 
1776  inline void changeMotorID(optVAL_t newID); //this should change the hardwareaddress...
1777 
1778  inline void setPositionMode(void);
1779 
1780  inline void setSpeedMode(void);
1781 
1782  inline void setSpeed(optVAL_t);
1783 
1784  inline void ledOff(void);
1785 
1786  inline void ledOn(void);
1787 
1788  inline void setTorque(uint16_t);
1789  #endif
1790 
1791  void setPosition(int pos, int speed=0x3FF);
1792 
1793  inline void storePosition(int pos, int speed = 0x3FF);
1794 
1795  inline optVAL_t getPosition(void);
1796 
1797  inline bool isMoving(void);
1798 
1800 
1802  //bool posMode; //we don't care wich mode we are in ^^
1803 
1805  private:
1806 
1807  int actPos;
1808 
1809  int actSpe;
1810  }; //shield //set limits auto register for begin
1811 
1813  #if EBOARD_USE_UTILITY > 0x0
1814  void AX12Servo::setID(optVAL_t newID) {this->id = newID;_servoHandler.SetServoLimit(this->id,_servoHandler.upperLimit_temp);}
1815  void AX12Servo::changeMotorID(optVAL_t newID) {this->id = newID;} //this should change the hardwareaddress...
1816  //IF needed: _servoHandler.setID(this->id, newID);
1819  void AX12Servo::setSpeed(optVAL_t) {} //i won't use the rotate functions...
1820  void AX12Servo::ledOff(void) {} //noone needs the AX12-Servo LED
1821  void AX12Servo::ledOn(void) {} //really.... noone ^^
1822  void AX12Servo::setTorque(uint16_t) {} //which damn register? xD
1823  #endif
1824  void AX12Servo::setPosition(int pos, int speed) {
1825  #if EBOARD_CLAMP > 0x0
1826  if(pos>1023 || speed > 1023) return;
1827  this->actPos=pos; this->storedPos=pos; this->storedSpe = speed;
1828  speed = speed*600/1023 - 300;
1829  pos = pos *600/1023 - 300;
1830  #else
1831  if(pos>300 || speed > 300) return;
1832  this->actPos=pos; this->storedPos=pos; this->storedSpe = speed;
1833  #endif
1834  if(speed != actSpe){ _servoHandler.setVelocity(speed); this->actSpe=speed;}
1835  _servoHandler.write(this->id,pos);
1836  }
1838  return this->actPos; //when moving... false value;
1839  }
1840  bool AX12Servo::isMoving(void) {return false;} //we don't know^^
1841 
1842 
1844 
1845  inline DynamixelBoard(SoccerBoard&);
1846  //inline ~DynamixelBoard(void) {}
1847  #if EBOARD_USE_UTILITY > 0x0
1848 
1849  inline void changeId(optVAL_t);
1850 
1851  inline void changeMotorID(optVAL_t);
1852 
1853  inline void ledOn(optVAL_t);
1854 
1855  inline void ledOff(optVAL_t);
1856  #endif
1857 
1858  inline void action(void);
1859 
1860  friend struct AX12Servo;
1861  protected:
1862 
1864  };
1865 
1867  for(optVAL_t i = 0; i < EBOARD_SPI_SERVO_MAX; i++ ) {this->connected[i] = NULL;} //wanna use nullptr... wanna have c++11^^
1868  }
1869  //inline ~DynamixelBoard(void) {}
1870  #if EBOARD_USE_UTILITY > 0x0
1875  #endif
1877  for(optVAL_t i = 0; (i < EBOARD_SPI_SERVO_MAX && !STOP); i++ ){
1878  if(this->connected[i] != NULL)
1879  (*connected[i]).setPosition((*connected[i]).storedPos,(*connected[i]).storedSpe);
1880  }
1881  }
1882  void AX12Servo::storePosition(int pos, int speed){
1883  if(this->id < EBOARD_SPI_SERVO_MAX) _conBoard->connected[this->id] = this;
1884  this->storedPos=pos;this->storedSpe=speed;
1885  }
1887  //#if EBOARD_DEBUG_MODE > 0x0
1888  // assert(servoID<EBOARD_SPI_SERVO_MAX);
1889  //#endif
1890  }
1891 
1892  #endif
1893  #if EBOARD_BLUETOOTH > 0x0
1894 
1895  struct RB14Scan {
1896 
1897  inline RB14Scan(void);
1898 
1899 
1900  inline int raw(optVAL_t);
1901 
1902 
1903  inline char channel(optVAL_t);
1904 
1905  inline void write(const char* const val);
1906  };
1907 
1908  inline RB14Scan::RB14Scan(void) {}
1909  inline int RB14Scan::raw(optVAL_t) {return isConnected();}
1910  inline char RB14Scan::channel(optVAL_t) {return ((isConnected())?(readVal()):(-1));}
1911  inline void RB14Scan::write(const char* const val) {writeVal(val);}
1912 
1913 
1914  #endif
1915 #if EBOARD_I2C > 0x0
1916 
1917  inline optVAL_t sendI2C(optVAL_t deviceID,byte *buf, byte buf_len);
1918 
1919  inline optVAL_t sendI2C(optVAL_t deviceID, byte buf);
1920 
1921  inline void pingI2C(optVAL_t ret[], optVAL_t ret_len);
1922 
1923  inline void pingI2C(optVAL_t ret[], optVAL_t ret_len){
1924  optVAL_t count = 0;
1925  for (byte i = 1; (i < 255 && !STOP); i++) {
1926  if(i==200)continue; //internal
1927  Wire.beginTransmission (i);
1928  if (Wire.endTransmission () == 0) {
1929  if(count < ret_len) ret[count] = i;
1930  count++;
1931  delay (1);
1932  }
1933  }
1934  }
1935  inline optVAL_t sendI2C(optVAL_t deviceID,byte *buf, byte buf_len) {
1936  Wire.beginTransmission(deviceID);
1937  Wire.write(buf,buf_len);
1938  return Wire.endTransmission();
1939  }
1940  inline optVAL_t sendI2C(optVAL_t deviceID, byte buf){
1941  Wire.beginTransmission(deviceID);
1942  Wire.write(buf);
1943  return Wire.endTransmission();
1944  }
1945 
1946 
1947  inline void readI2C(optVAL_t deviceID, optVAL_t ret[], optVAL_t ret_len,bool blocking=true);
1948 
1949  inline void readI2C(optVAL_t deviceID,optVAL_t ret[] , optVAL_t ret_len,bool blocking) {
1950  for(optVAL_t rect = 0x0; (Wire.available() || (((blocking && (rect < ret_len))) && (!STOP))); rect++)
1951  ret[rect] = Wire.read();
1952  }
1953 
1954  //Beginof LCD configuration
1955  #if EBOARD_LCD > 0x0
1956  PROGMEM const byte basicFont[][8] = {
1957  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
1958  {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
1959  {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
1960  {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
1961  {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
1962  {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
1963  {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
1964  {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
1965  {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
1966  {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
1967  {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
1968  {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
1969  {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
1970  {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
1971  {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
1972  {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
1973  {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
1974  {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
1975  {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
1976  {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
1977  {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
1978  {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
1979  {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
1980  {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
1981  {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
1982  {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
1983  {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
1984  {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
1985  {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
1986  {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
1987  {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
1988  {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
1989  {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
1990  {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
1991  {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
1992  {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
1993  {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
1994  {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
1995  {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
1996  {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
1997  {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
1998  {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
1999  {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
2000  {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
2001  {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
2002  {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
2003  {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
2004  {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
2005  {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
2006  {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
2007  {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
2008  {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
2009  {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
2010  {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
2011  {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
2012  {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
2013  {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
2014  {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
2015  {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
2016  {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
2017  {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
2018  {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
2019  {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
2020  {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
2021  {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
2022  {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
2023  {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
2024  {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
2025  {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
2026  {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
2027  {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
2028  {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
2029  {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
2030  {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
2031  {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
2032  {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
2033  {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
2034  {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
2035  {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
2036  {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
2037  {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
2038  {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
2039  {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
2040  {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
2041  {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
2042  {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
2043  {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
2044  {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
2045  {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
2046  {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
2047  {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
2048  {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
2049  {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
2050  {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
2051  {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
2052  {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
2053  };
2054 
2055  //Definition of OLED Constants
2056 
2057  #define LCD_COMMAND_MODE 0x80
2058 
2059  #define LCD_DATA_MODE 0x40
2060 
2061  #define LCD_COMMAND_DISPLAY_OFF 0xAE
2062 
2063  #define LCD_COMMAND_DISPLAY_ON 0xAF
2064 
2065  #define LCD_COMMAND_BLACK_BACKGROUND 0xA6
2066 
2067  #define LCD_COMMAND_WHITE_BACKGROUND 0xA7
2068 
2069  #define LCD_COMMAND_SET_BRIGHTNESS 0x81
2070 
2071  #define LCD_PAGE_ADDRESSING 0x02
2072 
2073  #define LCD_HORIZONTAL_ADDRESSING 0x00
2074  //The regulator
2075 
2076  #define LCD_COMMAND_CHARGE_PUMP_SETTING 0x8d
2077 
2078  #define LCD_COMMAND_CHARGE_PUMP_ENABLE 0x14
2079  #ifndef LCD_WIDTH
2080 
2081  #define LCD_WIDTH 128
2082  #endif
2083  #ifndef LCD_HEIGHT
2084 
2085  #define LCD_HEIGHT 64
2086  #endif
2087 
2088  struct LCD {
2089  #if EBOARD_NANO == 0
2090 
2091  LCD(SoccerBoard &soccerBoard, optVAL_t id=0x3C);
2092  #else
2093  LCD(optVAL_t id=0x3C);
2094  #endif
2095 
2096  inline bool changeID(optVAL_t newID = 0x3C);
2097 
2098  inline bool clear(void);
2099 
2100  inline void print(const char* data);
2101 
2102  inline void print(int data);
2103 
2104  inline void print(optVAL_t line, optVAL_t col, const char* data);
2105 
2106  inline void print(optVAL_t line, optVAL_t col, int data);
2107 
2108  inline void lightOn(void);
2109 
2110  inline void lightOff(void);
2111 
2112  inline bool reset(void);
2113  //added features
2114 
2115  inline bool init(void);
2116 
2117  inline void drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY);
2118 
2119  inline void changeMode(bool newMode = true);
2120 
2121  inline bool setCursor(byte posX = 0x0, byte posY = 0x0);
2122 
2123  inline bool changeBrightness (byte val = 0x64);
2124 
2125  inline void changeBackground(bool newBackground = false);
2126 
2128  private:
2129 
2130 
2131  byte pX;
2132 
2133  byte pY;
2134 
2135  bool _cI;
2136 
2137  inline void s2Cmd(optVAL_t o, optVAL_t t);
2138 
2139  inline bool s1Cmd(optVAL_t o);
2140 
2141  inline void s1Dat(optVAL_t o);
2142  };
2143 
2144  #if EBOARD_NANO == 0x0
2145  LCD::LCD(SoccerBoard &soccerBoard, optVAL_t id) {
2146  this->_cI = false;
2147  this->ID = id;
2148  //this->init();
2149  }
2150  #else
2151  LCD::LCD( optVAL_t id) {
2152  this->_cI = false;
2153  this->ID = id;
2154  //this->init();
2155  }
2156  #endif
2157  inline bool LCD::changeID(optVAL_t newID) {
2158  this->ID = newID;
2159  return this->init();
2160  }
2161  inline bool LCD::clear(void) {
2162  if(!this->_cI) this->init();
2163  for(byte i = 0; i < 8; i++){
2164  //maybe *8
2165  setCursor(0,i);
2166  for (byte j = 0; j < 128; j++)
2167  this->s1Dat(0);
2168  }
2169  return setCursor(0,0);
2170  }
2171  void LCD::print(optVAL_t line, optVAL_t col, const char *data) {
2172  if(!this->_cI) this->init();
2173  byte i = 0x0;
2174  if(col < ((LCD_WIDTH-1)/8.0) && line < ((LCD_HEIGHT-1)/8.0)) {
2175  setCursor(col,line);
2176  }
2177  while(data[i] && (pX*8) < LCD_WIDTH){
2178  //Serial.print(data[i]); Serial.print(" ");
2179  //Serial.print(i); Serial.print(" "); Serial.print(pX); Serial.print(" ");
2180  //Serial.println(this->pY);
2181  if(data[i] == '\n' || this->pX >= LCD_WIDTH) {
2182  setCursor(0,(pY+1));
2183  } else if (this->pY >= LCD_HEIGHT){
2184  setCursor(0,0);
2185  }
2186  if(data[i] < 32 || data[i] > 127){ i++; continue;}
2187  for (byte j = 0; j < 8; j++){
2188  this->s1Dat(pgm_read_byte(&basicFont[data[i]-32][j]));
2189  }
2190  i++;this->pX++;
2191  }
2192  }
2193  void LCD::print(optVAL_t line, optVAL_t col, int data){
2194  char buffer[11] = "";
2195  itoa(data,buffer,10);
2196  this->print(line,col,buffer);
2197  }
2198  inline void LCD::lightOn(void) {
2199  this->changeBrightness(255);
2200  }
2201  inline void LCD::lightOff(void) {
2202  this->changeBrightness(0);
2203  }
2204  inline bool LCD::reset(void) {
2205  return this->clear();
2206  }
2207  inline void LCD::print(int data) {this->print(255,255,data);}
2208  inline void LCD::print(const char* data) {this->print(255,255,data);}
2209  inline bool LCD::init() {
2210  #ifdef HIGHSPEED
2211  TWBR = 0xC;
2212  #endif
2213  this->_cI = true;
2215  this->changeMode(false);
2216  this->changeBackground(false);
2217  this->changeBrightness(255);
2218  this->s2Cmd(0x20,LCD_PAGE_ADDRESSING);
2219  this->changeMode(true);
2220  //this->print("eBoard \n written by \n EagleoutIce");
2221  return this->clear();
2222  }
2223  inline void LCD::drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY){
2224  if(!this->_cI) this->init();
2225  setCursor(posX,posY);
2226  byte col = 0x0;
2227  for(int i = 0x0; i < (hiX * 8 * hiY); i++){
2228  this->s1Dat(pgm_read_byte(&bitmap[i]));
2229  if(++col == (hiX * 8)) {
2230  col = 0x0;
2231  setCursor(posX,++posY);
2232  }
2233  }
2234  }
2235  inline void LCD::changeMode(bool newMode) {
2236  if(!this->_cI) this->init();
2237  if(newMode) this->s1Cmd(LCD_COMMAND_DISPLAY_ON);
2238  else this->s1Cmd(LCD_COMMAND_DISPLAY_OFF);
2239  }
2240  inline bool LCD::setCursor(byte posX, byte posY) {
2241  if(!this->_cI) this->init();
2242  this->s2Cmd((0x00 + (8 *posX & 0x0F)),(0x10 + ((8 * posX >> 4) & 0x0F))); //lower and higher address
2243  this->pX = posX; this->pY = posY;
2244  return this->s1Cmd(0xB0 + posY);
2245  }
2246  inline bool LCD::changeBrightness(byte val) {
2247  if(!this->_cI) this->init();
2248  this->s2Cmd(0x81,val); //brightness mode
2249  Wire.beginTransmission(this->ID);
2250  return (Wire.endTransmission() == 0);
2251  }
2252  inline void LCD::changeBackground(bool newBackground) {
2253  if(!this->_cI) this->init();
2254  if(newBackground) this->s1Cmd(LCD_COMMAND_WHITE_BACKGROUND);
2255  else this->s1Cmd(LCD_COMMAND_BLACK_BACKGROUND);
2256  }
2257  inline void LCD::s2Cmd(optVAL_t o, optVAL_t t){
2258  if(!this->_cI) this->init();
2259  this->s1Cmd(o); this->s1Cmd(t);
2260  }
2261  inline bool LCD::s1Cmd(optVAL_t C) {
2262  if(!this->_cI) this->init();
2263  Wire.beginTransmission(this->ID);
2264  Wire.write(LCD_COMMAND_MODE); Wire.write(C);
2265  return (Wire.endTransmission()==0);
2266  }
2267  inline void LCD::s1Dat(optVAL_t o){
2268  if(!this->_cI) this->init();
2269  Wire.beginTransmission(this->ID);
2270  Wire.write(LCD_DATA_MODE); Wire.write(o);
2272  }
2273 
2274  #endif
2275  #endif
2276  #if EBOARD_NEO > 0x0
2277  // Codesection based on official NeoPixel library
2278  // RGB NeoPixel permutations; white and red offsets are always same
2279  // Offset: W R G B
2280 
2281  #define EBOARD_NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2))
2282 
2283  #define EBOARD_NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1))
2284 
2285  #define EBOARD_NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2))
2286 
2287  #define EBOARD_NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1))
2288 
2289  #define EBOARD_NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0))
2290 
2291  #define EBOARD_NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0))
2292  // RGBW NeoPixel permutations; all 4 offsets are distinct
2293  // Offset: W R G B
2294 
2295  #define EBOARD_NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3))
2296 
2297  #define EBOARD_NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2))
2298 
2299  #define EBOARD_NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3))
2300 
2301  #define EBOARD_NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2))
2302 
2303  #define EBOARD_NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1))
2304 
2305  #define EBOARD_NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1))
2306 
2307  #define EBOARD_NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3))
2308 
2309  #define EBOARD_NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2))
2310 
2311  #define EBOARD_NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3))
2312 
2313  #define EBOARD_NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2))
2314 
2315  #define EBOARD_NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1))
2316 
2317  #define EBOARD_NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1))
2318 
2319  #define EBOARD_NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3))
2320 
2321  #define EBOARD_NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2))
2322 
2323  #define EBOARD_NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3))
2324 
2325  #define EBOARD_NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2))
2326 
2327  #define EBOARD_NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1))
2328 
2329  #define EBOARD_NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1))
2330 
2331  #define EBOARD_NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0))
2332 
2333  #define EBOARD_NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0))
2334 
2335  #define EBOARD_NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0))
2336 
2337  #define EBOARD_NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0))
2338 
2339  #define EBOARD_NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0))
2340 
2341  #define EBOARD_NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0))
2342 
2343  #define EBOARD_NEO_800KHZ 0x0000
2344 
2345  #define EBOARD_NEO_400KHZ 0x0100
2346  // uint16_t can be uint8_t in 800Khz mode ^^
2347 
2348  struct NeoPixel{
2349 
2350  NeoPixel(uint16_t n, uint8_t p = 6, uint16_t t = EBOARD_NEO_GRB + EBOARD_NEO_800KHZ);
2351 
2352  NeoPixel(void);
2353 
2354  ~NeoPixel(void);
2355 
2356  void begin(void);
2357 
2358  void show(void);
2359 
2360  void setPin(uint8_t p);
2361 
2362  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
2363 
2364  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
2365 
2366  void setPixelColor(uint16_t n, uint32_t c);
2367 
2368  void setBrightness(uint8_t val);
2369 
2370  void clear(void);
2371 
2372  void updateLength(uint16_t n);
2373 
2374  void updateType(uint16_t t);
2375 
2376  inline uint8_t *getPixels(void) const;
2377 
2378  inline uint8_t getBrightness(void) const;
2379 
2380  uint8_t sine8(uint8_t x) const;
2381 
2382  uint8_t gamma8(uint8_t x) const;
2383 
2384  inline int8_t getPin(void);
2385 
2386  inline uint16_t numPixels(void) const;
2387 
2388  static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b);
2389 
2390  static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w);
2391 
2392  uint32_t getPixelColor(uint16_t n) const;
2393 
2394  inline bool canShow(void);
2395  protected:
2396 
2397  bool is800KHz;
2398 
2399  bool begun;
2400 
2401  uint16_t numLEDs; //maybe shorten with PrepConst 'extendetLED'?
2402 
2403  uint16_t numBytes;
2404 
2405  int8_t pin;
2406 
2407  uint8_t brightness;
2408 
2409  uint8_t *pixels;
2410 
2411  uint8_t aOffset[4];
2412 
2413  uint32_t endTime; //used for diff calc
2414  #ifdef __AVR__ //not needed (rem?)
2415 
2416  volatile uint8_t *port;// Output PORT register
2417 
2418  uint8_t pinMask; // Output PORT bitmask
2419  #endif
2420  };
2421 
2422  NeoPixel::NeoPixel(uint16_t n, uint8_t p, uint16_t t) :
2423  begun(false), brightness(0), pixels(NULL), endTime(0) {
2424  updateType(t);
2425  updateLength(n);
2426  setPin(p);
2427  }
2428  inline bool NeoPixel::canShow(void) { return (micros() - endTime) >= 300L; }
2430  is800KHz(true),
2431  begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0), pixels(NULL),
2432  endTime(0)
2433  {aOffset[0]=1;aOffset[1]=0;aOffset[2]=2;aOffset[3]=1;}
2435  if(pixels) free(pixels);
2436  if(pin >= 0) pinMode(pin, INPUT);
2437  }
2438  void NeoPixel::begin(void) {
2439  if(pin >= 0) {
2440  pinMode(pin, OUTPUT);
2441  digitalWrite(pin, LOW);
2442  }
2443  begun = true;
2444  }
2445  void NeoPixel::updateLength(uint16_t n) {
2446  if(pixels) free(pixels);
2447  numBytes = n * ((aOffset[3] == aOffset[0]) ? 3 : 4);
2448  if((pixels = (uint8_t *)malloc(numBytes))) {
2449  memset(pixels, 0, numBytes);
2450  numLEDs = n;
2451  } else {
2452  numLEDs = numBytes = 0;
2453  }
2454  }
2455  void NeoPixel::updateType(uint16_t t) {
2456  boolean oldThreeBytesPerPixel = (aOffset[3] == aOffset[0]); // false if RGBW
2457  aOffset[3] = (t >> 6) & 0b11;
2458  aOffset[0] = (t >> 4) & 0b11;
2459  aOffset[1] = (t >> 2) & 0b11;
2460  aOffset[2] = t & 0b11;
2461  is800KHz = (t < 256); // 400 KHz flag is 1<<8
2462  if(pixels) {
2463  boolean newThreeBytesPerPixel = (aOffset[3] == aOffset[0]);
2464  if(newThreeBytesPerPixel != oldThreeBytesPerPixel) updateLength(numLEDs);
2465  }
2466  }
2467  #if defined(ESP8266)
2468  // ESP8266 show() is external to enforce ICACHE_RAM_ATTR execution
2469  extern "C" void ICACHE_RAM_ATTR espShow(
2470  uint8_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
2471  #elif defined(ESP32)
2472  extern "C" void espShow(
2473  uint8_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
2474  #endif
2475  void NeoPixel::show(void) {
2476  if(!pixels) return;
2477  while(!canShow()); //maybe timeout ?
2478  noInterrupts(); // Need 100% focus on instruction timing
2479  #ifdef __AVR__
2480  volatile uint16_t
2481  i = numBytes;
2482  volatile uint8_t
2483  *ptr = pixels,
2484  b = *ptr++,
2485  hi,
2486  lo;
2487  #if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL)
2488  if(is800KHz) {
2489  volatile uint8_t n1, n2 = 0;
2490  #if defined(PORTD)
2491  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
2492  if(port == &PORTD) {
2493  #endif
2494  hi = PORTD | pinMask;
2495  lo = PORTD & ~pinMask;
2496  n1 = lo;
2497  if(b & 0x80) n1 = hi;
2498  asm volatile(
2499  "headD:" "\n\t" // Clk Pseudocode
2500  // Bit 7:
2501  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2502  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
2503  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
2504  "rjmp .+0" "\n\t" // 2 nop nop
2505  "sbrc %[byte] , 6" "\n\t" // 1-2 if(b & 0x40)
2506  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
2507  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2508  "rjmp .+0" "\n\t" // 2 nop nop
2509  // Bit 6:
2510  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2511  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
2512  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
2513  "rjmp .+0" "\n\t" // 2 nop nop
2514  "sbrc %[byte] , 5" "\n\t" // 1-2 if(b & 0x20)
2515  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
2516  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2517  "rjmp .+0" "\n\t" // 2 nop nop
2518  // Bit 5:
2519  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2520  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
2521  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
2522  "rjmp .+0" "\n\t" // 2 nop nop
2523  "sbrc %[byte] , 4" "\n\t" // 1-2 if(b & 0x10)
2524  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
2525  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2526  "rjmp .+0" "\n\t" // 2 nop nop
2527  // Bit 4:
2528  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2529  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
2530  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
2531  "rjmp .+0" "\n\t" // 2 nop nop
2532  "sbrc %[byte] , 3" "\n\t" // 1-2 if(b & 0x08)
2533  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
2534  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2535  "rjmp .+0" "\n\t" // 2 nop nop
2536  // Bit 3:
2537  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2538  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
2539  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
2540  "rjmp .+0" "\n\t" // 2 nop nop
2541  "sbrc %[byte] , 2" "\n\t" // 1-2 if(b & 0x04)
2542  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
2543  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2544  "rjmp .+0" "\n\t" // 2 nop nop
2545  // Bit 2:
2546  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2547  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
2548  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
2549  "rjmp .+0" "\n\t" // 2 nop nop
2550  "sbrc %[byte] , 1" "\n\t" // 1-2 if(b & 0x02)
2551  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
2552  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2553  "rjmp .+0" "\n\t" // 2 nop nop
2554  // Bit 1:
2555  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2556  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
2557  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
2558  "rjmp .+0" "\n\t" // 2 nop nop
2559  "sbrc %[byte] , 0" "\n\t" // 1-2 if(b & 0x01)
2560  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
2561  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2562  "sbiw %[count], 1" "\n\t" // 2 i-- (don't act on Z flag yet)
2563  // Bit 0:
2564  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
2565  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
2566  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
2567  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++
2568  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 0x80)
2569  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
2570  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
2571  "brne headD" "\n" // 2 while(i) (Z flag set above)
2572  : [byte] "+r" (b),
2573  [n1] "+r" (n1),
2574  [n2] "+r" (n2),
2575  [count] "+w" (i)
2576  : [port] "I" (_SFR_IO_ADDR(PORTD)),
2577  [ptr] "e" (ptr),
2578  [hi] "r" (hi),
2579  [lo] "r" (lo));
2580  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
2581  } else
2582  #endif
2583  #endif
2584  #if defined(PORTB)
2585  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
2586  if(port == &PORTB) {
2587  #endif // defined(PORTD/C/F)
2588  hi = PORTB | pinMask;
2589  lo = PORTB & ~pinMask;
2590  n1 = lo;
2591  if(b & 0x80) n1 = hi;
2592  asm volatile(
2593  "headB:" "\n\t"
2594  "out %[port] , %[hi]" "\n\t"
2595  "mov %[n2] , %[lo]" "\n\t"
2596  "out %[port] , %[n1]" "\n\t"
2597  "rjmp .+0" "\n\t"
2598  "sbrc %[byte] , 6" "\n\t"
2599  "mov %[n2] , %[hi]" "\n\t"
2600  "out %[port] , %[lo]" "\n\t"
2601  "rjmp .+0" "\n\t"
2602  "out %[port] , %[hi]" "\n\t"
2603  "mov %[n1] , %[lo]" "\n\t"
2604  "out %[port] , %[n2]" "\n\t"
2605  "rjmp .+0" "\n\t"
2606  "sbrc %[byte] , 5" "\n\t"
2607  "mov %[n1] , %[hi]" "\n\t"
2608  "out %[port] , %[lo]" "\n\t"
2609  "rjmp .+0" "\n\t"
2610  "out %[port] , %[hi]" "\n\t"
2611  "mov %[n2] , %[lo]" "\n\t"
2612  "out %[port] , %[n1]" "\n\t"
2613  "rjmp .+0" "\n\t"
2614  "sbrc %[byte] , 4" "\n\t"
2615  "mov %[n2] , %[hi]" "\n\t"
2616  "out %[port] , %[lo]" "\n\t"
2617  "rjmp .+0" "\n\t"
2618  "out %[port] , %[hi]" "\n\t"
2619  "mov %[n1] , %[lo]" "\n\t"
2620  "out %[port] , %[n2]" "\n\t"
2621  "rjmp .+0" "\n\t"
2622  "sbrc %[byte] , 3" "\n\t"
2623  "mov %[n1] , %[hi]" "\n\t"
2624  "out %[port] , %[lo]" "\n\t"
2625  "rjmp .+0" "\n\t"
2626  "out %[port] , %[hi]" "\n\t"
2627  "mov %[n2] , %[lo]" "\n\t"
2628  "out %[port] , %[n1]" "\n\t"
2629  "rjmp .+0" "\n\t"
2630  "sbrc %[byte] , 2" "\n\t"
2631  "mov %[n2] , %[hi]" "\n\t"
2632  "out %[port] , %[lo]" "\n\t"
2633  "rjmp .+0" "\n\t"
2634  "out %[port] , %[hi]" "\n\t"
2635  "mov %[n1] , %[lo]" "\n\t"
2636  "out %[port] , %[n2]" "\n\t"
2637  "rjmp .+0" "\n\t"
2638  "sbrc %[byte] , 1" "\n\t"
2639  "mov %[n1] , %[hi]" "\n\t"
2640  "out %[port] , %[lo]" "\n\t"
2641  "rjmp .+0" "\n\t"
2642  "out %[port] , %[hi]" "\n\t"
2643  "mov %[n2] , %[lo]" "\n\t"
2644  "out %[port] , %[n1]" "\n\t"
2645  "rjmp .+0" "\n\t"
2646  "sbrc %[byte] , 0" "\n\t"
2647  "mov %[n2] , %[hi]" "\n\t"
2648  "out %[port] , %[lo]" "\n\t"
2649  "sbiw %[count], 1" "\n\t"
2650  "out %[port] , %[hi]" "\n\t"
2651  "mov %[n1] , %[lo]" "\n\t"
2652  "out %[port] , %[n2]" "\n\t"
2653  "ld %[byte] , %a[ptr]+" "\n\t"
2654  "sbrc %[byte] , 7" "\n\t"
2655  "mov %[n1] , %[hi]" "\n\t"
2656  "out %[port] , %[lo]" "\n\t"
2657  "brne headB" "\n"
2658  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
2659  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
2660  [lo] "r" (lo));
2661  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
2662  }
2663  #endif
2664  #if defined(PORTC) || defined(PORTF)
2665  else
2666  #endif
2667  #endif
2668  #if defined(PORTC)
2669  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
2670  if(port == &PORTC) {
2671  #endif
2672  hi = PORTC | pinMask;
2673  lo = PORTC & ~pinMask;
2674  n1 = lo;
2675  if(b & 0x80) n1 = hi;
2676  asm volatile(
2677  "headC:" "\n\t"
2678  "out %[port] , %[hi]" "\n\t"
2679  "mov %[n2] , %[lo]" "\n\t"
2680  "out %[port] , %[n1]" "\n\t"
2681  "rjmp .+0" "\n\t"
2682  "sbrc %[byte] , 6" "\n\t"
2683  "mov %[n2] , %[hi]" "\n\t"
2684  "out %[port] , %[lo]" "\n\t"
2685  "rjmp .+0" "\n\t"
2686  "out %[port] , %[hi]" "\n\t"
2687  "mov %[n1] , %[lo]" "\n\t"
2688  "out %[port] , %[n2]" "\n\t"
2689  "rjmp .+0" "\n\t"
2690  "sbrc %[byte] , 5" "\n\t"
2691  "mov %[n1] , %[hi]" "\n\t"
2692  "out %[port] , %[lo]" "\n\t"
2693  "rjmp .+0" "\n\t"
2694  "out %[port] , %[hi]" "\n\t"
2695  "mov %[n2] , %[lo]" "\n\t"
2696  "out %[port] , %[n1]" "\n\t"
2697  "rjmp .+0" "\n\t"
2698  "sbrc %[byte] , 4" "\n\t"
2699  "mov %[n2] , %[hi]" "\n\t"
2700  "out %[port] , %[lo]" "\n\t"
2701  "rjmp .+0" "\n\t"
2702  "out %[port] , %[hi]" "\n\t"
2703  "mov %[n1] , %[lo]" "\n\t"
2704  "out %[port] , %[n2]" "\n\t"
2705  "rjmp .+0" "\n\t"
2706  "sbrc %[byte] , 3" "\n\t"
2707  "mov %[n1] , %[hi]" "\n\t"
2708  "out %[port] , %[lo]" "\n\t"
2709  "rjmp .+0" "\n\t"
2710  "out %[port] , %[hi]" "\n\t"
2711  "mov %[n2] , %[lo]" "\n\t"
2712  "out %[port] , %[n1]" "\n\t"
2713  "rjmp .+0" "\n\t"
2714  "sbrc %[byte] , 2" "\n\t"
2715  "mov %[n2] , %[hi]" "\n\t"
2716  "out %[port] , %[lo]" "\n\t"
2717  "rjmp .+0" "\n\t"
2718  "out %[port] , %[hi]" "\n\t"
2719  "mov %[n1] , %[lo]" "\n\t"
2720  "out %[port] , %[n2]" "\n\t"
2721  "rjmp .+0" "\n\t"
2722  "sbrc %[byte] , 1" "\n\t"
2723  "mov %[n1] , %[hi]" "\n\t"
2724  "out %[port] , %[lo]" "\n\t"
2725  "rjmp .+0" "\n\t"
2726  "out %[port] , %[hi]" "\n\t"
2727  "mov %[n2] , %[lo]" "\n\t"
2728  "out %[port] , %[n1]" "\n\t"
2729  "rjmp .+0" "\n\t"
2730  "sbrc %[byte] , 0" "\n\t"
2731  "mov %[n2] , %[hi]" "\n\t"
2732  "out %[port] , %[lo]" "\n\t"
2733  "sbiw %[count], 1" "\n\t"
2734  "out %[port] , %[hi]" "\n\t"
2735  "mov %[n1] , %[lo]" "\n\t"
2736  "out %[port] , %[n2]" "\n\t"
2737  "ld %[byte] , %a[ptr]+" "\n\t"
2738  "sbrc %[byte] , 7" "\n\t"
2739  "mov %[n1] , %[hi]" "\n\t"
2740  "out %[port] , %[lo]" "\n\t"
2741  "brne headC" "\n"
2742  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
2743  : [port] "I" (_SFR_IO_ADDR(PORTC)), [ptr] "e" (ptr), [hi] "r" (hi),
2744  [lo] "r" (lo));
2745  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
2746  }
2747  #endif
2748  #if defined(PORTF)
2749  else
2750  #endif
2751  #endif
2752  #if defined(PORTF)
2753  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
2754  if(port == &PORTF) {
2755  #endif // defined(PORTD/B/C)
2756  hi = PORTF | pinMask;
2757  lo = PORTF & ~pinMask;
2758  n1 = lo;
2759  if(b & 0x80) n1 = hi;
2760  asm volatile(
2761  "headF:" "\n\t"
2762  "out %[port] , %[hi]" "\n\t"
2763  "mov %[n2] , %[lo]" "\n\t"
2764  "out %[port] , %[n1]" "\n\t"
2765  "rjmp .+0" "\n\t"
2766  "sbrc %[byte] , 6" "\n\t"
2767  "mov %[n2] , %[hi]" "\n\t"
2768  "out %[port] , %[lo]" "\n\t"
2769  "rjmp .+0" "\n\t"
2770  "out %[port] , %[hi]" "\n\t"
2771  "mov %[n1] , %[lo]" "\n\t"
2772  "out %[port] , %[n2]" "\n\t"
2773  "rjmp .+0" "\n\t"
2774  "sbrc %[byte] , 5" "\n\t"
2775  "mov %[n1] , %[hi]" "\n\t"
2776  "out %[port] , %[lo]" "\n\t"
2777  "rjmp .+0" "\n\t"
2778  "out %[port] , %[hi]" "\n\t"
2779  "mov %[n2] , %[lo]" "\n\t"
2780  "out %[port] , %[n1]" "\n\t"
2781  "rjmp .+0" "\n\t"
2782  "sbrc %[byte] , 4" "\n\t"
2783  "mov %[n2] , %[hi]" "\n\t"
2784  "out %[port] , %[lo]" "\n\t"
2785  "rjmp .+0" "\n\t"
2786  "out %[port] , %[hi]" "\n\t"
2787  "mov %[n1] , %[lo]" "\n\t"
2788  "out %[port] , %[n2]" "\n\t"
2789  "rjmp .+0" "\n\t"
2790  "sbrc %[byte] , 3" "\n\t"
2791  "mov %[n1] , %[hi]" "\n\t"
2792  "out %[port] , %[lo]" "\n\t"
2793  "rjmp .+0" "\n\t"
2794  "out %[port] , %[hi]" "\n\t"
2795  "mov %[n2] , %[lo]" "\n\t"
2796  "out %[port] , %[n1]" "\n\t"
2797  "rjmp .+0" "\n\t"
2798  "sbrc %[byte] , 2" "\n\t"
2799  "mov %[n2] , %[hi]" "\n\t"
2800  "out %[port] , %[lo]" "\n\t"
2801  "rjmp .+0" "\n\t"
2802  "out %[port] , %[hi]" "\n\t"
2803  "mov %[n1] , %[lo]" "\n\t"
2804  "out %[port] , %[n2]" "\n\t"
2805  "rjmp .+0" "\n\t"
2806  "sbrc %[byte] , 1" "\n\t"
2807  "mov %[n1] , %[hi]" "\n\t"
2808  "out %[port] , %[lo]" "\n\t"
2809  "rjmp .+0" "\n\t"
2810  "out %[port] , %[hi]" "\n\t"
2811  "mov %[n2] , %[lo]" "\n\t"
2812  "out %[port] , %[n1]" "\n\t"
2813  "rjmp .+0" "\n\t"
2814  "sbrc %[byte] , 0" "\n\t"
2815  "mov %[n2] , %[hi]" "\n\t"
2816  "out %[port] , %[lo]" "\n\t"
2817  "sbiw %[count], 1" "\n\t"
2818  "out %[port] , %[hi]" "\n\t"
2819  "mov %[n1] , %[lo]" "\n\t"
2820  "out %[port] , %[n2]" "\n\t"
2821  "ld %[byte] , %a[ptr]+" "\n\t"
2822  "sbrc %[byte] , 7" "\n\t"
2823  "mov %[n1] , %[hi]" "\n\t"
2824  "out %[port] , %[lo]" "\n\t"
2825  "brne headF" "\n"
2826  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
2827  : [port] "I" (_SFR_IO_ADDR(PORTF)), [ptr] "e" (ptr), [hi] "r" (hi),
2828  [lo] "r" (lo));
2829  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
2830  }
2831  #endif // defined(PORTD/B/C)
2832  #endif // defined(PORTF)
2833  } else {
2834  volatile uint8_t next, bit;
2835  hi = *port | pinMask;
2836  lo = *port & ~pinMask;
2837  next = lo;
2838  bit = 8;
2839  asm volatile(
2840  "head20:" "\n\t" // Clk Pseudocode (T = 0)
2841  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
2842  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
2843  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
2844  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 6)
2845  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
2846  "dec %[bit]" "\n\t" // 1 bit-- (T = 8)
2847  "breq nextbyte20" "\n\t" // 1-2 if(bit == 0)
2848  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
2849  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
2850  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
2851  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
2852  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
2853  "rjmp head20" "\n\t" // 2 -> head20 (next bit out)
2854  "nextbyte20:" "\n\t" // (T = 10)
2855  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
2856  "nop" "\n\t" // 1 nop (T = 13)
2857  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 14)
2858  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 16)
2859  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
2860  "brne head20" "\n" // 2 if(i != 0) -> (next byte)
2861  : [port] "+e" (port),
2862  [byte] "+r" (b),
2863  [bit] "+r" (bit),
2864  [next] "+r" (next),
2865  [count] "+w" (i)
2866  : [hi] "r" (hi),
2867  [lo] "r" (lo),
2868  [ptr] "e" (ptr));
2869  }
2870  #elif (F_CPU >= 11100000UL) && (F_CPU <= 14300000UL)
2871  if(is800KHz) {
2872  volatile uint8_t next;
2873  // PORTD OUTPUT ----------------------------------------------------
2874  #if defined(PORTD)
2875  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
2876  if(port == &PORTD) {
2877  #endif
2878  hi = PORTD | pinMask;
2879  lo = PORTD & ~pinMask;
2880  next = lo;
2881  if(b & 0x80) next = hi;
2882  asm volatile(
2883  "headD:" "\n\t" // (T = 0)
2884  "out %[port], %[hi]" "\n\t" // (T = 1)
2885  "rcall bitTimeD" "\n\t" // Bit 7 (T = 15)
2886  "out %[port], %[hi]" "\n\t"
2887  "rcall bitTimeD" "\n\t" // Bit 6
2888  "out %[port], %[hi]" "\n\t"
2889  "rcall bitTimeD" "\n\t" // Bit 5
2890  "out %[port], %[hi]" "\n\t"
2891  "rcall bitTimeD" "\n\t" // Bit 4
2892  "out %[port], %[hi]" "\n\t"
2893  "rcall bitTimeD" "\n\t" // Bit 3
2894  "out %[port], %[hi]" "\n\t"
2895  "rcall bitTimeD" "\n\t" // Bit 2
2896  "out %[port], %[hi]" "\n\t"
2897  "rcall bitTimeD" "\n\t" // Bit 1
2898  // Bit 0:
2899  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi (T = 1)
2900  "rjmp .+0" "\n\t" // 2 nop nop (T = 3)
2901  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 5)
2902  "out %[port] , %[next]" "\n\t" // 1 PORT = next (T = 6)
2903  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
2904  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 0x80) (T = 8)
2905  "mov %[next] , %[hi]" "\n\t" // 0-1 next = hi (T = 9)
2906  "nop" "\n\t" // 1 (T = 10)
2907  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo (T = 11)
2908  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 13)
2909  "brne headD" "\n\t" // 2 if(i != 0) -> (next byte)
2910  "rjmp doneD" "\n\t"
2911  "bitTimeD:" "\n\t" // nop nop nop (T = 4)
2912  "out %[port], %[next]" "\n\t" // 1 PORT = next (T = 5)
2913  "mov %[next], %[lo]" "\n\t" // 1 next = lo (T = 6)
2914  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 7)
2915  "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 0x80) (T = 8)
2916  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 9)
2917  "nop" "\n\t" // 1 (T = 10)
2918  "out %[port], %[lo]" "\n\t" // 1 PORT = lo (T = 11)
2919  "ret" "\n\t" // 4 nop nop nop nop (T = 15)
2920  "doneD:" "\n"
2921  : [byte] "+r" (b),
2922  [next] "+r" (next),
2923  [count] "+w" (i)
2924  : [port] "I" (_SFR_IO_ADDR(PORTD)),
2925  [ptr] "e" (ptr),
2926  [hi] "r" (hi),
2927  [lo] "r" (lo));
2928  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
2929  } else
2930  #endif
2931  #endif
2932  #if defined(PORTB)
2933  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
2934  if(port == &PORTB) {
2935  #endif
2936  hi = PORTB | pinMask;
2937  lo = PORTB & ~pinMask;
2938  next = lo;
2939  if(b & 0x80) next = hi;
2940  asm volatile(
2941  "headB:" "\n\t"
2942  "out %[port], %[hi]" "\n\t"
2943  "rcall bitTimeB" "\n\t"
2944  "out %[port], %[hi]" "\n\t"
2945  "rcall bitTimeB" "\n\t"
2946  "out %[port], %[hi]" "\n\t"
2947  "rcall bitTimeB" "\n\t"
2948  "out %[port], %[hi]" "\n\t"
2949  "rcall bitTimeB" "\n\t"
2950  "out %[port], %[hi]" "\n\t"
2951  "rcall bitTimeB" "\n\t"
2952  "out %[port], %[hi]" "\n\t"
2953  "rcall bitTimeB" "\n\t"
2954  "out %[port], %[hi]" "\n\t"
2955  "rcall bitTimeB" "\n\t"
2956  "out %[port] , %[hi]" "\n\t"
2957  "rjmp .+0" "\n\t"
2958  "ld %[byte] , %a[ptr]+" "\n\t"
2959  "out %[port] , %[next]" "\n\t"
2960  "mov %[next] , %[lo]" "\n\t"
2961  "sbrc %[byte] , 7" "\n\t"
2962  "mov %[next] , %[hi]" "\n\t"
2963  "nop" "\n\t"
2964  "out %[port] , %[lo]" "\n\t"
2965  "sbiw %[count], 1" "\n\t"
2966  "brne headB" "\n\t"
2967  "rjmp doneB" "\n\t"
2968  "bitTimeB:" "\n\t"
2969  "out %[port], %[next]" "\n\t"
2970  "mov %[next], %[lo]" "\n\t"
2971  "rol %[byte]" "\n\t"
2972  "sbrc %[byte], 7" "\n\t"
2973  "mov %[next], %[hi]" "\n\t"
2974  "nop" "\n\t"
2975  "out %[port], %[lo]" "\n\t"
2976  "ret" "\n\t"
2977  "doneB:" "\n"
2978  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
2979  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
2980  [lo] "r" (lo));
2981  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
2982  }
2983  #endif
2984  #if defined(PORTC) || defined(PORTF)
2985  else
2986  #endif
2987  #endif
2988  #if defined(PORTC)
2989  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
2990  if(port == &PORTC) {
2991  #endif
2992  hi = PORTC | pinMask;
2993  lo = PORTC & ~pinMask;
2994  next = lo;
2995  if(b & 0x80) next = hi;
2996  asm volatile(
2997  "headC:" "\n\t"
2998  "out %[port], %[hi]" "\n\t"
2999  "rcall bitTimeC" "\n\t"
3000  "out %[port], %[hi]" "\n\t"
3001  "rcall bitTimeC" "\n\t"
3002  "out %[port], %[hi]" "\n\t"
3003  "rcall bitTimeC" "\n\t"
3004  "out %[port], %[hi]" "\n\t"
3005  "rcall bitTimeC" "\n\t"
3006  "out %[port], %[hi]" "\n\t"
3007  "rcall bitTimeC" "\n\t"
3008  "out %[port], %[hi]" "\n\t"
3009  "rcall bitTimeC" "\n\t"
3010  "out %[port], %[hi]" "\n\t"
3011  "rcall bitTimeC" "\n\t"
3012  "out %[port] , %[hi]" "\n\t"
3013  "rjmp .+0" "\n\t"
3014  "ld %[byte] , %a[ptr]+" "\n\t"
3015  "out %[port] , %[next]" "\n\t"
3016  "mov %[next] , %[lo]" "\n\t"
3017  "sbrc %[byte] , 7" "\n\t"
3018  "mov %[next] , %[hi]" "\n\t"
3019  "nop" "\n\t"
3020  "out %[port] , %[lo]" "\n\t"
3021  "sbiw %[count], 1" "\n\t"
3022  "brne headC" "\n\t"
3023  "rjmp doneC" "\n\t"
3024  "bitTimeC:" "\n\t"
3025  "out %[port], %[next]" "\n\t"
3026  "mov %[next], %[lo]" "\n\t"
3027  "rol %[byte]" "\n\t"
3028  "sbrc %[byte], 7" "\n\t"
3029  "mov %[next], %[hi]" "\n\t"
3030  "nop" "\n\t"
3031  "out %[port], %[lo]" "\n\t"
3032  "ret" "\n\t"
3033  "doneC:" "\n"
3034  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
3035  : [port] "I" (_SFR_IO_ADDR(PORTC)), [ptr] "e" (ptr), [hi] "r" (hi),
3036  [lo] "r" (lo));
3037  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
3038  }
3039  #endif
3040  #if defined(PORTF)
3041  else
3042  #endif
3043  #endif
3044  #if defined(PORTF)
3045  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
3046  if(port == &PORTF) {
3047  #endif
3048  hi = PORTF | pinMask;
3049  lo = PORTF & ~pinMask;
3050  next = lo;
3051  if(b & 0x80) next = hi;
3052  asm volatile(
3053  "headF:" "\n\t"
3054  "out %[port], %[hi]" "\n\t"
3055  "rcall bitTimeC" "\n\t"
3056  "out %[port], %[hi]" "\n\t"
3057  "rcall bitTimeC" "\n\t"
3058  "out %[port], %[hi]" "\n\t"
3059  "rcall bitTimeC" "\n\t"
3060  "out %[port], %[hi]" "\n\t"
3061  "rcall bitTimeC" "\n\t"
3062  "out %[port], %[hi]" "\n\t"
3063  "rcall bitTimeC" "\n\t"
3064  "out %[port], %[hi]" "\n\t"
3065  "rcall bitTimeC" "\n\t"
3066  "out %[port], %[hi]" "\n\t"
3067  "rcall bitTimeC" "\n\t"
3068  "out %[port] , %[hi]" "\n\t"
3069  "rjmp .+0" "\n\t"
3070  "ld %[byte] , %a[ptr]+" "\n\t"
3071  "out %[port] , %[next]" "\n\t"
3072  "mov %[next] , %[lo]" "\n\t"
3073  "sbrc %[byte] , 7" "\n\t"
3074  "mov %[next] , %[hi]" "\n\t"
3075  "nop" "\n\t"
3076  "out %[port] , %[lo]" "\n\t"
3077  "sbiw %[count], 1" "\n\t"
3078  "brne headF" "\n\t"
3079  "rjmp doneC" "\n\t"
3080  "bitTimeC:" "\n\t"
3081  "out %[port], %[next]" "\n\t"
3082  "mov %[next], %[lo]" "\n\t"
3083  "rol %[byte]" "\n\t"
3084  "sbrc %[byte], 7" "\n\t"
3085  "mov %[next], %[hi]" "\n\t"
3086  "nop" "\n\t"
3087  "out %[port], %[lo]" "\n\t"
3088  "ret" "\n\t"
3089  "doneC:" "\n"
3090  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
3091  : [port] "I" (_SFR_IO_ADDR(PORTF)), [ptr] "e" (ptr), [hi] "r" (hi),
3092  [lo] "r" (lo));
3093  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
3094  }
3095  #endif
3096  #endif
3097  } else {
3098  volatile uint8_t next, bit;
3099  hi = *port | pinMask;
3100  lo = *port & ~pinMask;
3101  next = lo;
3102  bit = 8;
3103  asm volatile(
3104  "head30:" "\n\t" // Clk Pseudocode (T = 0)
3105  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
3106  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
3107  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
3108  "rjmp .+0" "\n\t" // 2 nop nop (T = 6)
3109  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 8)
3110  "rjmp .+0" "\n\t" // 2 nop nop (T = 10)
3111  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
3112  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
3113  "nop" "\n\t" // 1 nop (T = 15)
3114  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 17)
3115  "rjmp .+0" "\n\t" // 2 nop nop (T = 19)
3116  "dec %[bit]" "\n\t" // 1 bit-- (T = 20)
3117  "breq nextbyte30" "\n\t" // 1-2 if(bit == 0)
3118  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 22)
3119  "rjmp .+0" "\n\t" // 2 nop nop (T = 24)
3120  "rjmp .+0" "\n\t" // 2 nop nop (T = 26)
3121  "rjmp .+0" "\n\t" // 2 nop nop (T = 28)
3122  "rjmp head30" "\n\t" // 2 -> head30 (next bit out)
3123  "nextbyte30:" "\n\t" // (T = 22)
3124  "nop" "\n\t" // 1 nop (T = 23)
3125  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 24)
3126  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 26)
3127  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 28)
3128  "brne head30" "\n" // 1-2 if(i != 0) -> (next byte)
3129  : [port] "+e" (port),
3130  [byte] "+r" (b),
3131  [bit] "+r" (bit),
3132  [next] "+r" (next),
3133  [count] "+w" (i)
3134  : [hi] "r" (hi),
3135  [lo] "r" (lo),
3136  [ptr] "e" (ptr));
3137  }
3138  #elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L)
3139  if(is800KHz) {
3140  volatile uint8_t next, bit;
3141  hi = *port | pinMask;
3142  lo = *port & ~pinMask;
3143  next = lo;
3144  bit = 8;
3145  asm volatile(
3146  "head20:" "\n\t" // Clk Pseudocode (T = 0)
3147  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
3148  "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 128)
3149  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
3150  "dec %[bit]" "\n\t" // 1 bit-- (T = 5)
3151  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 7)
3152  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 8)
3153  "breq nextbyte20" "\n\t" // 1-2 if(bit == 0) (from dec above)
3154  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
3155  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
3156  "nop" "\n\t" // 1 nop (T = 13)
3157  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15)
3158  "nop" "\n\t" // 1 nop (T = 16)
3159  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
3160  "rjmp head20" "\n\t" // 2 -> head20 (next bit out)
3161  "nextbyte20:" "\n\t" // (T = 10)
3162  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 11)
3163  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 13)
3164  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15)
3165  "nop" "\n\t" // 1 nop (T = 16)
3166  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
3167  "brne head20" "\n" // 2 if(i != 0) -> (next byte)
3168  : [port] "+e" (port),
3169  [byte] "+r" (b),
3170  [bit] "+r" (bit),
3171  [next] "+r" (next),
3172  [count] "+w" (i)
3173  : [ptr] "e" (ptr),
3174  [hi] "r" (hi),
3175  [lo] "r" (lo));
3176  } else {
3177  volatile uint8_t next, bit;
3178  hi = *port | pinMask;
3179  lo = *port & ~pinMask;
3180  next = lo;
3181  bit = 8;
3182  asm volatile(
3183  "head40:" "\n\t" // Clk Pseudocode (T = 0)
3184  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
3185  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
3186  "mov %[next] , %[hi]" "\n\t" // 0-1 next = hi (T = 4)
3187  "rjmp .+0" "\n\t" // 2 nop nop (T = 6)
3188  "rjmp .+0" "\n\t" // 2 nop nop (T = 8)
3189  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 10)
3190  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
3191  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
3192  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
3193  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
3194  "rjmp .+0" "\n\t" // 2 nop nop (T = 20)
3195  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 22)
3196  "nop" "\n\t" // 1 nop (T = 23)
3197  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 24)
3198  "dec %[bit]" "\n\t" // 1 bit-- (T = 25)
3199  "breq nextbyte40" "\n\t" // 1-2 if(bit == 0)
3200  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 27)
3201  "nop" "\n\t" // 1 nop (T = 28)
3202  "rjmp .+0" "\n\t" // 2 nop nop (T = 30)
3203  "rjmp .+0" "\n\t" // 2 nop nop (T = 32)
3204  "rjmp .+0" "\n\t" // 2 nop nop (T = 34)
3205  "rjmp .+0" "\n\t" // 2 nop nop (T = 36)
3206  "rjmp .+0" "\n\t" // 2 nop nop (T = 38)
3207  "rjmp head40" "\n\t" // 2 -> head40 (next bit out)
3208  "nextbyte40:" "\n\t" // (T = 27)
3209  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 28)
3210  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 30)
3211  "rjmp .+0" "\n\t" // 2 nop nop (T = 32)
3212  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 34)
3213  "rjmp .+0" "\n\t" // 2 nop nop (T = 36)
3214  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 38)
3215  "brne head40" "\n" // 1-2 if(i != 0) -> (next byte)
3216  : [port] "+e" (port),
3217  [byte] "+r" (b),
3218  [bit] "+r" (bit),
3219  [next] "+r" (next),
3220  [count] "+w" (i)
3221  : [ptr] "e" (ptr),
3222  [hi] "r" (hi),
3223  [lo] "r" (lo));
3224  }
3225  #else
3226  #error "CPU SPEED NOT SUPPORTED"
3227  #endif
3228  #elif defined(__arm__)
3229  #if defined(TEENSYDUINO) && defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6
3230  #define CYCLES_800_T0H (F_CPU / 4000000)
3231  #define CYCLES_800_T1H (F_CPU / 1250000)
3232  #define CYCLES_800 (F_CPU / 800000)
3233  #define CYCLES_400_T0H (F_CPU / 2000000)
3234  #define CYCLES_400_T1H (F_CPU / 833333)
3235  #define CYCLES_400 (F_CPU / 400000)
3236  uint8_t *p = pixels,
3237  *end = p + numBytes, pix, mask;
3238  volatile uint8_t *set = portSetRegister(pin),
3239  *clr = portClearRegister(pin);
3240  uint32_t cyc;
3241  ARM_DEMCR |= ARM_DEMCR_TRCENA;
3242  ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
3243  if(is800KHz) {
3244  cyc = ARM_DWT_CYCCNT + CYCLES_800;
3245  while(p < end) {
3246  pix = *p++;
3247  for(mask = 0x80; mask; mask >>= 1) {
3248  while(ARM_DWT_CYCCNT - cyc < CYCLES_800);
3249  cyc = ARM_DWT_CYCCNT;
3250  *set = 1;
3251  if(pix & mask) {
3252  while(ARM_DWT_CYCCNT - cyc < CYCLES_800_T1H);
3253  } else {
3254  while(ARM_DWT_CYCCNT - cyc < CYCLES_800_T0H);
3255  }
3256  *clr = 1;
3257  }
3258  }
3259  while(ARM_DWT_CYCCNT - cyc < CYCLES_800);
3260  } else {
3261  cyc = ARM_DWT_CYCCNT + CYCLES_400;
3262  while(p < end) {
3263  pix = *p++;
3264  for(mask = 0x80; mask; mask >>= 1) {
3265  while(ARM_DWT_CYCCNT - cyc < CYCLES_400);
3266  cyc = ARM_DWT_CYCCNT;
3267  *set = 1;
3268  if(pix & mask) {
3269  while(ARM_DWT_CYCCNT - cyc < CYCLES_400_T1H);
3270  } else {
3271  while(ARM_DWT_CYCCNT - cyc < CYCLES_400_T0H);
3272  }
3273  *clr = 1;
3274  }
3275  }
3276  while(ARM_DWT_CYCCNT - cyc < CYCLES_400);
3277  }
3278  #else
3279  #error "Sorry, only 48 MHz is supported, please set Tools > CPU Speed to 48 MHz"
3280  #endif
3281  #elif defined(ESP8266) || defined(ESP32)
3282  espShow(pin, pixels, numBytes, is800KHz);
3283  #elif defined(__ARDUINO_ARC__)
3284  // Arduino 101 -----------------------------------------------------------
3285  #define NOPx7 { __builtin_arc_nop(); \
3286  __builtin_arc_nop(); __builtin_arc_nop(); \
3287  __builtin_arc_nop(); __builtin_arc_nop(); \
3288  __builtin_arc_nop(); __builtin_arc_nop(); }
3289  PinDescription *pindesc = &g_APinDescription[pin];
3290  register uint32_t loop = 8 * numBytes; // one loop to handle all bytes and all bits
3291  register uint8_t *p = pixels;
3292  register uint32_t currByte = (uint32_t) (*p);
3293  register uint32_t currBit = 0x80 & currByte;
3294  register uint32_t bitCounter = 0;
3295  register uint32_t first = 1;
3296  if (pindesc->ulGPIOType == SS_GPIO) {
3297  register uint32_t reg = pindesc->ulGPIOBase + SS_GPIO_SWPORTA_DR;
3298  uint32_t reg_val = __builtin_arc_lr((volatile uint32_t)reg);
3299  register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
3300  register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
3301  loop += 1;
3302  while(loop--) {
3303  if(!first) {
3304  currByte <<= 1;
3305  bitCounter++;
3306  }
3307  // 1 is >550ns high and >450ns low; 0 is 200..500ns high and >450ns low
3308  __builtin_arc_sr(first ? reg_bit_low : reg_bit_high, (volatile uint32_t)reg);
3309  if(currBit) { // ~400ns HIGH (740ns overall)
3310  NOPx7
3311  NOPx7
3312  }
3313  // ~340ns HIGH
3314  NOPx7
3315  __builtin_arc_nop();
3316  // 820ns LOW; per spec, max allowed low here is 5000ns */
3317  __builtin_arc_sr(reg_bit_low, (volatile uint32_t)reg);
3318  NOPx7
3319  NOPx7
3320  if(bitCounter >= 8) {
3321  bitCounter = 0;
3322  currByte = (uint32_t) (*++p);
3323  }
3324  currBit = 0x80 & currByte;
3325  first = 0;
3326  }
3327  } else if(pindesc->ulGPIOType == SOC_GPIO) {
3328  register uint32_t reg = pindesc->ulGPIOBase + SOC_GPIO_SWPORTA_DR;
3329  uint32_t reg_val = MMIO_REG_VAL(reg);
3330  register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
3331  register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
3332  loop += 1; // include first, special iteration
3333  while(loop--) {
3334  if(!first) {
3335  currByte <<= 1;
3336  bitCounter++;
3337  }
3338  MMIO_REG_VAL(reg) = first ? reg_bit_low : reg_bit_high;
3339  if(currBit) { // ~430ns HIGH (740ns overall)
3340  NOPx7
3341  NOPx7
3342  __builtin_arc_nop();
3343  }
3344  // ~310ns HIGH
3345  NOPx7
3346  // 850ns LOW; per spec, max allowed low here is 5000ns */
3347  MMIO_REG_VAL(reg) = reg_bit_low;
3348  NOPx7
3349  NOPx7
3350  if(bitCounter >= 8) {
3351  bitCounter = 0;
3352  currByte = (uint32_t) (*++p);
3353  }
3354  currBit = 0x80 & currByte;
3355  first = 0;
3356  }
3357  }
3358  #else
3359  #error Architecture not supported
3360  #endif
3361  interrupts();
3362  endTime = micros();
3363  }
3364  void NeoPixel::setPin(uint8_t p) {
3365  if(begun && (pin >= 0)) pinMode(pin, INPUT);
3366  pin = p;
3367  if(begun) {
3368  pinMode(p, OUTPUT);
3369  digitalWrite(p, LOW);
3370  }
3371  #ifdef __AVR__
3372  port = portOutputRegister(digitalPinToPort(p));
3373  pinMask = digitalPinToBitMask(p);
3374  #endif
3375  }
3377  uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
3378  if(n < numLEDs) {
3379  if(brightness) { // See notes in setBrightness()
3380  r = (r * brightness) >> 8;
3381  g = (g * brightness) >> 8;
3382  b = (b * brightness) >> 8;
3383  }
3384  uint8_t *p;
3385  if(aOffset[3] == aOffset[0]) {
3386  p = &pixels[n * 3];
3387  } else {
3388  p = &pixels[n * 4];
3389  p[aOffset[3]] = 0;
3390  }
3391  p[aOffset[0]] = r;
3392  p[aOffset[1]] = g;
3393  p[aOffset[2]] = b;
3394  }
3395  }
3397  uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
3398  if(n < numLEDs) {
3399  if(brightness) {
3400  r = (r * brightness) >> 8;
3401  g = (g * brightness) >> 8;
3402  b = (b * brightness) >> 8;
3403  w = (w * brightness) >> 8;
3404  }
3405  uint8_t *p;
3406  if(aOffset[3] == aOffset[0]) {
3407  p = &pixels[n * 3];
3408  } else {
3409  p = &pixels[n * 4];
3410  p[aOffset[3]] = w;
3411  }
3412  p[aOffset[0]] = r;
3413  p[aOffset[1]] = g;
3414  p[aOffset[2]] = b;
3415  }
3416  }
3417  void NeoPixel::setPixelColor(uint16_t n, uint32_t c) {
3418  if(n < numLEDs) {
3419  uint8_t *p,
3420  r = (uint8_t)(c >> 16),
3421  g = (uint8_t)(c >> 8),
3422  b = (uint8_t)c;
3423  if(brightness) {
3424  r = (r * brightness) >> 8;
3425  g = (g * brightness) >> 8;
3426  b = (b * brightness) >> 8;
3427  }
3428  if(aOffset[3] == aOffset[0]) {
3429  p = &pixels[n * 3];
3430  } else {
3431  p = &pixels[n * 4];
3432  uint8_t w = (uint8_t)(c >> 24);
3433  p[aOffset[3]] = brightness ? ((w * brightness) >> 8) : w;
3434  }
3435  p[aOffset[0]] = r;
3436  p[aOffset[1]] = g;
3437  p[aOffset[2]] = b;
3438  }
3439  }
3440  uint32_t NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b) {
3441  return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
3442  }
3443  uint32_t NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
3444  return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
3445  }
3446  uint32_t NeoPixel::getPixelColor(uint16_t n) const {
3447  if(n >= numLEDs) return 0;
3448  uint8_t *p;
3449  if(aOffset[3] == aOffset[0]) {
3450  p = &pixels[n * 3];
3451  if(brightness) {
3452  return (((uint32_t)(p[aOffset[0]] << 8) / brightness) << 16) |
3453  (((uint32_t)(p[aOffset[1]] << 8) / brightness) << 8) |
3454  ( (uint32_t)(p[aOffset[2]] << 8) / brightness );
3455  } else {
3456  return ((uint32_t)p[aOffset[0]] << 16) |
3457  ((uint32_t)p[aOffset[1]] << 8) |
3458  (uint32_t)p[aOffset[2]];
3459  }
3460  } else {
3461  p = &pixels[n * 4];
3462  if(brightness) {
3463  return (((uint32_t)(p[aOffset[3]] << 8) / brightness) << 24) |
3464  (((uint32_t)(p[aOffset[0]] << 8) / brightness) << 16) |
3465  (((uint32_t)(p[aOffset[1]] << 8) / brightness) << 8) |
3466  ( (uint32_t)(p[aOffset[2]] << 8) / brightness );
3467  } else {
3468  return ((uint32_t)p[aOffset[3]] << 24) |
3469  ((uint32_t)p[aOffset[0]] << 16) |
3470  ((uint32_t)p[aOffset[1]] << 8) |
3471  (uint32_t)p[aOffset[2]];
3472  }
3473  }
3474  }
3475  uint8_t *NeoPixel::getPixels(void) const {
3476  return pixels;
3477  }
3478  uint16_t NeoPixel::numPixels(void) const {
3479  return numLEDs;
3480  }
3481  void NeoPixel::setBrightness(uint8_t b) {
3482  uint8_t newBrightness = b + 1;
3483  if(newBrightness != brightness) {
3484  uint8_t c,
3485  *ptr = pixels,
3486  oldBrightness = brightness - 1;
3487  uint16_t scale;
3488  if(oldBrightness == 0) scale = 0; // Avoid /0
3489  else if(b == 255) scale = 65535 / oldBrightness;
3490  else scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
3491  for(uint16_t i=0; i<numBytes; i++) {
3492  c = *ptr;
3493  *ptr++ = (c * scale) >> 8;
3494  }
3495  brightness = newBrightness;
3496  }
3497  }
3498  uint8_t NeoPixel::getBrightness(void) const {
3499  return brightness - 1;
3500  }
3502  memset(pixels, 0, numBytes);
3503  }
3504  static const uint8_t PROGMEM _sineTable[256] = {
3505  128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,
3506  176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,
3507  218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,
3508  245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,
3509  255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,
3510  245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,
3511  218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,
3512  176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,
3513  128,124,121,118,115,112,109,106,103,100, 97, 93, 90, 88, 85, 82,
3514  79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
3515  37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
3516  10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0,
3517  0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
3518  10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
3519  37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
3520  79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124};
3521  static const uint8_t PROGMEM _gammaTable[256] = {
3522  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3523  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
3524  1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
3525  3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
3526  7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12,
3527  13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
3528  20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
3529  30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
3530  42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
3531  58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
3532  76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
3533  97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
3534  122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
3535  150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
3536  182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
3537  218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255};
3538  uint8_t NeoPixel::sine8(uint8_t x) const {
3539  return pgm_read_byte(&_sineTable[x]); // 0-255 in, 0-255 out
3540  }
3541  uint8_t NeoPixel::gamma8(uint8_t x) const {
3542  return pgm_read_byte(&_gammaTable[x]); // 0-255 in, 0-255 out
3543  }
3544  #endif
3545 
3546 
3547 
3548 
3549 
3550 
3551 
3552 
3553 
3554 
3555 
3556 
3557 #if EBOARD_NANO > 0x0 || defined(DOC)
3558 //offer more functions
3559  #if EBOARD_GUESSPATH > 0x0
3560  //import servo-class
3561 
3562  //shameless copy paste :D
3563  #define _useTimer1
3565  #define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
3566  #define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
3567  #define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
3568  #define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
3569  #define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
3570  #define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
3571  #define INVALID_SERVO 255 // flag indicating an invalid servo index
3572  typedef struct {
3573  uint8_t nbr :6 ; // a pin number from 0 to 63
3574  uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false
3575  } ServoPin_t ;
3576  typedef struct {
3578  volatile unsigned int ticks;
3579  } servo_t;
3580  class Servo {
3581  public:
3582  Servo();
3583  uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
3584  uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes.
3585  void detach();
3586  void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
3587  void writeMicroseconds(int value); // Write pulse width in microseconds
3588  inline int read(); // returns current pulse width as an angle between 0 and 180 degrees
3589  int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
3590  inline bool attached(); // return true if this servo is attached, otherwise false
3591  private:
3592  uint8_t servoIndex; // index into the channel data for this servo
3593  int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH
3594  int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
3595  };
3596  #define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009
3597  #define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
3598  #define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009
3599  //#define NBR_TIMERS (MAX_SERVOS / SERVOS_PER_TIMER)
3600  static servo_t servos[MAX_SERVOS]; // static array of servo structures
3601  static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
3602  uint8_t ServoCount = 0; // the total number of attached servos
3603  // convenience macros
3604  #define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo
3605  #define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer
3606  #define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel
3607  #define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
3608  #define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
3609  #define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
3610  static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA)
3611  {
3612  if( Channel[timer] < 0 )
3613  *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
3614  else{
3615  if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true )
3616  digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated
3617  }
3618  Channel[timer]++; // increment to the next channel
3619  if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
3620  *OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks;
3621  if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated
3622  digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high
3623  }
3624  else {
3625  // finished all channels so wait for the refresh period to expire before starting over
3626  if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed
3627  *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
3628  else
3629  *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
3630  Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
3631  }
3632  }
3633  #ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
3634  // Interrupt handlers for Arduino
3635  #if defined(_useTimer1)
3636  SIGNAL (TIMER1_COMPA_vect)
3637  {
3638  handle_interrupts(_timer1, &TCNT1, &OCR1A);
3639  }
3640  #endif
3641  #elif defined WIRING
3642  // Interrupt handlers for Wiring
3643  #if defined(_useTimer1)
3644  void Timer1Service()
3645  {
3646  handle_interrupts(_timer1, &TCNT1, &OCR1A);
3647  }
3648  #endif
3649  #endif
3650  static void initISR(timer16_Sequence_t timer) {
3651  if(timer == _timer1) {
3652  TCCR1A = 0; // normal counting mode
3653  TCCR1B = _BV(CS11); // set prescaler of 8
3654  TCNT1 = 0; // clear the timer count
3655  TIFR1 |= _BV(OCF1A); // clear any pending interrupts;
3656  TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt
3657  #if defined(WIRING)
3658  timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
3659  #endif
3660  }
3661  }
3662  static void finISR(timer16_Sequence_t timer) {
3663  #if defined WIRING // Wiring
3664  if(timer == _timer1) {
3665  TIMSK &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt
3666  timerDetach(TIMER1OUTCOMPAREA_INT);
3667  }
3668  else if(timer == _timer3) {
3669  ETIMSK &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt
3670  timerDetach(TIMER3OUTCOMPAREA_INT);
3671  }
3672  #else
3673  //For arduino - in future: call here to a currently undefined function to reset the timer
3674  (void) timer; // squash "unused parameter 'timer' [-Wunused-parameter]" warning
3675  #endif
3676  }
3677  static boolean isTimerActive(timer16_Sequence_t timer) {
3678  // returns true if any servo is active on this timer
3679  for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) {
3680  if(SERVO(timer,channel).Pin.isActive == true)
3681  return true;
3682  }
3683  return false;
3684  }
3686  if( ServoCount < MAX_SERVOS) {
3687  this->servoIndex = ServoCount++; // assign a servo index to this instance
3688  servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
3689  }
3690  else
3691  this->servoIndex = INVALID_SERVO ; // too many servos
3692  }
3693  uint8_t Servo::attach(int pin) {
3694  return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
3695  }
3696  uint8_t Servo::attach(int pin, int min, int max) {
3697  if(this->servoIndex < MAX_SERVOS ) {
3698  pinMode( pin, OUTPUT) ; // set servo pin to output
3699  servos[this->servoIndex].Pin.nbr = pin;
3700  // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
3701  this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
3702  this->max = (MAX_PULSE_WIDTH - max)/4;
3703  // initialize the timer if it has not already been initialized
3705  if(isTimerActive(timer) == false)
3706  initISR(timer);
3707  servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
3708  }
3709  return this->servoIndex ;
3710  }
3711  void Servo::detach() {
3712  servos[this->servoIndex].Pin.isActive = false;
3714  if(isTimerActive(timer) == false) {
3715  finISR(timer);
3716  }
3717  }
3718  void Servo::write(int value) {
3719  if(value < MIN_PULSE_WIDTH)
3720  { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
3721  if(value < 0) value = 0;
3722  if(value > 180) value = 180;
3723  value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX());
3724  }
3725  this->writeMicroseconds(value);
3726  }
3727  void Servo::writeMicroseconds(int value) {
3728  // calculate and store the values for the given channel
3729  byte channel = this->servoIndex;
3730  if( (channel < MAX_SERVOS) ) // ensure channel is valid
3731  {
3732  if( value < SERVO_MIN() ) // ensure pulse width is valid
3733  value = SERVO_MIN();
3734  else if( value > SERVO_MAX() )
3735  value = SERVO_MAX();
3736  value = value - TRIM_DURATION;
3737  value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009
3738  uint8_t oldSREG = SREG;
3739  cli();
3740  servos[channel].ticks = value;
3741  SREG = oldSREG;
3742  }
3743  }
3744  inline int Servo::read() // return the value as degrees
3745  {
3746  return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180);
3747  }
3749  unsigned int pulsewidth;
3750  if( this->servoIndex != INVALID_SERVO )
3751  pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION ; // 12 aug 2009
3752  else
3753  pulsewidth = 0;
3754  return pulsewidth;
3755  }
3756  inline bool Servo::attached() {
3757  return servos[this->servoIndex].Pin.isActive ;
3758  }
3759 
3760  #endif
3761 #endif
3762 #if EBOARD_COPY_AND_PASTE > 0x0
3764  if (_pwmValue!=_OpwmValue){
3765  analogWrite(PIN_MOTOR_SPE,_pwmValue);
3767  }
3768  #ifdef REPT_TASK
3769  rept_task();
3770  #endif
3771  }
3772  #if EBOARD_NANO > 0x0
3773  Servo mainMotor,steerMotor;
3774  #endif
3775  int timer_count = 0;
3776  bool timer_ofl = false;
3777  ISR(TIMER2_OVF_vect) {
3778  timer_count++;
3779  if(timer_count >= EBOARD_PWM_SPE*1000 && !timer_ofl){
3780  timer_ofl = true;
3781  timer_count -= EBOARD_PWM_SPE*1000;
3782  trig_rept_task();
3783  timer_ofl = false;
3784  }
3785  TCNT2 = 256 - (int)((float)F_CPU * 0.001 / 64);
3786  }
3787 
3788  extern int eVirtual_main();
3789 
3790 
3791  void setup(void);
3792 
3793  void setup(void) {
3794  //setup of RX and TX should be handled manually - in everyCase ^^
3797  #if EBOARD_DEBUG_MODE > 0x0
3798  Serial.begin(EBOARD_DEBUG_SPEED);
3799  #endif
3800  //this will initialize the interrupt handling!
3801  cli();
3802  TIMSK2 &= ~(1<<TOIE2);
3803  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
3804  TCCR2B &= ~(1<<WGM22);
3805  ASSR &= ~(1<<AS2);
3806  TIMSK2 &= ~(1<<OCIE2A);
3807  TCCR2B |= (1<<CS22);
3808  TCCR2B &= ~((1<<CS21) | (1<<CS20));
3809  TCNT2 = 256 - (int)((float)F_CPU * 0.001 / 64);
3810  TIMSK2 |= (1<<TOIE2);
3811  sei();
3812  #if EBOARD_BLUETOOTH > 0x0
3813 
3814 
3815  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
3816  Serial1.begin(38400);
3817  #else
3818  _serial.begin(38400);
3819  #endif
3821  #endif
3822  #if EBOARD_I2C > 0x0
3823  Wire.begin();
3824  #endif
3825  #if EBOARD_SHIFT_REGISTER > 0x0
3826  pinMode(PIN_SHIFT_CLK,OUTPUT);
3827  pinMode(PIN_SHIFT_DAT,OUTPUT);
3828  pinMode(PIN_SHIFT_LAT,OUTPUT);
3829  shiftAll(); //set all to 0
3830  #endif
3831  #if EBOARD_USE_SPI > 0x0 && (EBOARD_NANO == 0)
3832  _servoHandler.begin(); //Setup SPI
3833  #endif
3834  #if EBOARD_NANO > 0x0
3835  mainMotor.attach(EBOARD_NANO_MAIN);
3836  steerMotor.attach(EBOARD_NANO_STEER);
3837  #if EBOARD_DEBUG_MODE > 0x0
3838  Serial.println("Initializing main driving motor (3s)");
3839  #endif
3840  mainMotor.write(90);
3841  delay(3005);
3842  #if EBOARD_DEBUG_MODE > 0x0
3843  Serial.println("Initializing of main driving motor completed");
3844  #endif
3845  #endif
3846  #if EBOARD_DEBUG_MODE > 0x0
3847  Serial.print((char) eVirtual_main());
3848  Serial.println("fin");
3849  #else
3850  eVirtual_main();
3851  #endif
3852  if (STOP) {} //prevent unused error
3853  delay(200);
3854  #if EBOARD_NANO > 0x0
3855  mainMotor.write(90);
3856  #endif
3857  cli(); //disable timers after running the program :D
3858  #if EBOARD_NANO == 0x0
3859  writePWM(0);analogWrite(PIN_MOTOR_SPE,0);
3860  #endif
3861  }
3862 
3863 
3864  void loop(void);
3865 
3866  void loop(void){
3867  //shall be empty
3868  }
3869 
3870 #endif
3871 #if EBOARD_NANO > 0x0 || defined(DOC)
3872 
3873  inline void set_motor_speed(optVAL_t spe){
3874  if(spe < 0 || spe > 180) return;
3875  mainMotor.write(spe);
3876  }
3877 
3878  inline void set_steer_angle(optVAL_t ang){
3879  if(ang < 0 || ang > 180) return;
3880  steerMotor.write(ang);
3881  }
3882 #endif
3883 #else
3884  #error This library is build for arduino-devices and should be used only in the Arduino IDE or with a similar linking process
3885 #endif
3886 #pragma GCC diagnostic pop
3887 #pragma pack(pop)
3888 #endif
int actPos
stores the actual pos or move-to pos of the AX12Servo
Definition: eBoard.h:1807
uint16_t _rx_delay_intrabit
the rx startbit delay
Definition: eBoard.h:854
static void setDataMode(uint8_t mode)
Definition: eBoard.h:626
#define SERVO_MIN()
Definition: eBoard.h:3608
optVAL_t _pwmValue
Definition: eBoard.h:1422
#define SERVO_INDEX(_timer, _channel)
Definition: eBoard.h:3606
static volatile uint8_t twi_inRepStart
Definition: eBoard.h:117
uint8_t requestFrom(uint8_t address, uint8_t quantity)
Definition: eBoard.h:445
bool checkPin(optVAL_t idx, optVAL_t mode=0x1)
[COPY&PASTE] [CHECK_PINS] Check if a pin is set to a specific mode
Definition: eBoard.h:1332
SoccerBoard(void)
Definition: eBoard.h:1640
void tx_pin_write(uint8_t pin_state)
Definition: eBoard.h:1101
static void setBitOrder(uint8_t bitOrder)
Definition: eBoard.h:622
long baud
Definition: eBoard.h:931
int8_t pin
stores the pin -1 if the pin wasn&#39;t set
Definition: eBoard.h:2405
static volatile uint8_t _receive_buffer_head
current location in rxBuffer
Definition: eBoard.h:868
optVAL_t C
storing value for C-pin [MOTOR SPE]
Definition: eBoard.h:1746
uint8_t endTransmission(void)
Definition: eBoard.h:470
void shiftSingle(optVAL_t idx, bool val)
[SHIFT] Changes a single output Pin
Definition: eBoard.h:1407
static const uint8_t PROGMEM _sineTable[256]
Definition: eBoard.h:3504
static volatile int8_t Channel[_Nbr_16timers]
Definition: eBoard.h:3601
const unsigned char * buf[11]
to enable &#39;smooth&#39; access (:
void writePWM(optVAL_t val)
write a clamped pwm value to an output pin
Definition: eBoard.h:1426
uint8_t _transmitBitMask
the pin mask to address the tx pin
Definition: eBoard.h:848
[COPY&PASTE] This is the SoccerBoard ghost struct :D
Definition: eBoard.h:1592
void twi_stop(void)
Definition: eBoard.h:213
void writeVal(const T &val)
[BLUETOOTH] writes Data to bluetooth
Definition: eBoard.h:1383
uint8_t aOffset[4]
stores the offsets in rgbw format
Definition: eBoard.h:2411
void write(int value)
Definition: eBoard.h:3718
ServoCds55(int CS=53)
Definition: eBoard.h:1508
uint8_t * pixels
stores the pixels
Definition: eBoard.h:2409
static uint8_t txBufferLength
this defines the length of txBuffer
Definition: eBoard.h:348
void twi_releaseBus(void)
Definition: eBoard.h:218
#define PIN_SHIFT_LAT
Definition: eBoard.h:820
[COPY&PASTE] This is the AX12Servo ghost struct :D
Definition: eBoard.h:1766
void write(void)
Definition: eBoard.h:1757
ISR(TWI_vect)
Definition: eBoard.h:222
#define DEBUG_MSG(str)
Definition: eBoard.h:17
#define MAX_SERVOS
Definition: eBoard.h:3570
bool canShow(void)
Definition: eBoard.h:2428
void storePosition(int pos, int speed=0x3FF)
Definition: eBoard.h:1882
int actSpe
stores the actual &#39;would use speed&#39; of the AX12Servo
Definition: eBoard.h:1809
static volatile uint8_t twi_masterBufferIndex
Definition: eBoard.h:121
optVAL_t getPosition(void)
Definition: eBoard.h:1837
optVAL_t B
storing value for B-pin [MOTOR DIR]
Definition: eBoard.h:1744
void setID(optVAL_t newID)
Definition: eBoard.h:1814
#define PIN_MAX
Definition: eBoard.h:80
virtual size_t write(uint8_t byte)
Definition: eBoard.h:1207
uint8_t getBrightness(void) const
Definition: eBoard.h:3498
static char _receive_buffer[64]
the buffer for rxBuffer
Definition: eBoard.h:864
[SPI] This is used to avoid path resolving issues and defines the common known Arduino SPI interface ...
Definition: eBoard.h:586
#define MACRO_MSG(mac, str)
Definition: eBoard.h:18
uint16_t numLEDs
stores the amount of LEDs
Definition: eBoard.h:2401
void SetServoLimit(int ID, int upperLimit)
Definition: eBoard.h:1551
I2CInOut(SoccerBoard &, optVAL_t, optVAL_t, optVAL_t, optVAL_t)
Definition: eBoard.h:1749
static void(* twi_onSlaveTransmit)(void)
Definition: eBoard.h:118
void button(int)
Definition: eBoard.h:1655
#define EBOARD_DEBUG_SPEED
Definition: eBoard.h:707
int velocity_temp
Definition: eBoard.h:1504
~NeoPixel(void)
Definition: eBoard.h:2434
optVAL_t countSetBits(optVAL_t x)
[COPY&PASTE] [CHECK_PWM] counts high-bits in an int/byte (determined by IGNORE_SIZE) ...
Definition: eBoard.h:1308
uint8_t ServoCount
Definition: eBoard.h:3602
byte pY
posY
Definition: eBoard.h:2133
#define LCD_COMMAND_DISPLAY_OFF
Definition: eBoard.h:2061
static uint8_t txBufferIndex
this defines the txBuffer Index - current position in txBuffer array
Definition: eBoard.h:346
TwoWire Wire
Definition: eBoard.h:543
#define PIN_BLUETOOTH_RX
Definition: eBoard.h:789
virtual int available(void)
Definition: eBoard.h:1202
void loop(void)
[COPY&PASTE] As we have an Arduino we need a setup function ;)
Definition: eBoard.h:3866
void SetMotormode(int ID, int velocity)
Definition: eBoard.h:1561
uint16_t _rx_delay_stopbit
the rx stopbit dely
Definition: eBoard.h:856
char channel(optVAL_t)
Definition: eBoard.h:1910
virtual size_t write(uint8_t data)
Definition: eBoard.h:473
This is used to avoid path resolving issues and defines the common known Arduino Wire-Interface &#160;&#160;&#160;...
Definition: eBoard.h:333
void led(int idx, bool state)
Definition: eBoard.h:1642
optVAL_t _OpwmValue
Definition: eBoard.h:1422
bool begun
true if NeoPixel::begin has been called
Definition: eBoard.h:2399
static void(* user_onReceive)(int numBytes)
twi slave [Rx]receive-event user def handler
Definition: eBoard.h:354
static void(* user_onRequest)(void)
twi slave [Tx]transmitting-event user def handler
Definition: eBoard.h:352
RB14Scan(void)
Definition: eBoard.h:1908
void setVelocity(int velocity)
Definition: eBoard.h:1523
void s2Cmd(optVAL_t o, optVAL_t t)
Definition: eBoard.h:2257
#define EBOARD_USE_RESET
Definition: eBoard.h:770
AX12Servo * connected[2]
stores the pointers to the registerd AX12Servo
Definition: eBoard.h:1863
void ledOff(int idx)
Definition: eBoard.h:1644
optVAL_t readPin(optVAL_t idx, bool dig=true)
read a digital state from an INPUTpin
Definition: eBoard.h:1460
uint8_t gamma8(uint8_t x) const
Definition: eBoard.h:3541
void ledMeter(int)
Definition: eBoard.h:1646
static const uint8_t PROGMEM _gammaTable[256]
Definition: eBoard.h:3521
virtual int read(void)
Definition: eBoard.h:500
#define EBOARD_PWM_SPE
Definition: eBoard.h:732
void writePin(optVAL_t idx, bool val)
write a boolean state to an output pin
Definition: eBoard.h:1437
void powerOn(optVAL_t id)
Definition: eBoard.h:1670
#define TRIM_DURATION
Definition: eBoard.h:3598
#define LCD_COMMAND_MODE
Definition: eBoard.h:2057
long store_bits
Definition: eBoard.h:1401
void changeModes(optVAL_t, optVAL_t, optVAL_t)
Definition: eBoard.h:1755
int8_t getPin(void)
void reset(void)
Definition: eBoard.h:1663
byte sendWait(const byte what)
Definition: eBoard.h:1518
void twi_init(void)
Definition: eBoard.h:129
bool _cI
called_guard
Definition: eBoard.h:2135
SIGNAL(TIMER1_COMPA_vect)
Definition: eBoard.h:3636
static void onReceiveService(uint8_t *inBytes, int numBytes)
Definition: eBoard.h:515
bool reset(void)
Definition: eBoard.h:2204
bool isMoving(void)
Definition: eBoard.h:1840
#define PIN_SHIFT_DAT
Definition: eBoard.h:816
#define EBOARD_SHIFT_REGISTER
Definition: eBoard.h:39
#define LCD_DATA_MODE
Definition: eBoard.h:2059
void sleep(uint16_t t)
Definition: eBoard.h:1672
void begin()
Definition: eBoard.h:1512
#define _SS_MAX_RX_BUFF
Definition: eBoard.h:833
void setTorque(uint16_t)
Definition: eBoard.h:1822
void changeMode(bool newMode=true)
Definition: eBoard.h:2235
NeoPixel pixels
the NeoPixel-object we use
volatile uint8_t * port
the used port register
Definition: eBoard.h:2416
void ledOn(void)
Definition: eBoard.h:1821
#define PIN_MOTOR_DIR
Definition: eBoard.h:804
#define LCD_COMMAND_DISPLAY_ON
Definition: eBoard.h:2063
int storedPos
stores the position the Servo should go to DynamixelBoard::action()
Definition: eBoard.h:1799
bool init(void)
Definition: eBoard.h:2209
static void(* twi_onSlaveReceive)(uint8_t *, int)
Definition: eBoard.h:119
volatile uint8_t * _receivePortRegister
the register the reveice pin is located on
Definition: eBoard.h:846
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
Definition: eBoard.h:3376
static void end(void)
Definition: eBoard.h:621
#define LCD_PAGE_ADDRESSING
Definition: eBoard.h:2071
int optVAL_t
Definition: eBoard.h:648
void rotate(int ID, int velocity)
Definition: eBoard.h:1533
void changeAddress(optVAL_t)
Definition: eBoard.h:1754
static void handle_interrupt(void)
Definition: eBoard.h:1110
int eVirtual_main()
this namespace contains all the Don&#39;t use manually classes ;)
Definition: eBoard.h:57
#define SERVOS_PER_TIMER
Definition: eBoard.h:3569
SoftwareSerial _serial(0x13, 0x12)
static uint8_t rxBuffer[]
this defines the rxBuffer used to enable delayed read
Definition: eBoard.h:336
uint8_t twi_transmit(const uint8_t *data, uint8_t length)
Definition: eBoard.h:192
bool isListening(void)
Definition: eBoard.h:916
DynamixelBoard * _conBoard
Definition: eBoard.h:1771
#define SPI_MODE_MASK
Definition: eBoard.h:579
static servo_t servos[(_Nbr_16timers *12)]
Definition: eBoard.h:3600
static volatile uint8_t twi_slarw
Definition: eBoard.h:115
#define LCD_COMMAND_CHARGE_PUMP_SETTING
Definition: eBoard.h:2076
uint64_t pin_out
Definition: eBoard.h:1321
#define PIN_BLUETOOTH_TX
Definition: eBoard.h:797
optVAL_t id
stores the id of the AX12Servo obejct
Definition: eBoard.h:1804
void msleep(uint16_t t)
Definition: eBoard.h:1673
static bool STOP
Definition: eBoard.h:641
void shiftAll(void)
[SHIFT] Changes bits according to store_bits
Definition: eBoard.h:1411
byte pX
the addressing mode (page/horizontal)
Definition: eBoard.h:2131
bool attached()
Definition: eBoard.h:3756
DynamixelBoard(SoccerBoard &)
Definition: eBoard.h:1866
ServoCds55 _servoHandler
Definition: eBoard.h:1588
void updateLength(uint16_t n)
Definition: eBoard.h:2445
int read()
Definition: eBoard.h:3744
static uint8_t rxBufferLength
this defines the length of rxBuffer
Definition: eBoard.h:340
#define PIN_BLUETOOTH_STATE
Definition: eBoard.h:781
static uint8_t rxBufferIndex
this defines the rxBuffer Index - current position in rxBuffer array
Definition: eBoard.h:338
void readI2C(optVAL_t deviceID, optVAL_t ret[], optVAL_t ret_len, bool blocking=true)
Reads a special amount of bits from a certain I²C-Device.
Definition: eBoard.h:1949
unsigned short rx_delay_stopbit
Definition: eBoard.h:934
#define PIN_SHIFT_CLK
Definition: eBoard.h:812
void setPin(optVAL_t idx, optVAL_t mode=0x1)
[COPY&PASTE] set a pin to a certain mode => checkPin() will return true then
Definition: eBoard.h:1341
uint16_t numBytes
stores the byte size [pixels] used internally
Definition: eBoard.h:2403
static volatile uint8_t twi_masterBufferLength
Definition: eBoard.h:122
void setPin(uint8_t p)
Definition: eBoard.h:3364
void SetID(int ID, int newID)
Definition: eBoard.h:1571
#define EBOARD_SPI_SERVO_MAX
Definition: eBoard.h:714
#define SPI_CLOCK_MASK
Definition: eBoard.h:581
void clear(void)
Definition: eBoard.h:3501
bool setCursor(byte posX=0x0, byte posY=0x0)
Definition: eBoard.h:2240
void twi_attachSlaveTxEvent(void(*function)(void))
Definition: eBoard.h:203
unsigned short rx_delay_intrabit
Definition: eBoard.h:933
int8_t max
Definition: eBoard.h:3594
static void finISR(timer16_Sequence_t timer)
Definition: eBoard.h:3662
static void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t *OCRnA)
Definition: eBoard.h:3610
uint8_t * getPixels(void) const
Definition: eBoard.h:3475
LCD(SoccerBoard &soccerBoard, optVAL_t id=0x3C)
Definition: eBoard.h:2145
#define LCD_COMMAND_WHITE_BACKGROUND
Definition: eBoard.h:2067
void waitForButton(int)
Definition: eBoard.h:1656
#define DEFAULT_PULSE_WIDTH
Definition: eBoard.h:3567
#define SERVO_MAX()
Definition: eBoard.h:3609
uint64_t pin_in
Definition: eBoard.h:1327
void motorsOff(void)
Definition: eBoard.h:1662
timer16_Sequence_t
Definition: eBoard.h:3564
int raw(optVAL_t)
Definition: eBoard.h:1909
volatile uint8_t * _transmitPortRegister
the register the reveice pin is located on
Definition: eBoard.h:850
#define TWI_FREQ
Definition: eBoard.h:93
static volatile uint8_t twi_txBufferIndex
Definition: eBoard.h:124
#define LCD_HEIGHT
Definition: eBoard.h:2085
void updateType(uint16_t t)
Definition: eBoard.h:2455
#define EBOARD_CLAMP
Definition: eBoard.h:752
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b)
Definition: eBoard.h:3440
NeoPixel(void)
Definition: eBoard.h:2429
[COPY&PASTE] [BLUETOOTH] This is the RB14Scan ghost struct :D
Definition: eBoard.h:1895
void changeBackground(bool newBackground=false)
Definition: eBoard.h:2252
static void begin(void)
Definition: eBoard.h:613
#define TWI_STX
Definition: eBoard.h:102
static void setClockDivider(uint8_t rate)
Definition: eBoard.h:627
#define TWI_SRX
Definition: eBoard.h:101
static void attachInterrupt(void)
Definition: eBoard.h:611
optVAL_t ID
ID of the Display.
Definition: eBoard.h:2127
void pingI2C(optVAL_t ret[], optVAL_t ret_len)
Sends a byte to a certain I²C-Device.
Definition: eBoard.h:1923
void motor(uint8_t id, int16_t val)
Definition: eBoard.h:1658
static volatile uint8_t twi_txBufferLength
Definition: eBoard.h:125
uint8_t sine8(uint8_t x) const
Definition: eBoard.h:3538
bool digital(optVAL_t id)
Definition: eBoard.h:1674
#define TWI_READY
Definition: eBoard.h:98
void onReceive(void(*function)(int))
Definition: eBoard.h:535
int storedSpe
stores the Speed of the Servo DynamixelBoard::action()
Definition: eBoard.h:1801
[COPY&PASTE] This is the DynamixelBoard ghost struct :D
Definition: eBoard.h:1843
char readVal(char oF='.')
[BLUETOOTH] reads a single value from bluetooth if available!
Definition: eBoard.h:1375
#define EBOARD_BLUETOOTH
Definition: eBoard.h:41
#define ticksToUs(_ticks)
Definition: eBoard.h:3597
#define EBOARD_NEO_GRB
Definition: eBoard.h:2285
#define SPI_CLOCK_DIV8
Definition: eBoard.h:567
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic=false)
Definition: eBoard.h:1135
void checkIdx(optVAL_t idx)
[DEBUG_MODE] used to check if a pin index is in bounds
Definition: eBoard.h:1296
bool checkOverflow(void)
[BLUETOOTH] checks if theres a lack of Data!
Definition: eBoard.h:1368
uint8_t rx_pin_read(void)
Definition: eBoard.h:1107
static SoftwareSerial * active_object
the active SoftwareSerial object to operate on
Definition: eBoard.h:870
#define REFRESH_INTERVAL
Definition: eBoard.h:3568
void write(const char *const val)
Definition: eBoard.h:1911
struct _DELAY_TABLE DELAY_TABLE
volatile unsigned int ticks
Definition: eBoard.h:3578
void WritePos(int ID, int Pos)
Definition: eBoard.h:1538
int upperLimit_temp
Definition: eBoard.h:1505
#define EBOARD_NEO
Definition: eBoard.h:49
void power(optVAL_t id, bool state)
Definition: eBoard.h:1669
void s1Dat(optVAL_t o)
Definition: eBoard.h:2267
#define PIN_MOTOR_SPE
Definition: eBoard.h:808
uint32_t endTime
stores the last call time of show for NeoPixel::canShow()
Definition: eBoard.h:2413
void changeId(optVAL_t)
Definition: eBoard.h:1871
uint16_t _tx_delay
the (generic) tx delay
Definition: eBoard.h:858
#define MIN_PULSE_WIDTH
Definition: eBoard.h:3565
void setBrightness(uint8_t val)
Definition: eBoard.h:3481
static uint8_t twi_masterBuffer[32]
Definition: eBoard.h:120
static volatile uint8_t twi_error
Definition: eBoard.h:128
void setSpeed(optVAL_t)
Definition: eBoard.h:1819
void lightOn(void)
Definition: eBoard.h:2198
void setTX(uint8_t transmitPin)
Definition: eBoard.h:1148
#define INVALID_SERVO
Definition: eBoard.h:3571
[COPY&PASTE] This is the I2CInOut ghost struct :D
Definition: eBoard.h:1727
bool timer_ofl
Definition: eBoard.h:3776
void lightOff(void)
Definition: eBoard.h:2201
unsigned short rx_delay_centering
Definition: eBoard.h:932
void set_steer_angle(optVAL_t ang)
Definition: eBoard.h:3878
bool clear(void)
Definition: eBoard.h:2161
void write(int ID, int Pos)
Definition: eBoard.h:1529
void twi_attachSlaveRxEvent(void(*function)(uint8_t *, int))
Definition: eBoard.h:200
#define usToTicks(_us)
Definition: eBoard.h:3596
static volatile uint8_t _receive_buffer_tail
size of rxBuffer
Definition: eBoard.h:866
bool s1Cmd(optVAL_t o)
Definition: eBoard.h:2261
#define SERVO_INDEX_TO_TIMER(_servo_nbr)
Definition: eBoard.h:3604
#define BUFFER_LENGTH
Definition: eBoard.h:330
static volatile uint8_t twi_sendStop
Definition: eBoard.h:116
SPIClass SPI
Definition: eBoard.h:632
void detach()
Definition: eBoard.h:3711
Servo()
Definition: eBoard.h:3685
#define EBOARD_CHECK_PINS
Definition: eBoard.h:680
static void tunedDelay(uint16_t delay)
Definition: eBoard.h:1011
uint8_t brightness
stores the brightness
Definition: eBoard.h:2407
uint8_t pinMask
the used pinMask
Definition: eBoard.h:2418
void __assert(const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp)
[DEBUG_MODE] custom assert message
Definition: eBoard.h:1267
static byte transfer(byte _data)
Definition: eBoard.h:606
void ledsOff(void)
Definition: eBoard.h:1645
#define SPI_2XCLOCK_MASK
Definition: eBoard.h:583
#define MAX_PULSE_WIDTH
Definition: eBoard.h:3566
void setPositionMode(void)
Definition: eBoard.h:1817
void Reset(int ID)
Definition: eBoard.h:1579
void setup(void)
this is a guard
Definition: eBoard.h:3793
void action(void)
Definition: eBoard.h:1876
bool changeBrightness(byte val=0x64)
Definition: eBoard.h:2246
void read(void)
Definition: eBoard.h:1753
optVAL_t analog(optVAL_t id)
Definition: eBoard.h:1675
void twi_setAddress(uint8_t address)
Definition: eBoard.h:140
void ledOn(int idx)
Definition: eBoard.h:1643
AX12Servo(void)
Definition: eBoard.h:1812
#define TWI_BUFFER_LENGTH
Definition: eBoard.h:96
void ledOn(optVAL_t)
Definition: eBoard.h:1873
ServoPin_t Pin
Definition: eBoard.h:3577
bool changeID(optVAL_t newID=0x3C)
Definition: eBoard.h:2157
void setPosition(int pos, int speed=0x3FF)
Definition: eBoard.h:1824
#define EBOARD_USE_UTILITY
Definition: eBoard.h:721
static uint8_t txAddress
this defines the txAddress the transmitting Dta
Definition: eBoard.h:342
static uint8_t transmitting
&#39;boolean&#39; value. Set to 1 if transmitting => in master write mode
Definition: eBoard.h:350
uint16_t _inverse_logic
determining if all pin reads etc whould be inverted (e.g. no pullup on rx);
Definition: eBoard.h:862
uint8_t attach(int pin)
Definition: eBoard.h:3693
void setPoslimit(int posLimit)
Definition: eBoard.h:1526
virtual int available(void)
Definition: eBoard.h:497
DynamixelBoard dBoard(board)
the dBoard object
void DebugPulse(uint8_t pin, uint8_t count)
Definition: eBoard.h:999
virtual void flush(void)
Definition: eBoard.h:1240
static void detachInterrupt(void)
Definition: eBoard.h:612
virtual int read(void)
Definition: eBoard.h:1193
bool is800KHz
determines the speed the communcation is working on
Definition: eBoard.h:2397
void begin(long speed)
Definition: eBoard.h:1164
uint16_t _rx_delay_centering
the rx center delay
Definition: eBoard.h:852
#define TWI_MTX
Definition: eBoard.h:100
uint8_t isActive
Definition: eBoard.h:3574
#define SERVO(_timer, _channel)
Definition: eBoard.h:3607
#define EBOARD_CHECK_PINS_PWM
Definition: eBoard.h:698
int cs
Definition: eBoard.h:1506
void beginTransmission(uint8_t address)
Definition: eBoard.h:454
static volatile uint8_t twi_rxBufferIndex
Definition: eBoard.h:127
#define EBOARD_DEBUG_MODE
Definition: eBoard.h:652
bool isConnected(void)
[BLUETOOTH] this will check if the HC-05 is paired
Definition: eBoard.h:1390
static void onRequestService(void)
Definition: eBoard.h:529
void print(const char *data)
Definition: eBoard.h:2208
void setSpeedMode(void)
Definition: eBoard.h:1818
void twi_reply(uint8_t ack)
Definition: eBoard.h:206
static volatile uint8_t twi_state
Definition: eBoard.h:114
static uint8_t txBuffer[]
this defines the txBuffer used to enable delayed read
Definition: eBoard.h:344
unsigned short tx_delay
Definition: eBoard.h:935
uint8_t _receivePin
the id of the receive pin
Definition: eBoard.h:842
#define _DEBUG_PIN2
Definition: eBoard.h:928
void writeMicroseconds(int value)
Definition: eBoard.h:3727
void drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY)
Definition: eBoard.h:2223
#define LCD_COMMAND_CHARGE_PUMP_ENABLE
Definition: eBoard.h:2078
#define LCD_WIDTH
Definition: eBoard.h:2081
#define EBOARD_NANO
Definition: eBoard.h:661
uint8_t twi_readFrom(uint8_t address, uint8_t *data, uint8_t length, uint8_t sendStop)
Definition: eBoard.h:143
void ledOff(void)
Definition: eBoard.h:1820
uint8_t servoIndex
Definition: eBoard.h:3592
void powerOff(optVAL_t id)
Definition: eBoard.h:1671
uint16_t _buffer_overflow
determining if an _buffer_overflow occured
Definition: eBoard.h:860
uint8_t _receiveBitMask
the pin mask to directly read from register (Rx)
Definition: eBoard.h:844
uint8_t twi_writeTo(uint8_t address, uint8_t *data, uint8_t length, uint8_t wait, uint8_t sendStop)
Definition: eBoard.h:167
optVAL_t sendI2C(optVAL_t deviceID, byte *buf, byte buf_len)
Sends a buffer of bytes to a certain I²C-Device.
Definition: eBoard.h:1935
PROGMEM const byte basicFont[][8]
Definition: eBoard.h:1956
uint8_t nbr
Definition: eBoard.h:3573
void begin(void)
Definition: eBoard.h:2438
void setRX(uint8_t receivePin)
Definition: eBoard.h:1155
static void initISR(timer16_Sequence_t timer)
Definition: eBoard.h:3650
static boolean isTimerActive(timer16_Sequence_t timer)
Definition: eBoard.h:3677
#define _DEBUG_PIN1
Definition: eBoard.h:927
[NEO] this allows you to access Adafruit LED-stripes
Definition: eBoard.h:2348
uint32_t getPixelColor(uint16_t n) const
Definition: eBoard.h:3446
void set_motor_speed(optVAL_t spe)
Definition: eBoard.h:3873
int readMicroseconds()
Definition: eBoard.h:3748
int timer_count
Definition: eBoard.h:3775
void changeMotorID(optVAL_t)
Definition: eBoard.h:1872
void show(void)
Definition: eBoard.h:2475
uint16_t numPixels(void) const
Definition: eBoard.h:3478
virtual int peek(void)
Definition: eBoard.h:508
void ledOff(optVAL_t)
Definition: eBoard.h:1874
#define EBOARD_NEO_800KHZ
Definition: eBoard.h:2343
void rept_task(void)
static uint8_t twi_txBuffer[32]
Definition: eBoard.h:123
#define cbi(sfr, bit)
Definition: eBoard.h:108
int8_t min
Definition: eBoard.h:3593
void trig_rept_task()
Definition: eBoard.h:3763
[I2C] [LCD] This is used to add support for OLED displays connected to the &#39;SoccerBoard&#39; ...
Definition: eBoard.h:2088
#define LCD_COMMAND_BLACK_BACKGROUND
Definition: eBoard.h:2065
void changeMotorID(optVAL_t newID)
Definition: eBoard.h:1815
static uint8_t twi_rxBuffer[32]
Definition: eBoard.h:126
Definition: eBoard.h:3580
#define TWI_MRX
Definition: eBoard.h:99
void onRequest(void(*function)(void))
Definition: eBoard.h:538
optVAL_t A
storing value for A-pin (🔧 I prevent errors!)
Definition: eBoard.h:1741
This is used to avoid path resolving issues and defines the common known Arduino SoftwareSerial inter...
Definition: eBoard.h:839