eBoard šŸ‰  ā‘ ā‘§ā‘Ø
Written for SIA 2017/2018
The source code

Welcome to the matrix (:

1 
7  #pragma GCC diagnostic push
8  #pragma GCC diagnostic ignored "-Wall"
9  #pragma GCC diagnostic ignored "-Wextra"
10  #pragma pack(push)
11  #pragma pack(1) //only works on mega sad^^
12 
390 //i am a guard... leave me alone :D
391 #ifndef EBOARD_HEADER_GUARD
392  #define EBOARD_HEADER_GUARD
393 
394  #ifdef DOC
395  #define ARDUINO 200
396 
399  #define EBOARD_I2C 0x1
400 
404  #define EBOARD_LCD 0x1
405 
408  #define EBOARD_SHIFT_REGISTER 0x1
409 
412  #define EBOARD_BLUETOOTH 0x1
413 
416  #define REPT_TASK
417 
420  #define __AVR_ATmega2560__
421 
424  #define __AVR_ATmega328P__
425 
428  #define EBOARD_NEO 0x1
429 
435  #define HIGHSPEED
436  #define __AVR__
438  #endif
439 
440  #include <avr/pgmspace.h>
445  namespace eagle_impl {}
446  using namespace eagle_impl;
447  #ifndef EBOARD_GUESSPATH
448 
451  #define EBOARD_GUESSPATH 0x1
452  #endif
453 
454  #if defined(ARDUINO) //general platform-check [No tab]
455 
459  #define main eVirtual_main //main has a different meaning^^
460 
461  #if ARDUINO >= 100 //this could be only Arduino.h but this snippet is portable :D
462  #include "Arduino.h"
463  #else
464  #include <wiring.h>
465  #endif
466 
467  #if not ( defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__))
468  #error "This library was build for ARDUINO UNO R3 Aand ARDUINO MEGA 2560!"
469  #endif
470 
471  #if defined(__AVR_ATmega2560__)
472 
475  #define PIN_MAX 0x32 //53 pins to address - 4 !!53 is SS
476  #else
477  #define PIN_MAX 0xA // 13 Pins to address - 4 !!10 is SS
478  #endif
479 
480  #include <avr/io.h>
481  #include <avr/interrupt.h>
482 
483  #if EBOARD_I2C > 0x0 && EBOARD_GUESSPATH > 0x0
484  #define twi_h
486 
487  #include <inttypes.h>
488 
489  //#define ATMEGA8
490 
491  #ifndef TWI_FREQ
492  #define TWI_FREQ 100000L
493  #endif
494 
495  #ifndef TWI_BUFFER_LENGTH
496  #define TWI_BUFFER_LENGTH 32
497  #endif
498 
499  #define TWI_READY 0
500  #define TWI_MRX 1
501  #define TWI_MTX 2
502  #define TWI_SRX 3
503  #define TWI_STX 4
504 
505  void twi_init(void);
506  void twi_setAddress(uint8_t);
507  uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
508  uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
509  uint8_t twi_transmit(const uint8_t*, uint8_t);
510  void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
511  void twi_attachSlaveTxEvent( void (*)(void) );
512  void twi_reply(uint8_t);
513  void twi_stop(void);
514  void twi_releaseBus(void);
515 
516  #include <math.h>
517  #include <stdlib.h>
518  #include <inttypes.h>
519  #include <avr/io.h>
520  #include <avr/interrupt.h>
521  #include <compat/twi.h>
522 
523  #ifndef cbi
524  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
525  #endif
526 
527  #ifndef sbi
528  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
529  #endif
530 
531  #include "pins_arduino.h"
532 
533  static volatile uint8_t twi_state;
534  static volatile uint8_t twi_slarw;
535  static volatile uint8_t twi_sendStop;
536  static volatile uint8_t twi_inRepStart;
537 
538  static void (*twi_onSlaveTransmit)(void);
539  static void (*twi_onSlaveReceive)(uint8_t*, int);
540 
541  static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
542  static volatile uint8_t twi_masterBufferIndex;
543  static volatile uint8_t twi_masterBufferLength;
544 
545  static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
546  static volatile uint8_t twi_txBufferIndex;
547  static volatile uint8_t twi_txBufferLength;
548 
549  static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
550  static volatile uint8_t twi_rxBufferIndex;
551 
552  static volatile uint8_t twi_error;
553 
554  void twi_init(void) {
555  twi_state = TWI_READY;
556  twi_sendStop = true;
557  twi_inRepStart = false;
558 
559  digitalWrite(SDA, 1);
560  digitalWrite(SCL, 1);
561 
562  cbi(TWSR, TWPS0);
563  cbi(TWSR, TWPS1);
564  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
565 
566  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
567  }
568 
569  void twi_setAddress(uint8_t address) {
570  TWAR = address << 1;
571  }
572 
573  uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) {
574  uint8_t i;
575 
576  if(TWI_BUFFER_LENGTH < length){
577  return 0;
578  }
579 
580  while(TWI_READY != twi_state){
581  continue;
582  }
583  twi_state = TWI_MRX;
584  twi_sendStop = sendStop;
585 
586  twi_error = 0xFF;
587 
588  twi_masterBufferIndex = 0;
589  twi_masterBufferLength = length-1;
590  twi_slarw = TW_READ;
591  twi_slarw |= address << 1;
592 
593  if (true == twi_inRepStart) {
594  twi_inRepStart = false;
595  TWDR = twi_slarw;
596  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
597  }
598  else
599  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
600 
601  while(TWI_MRX == twi_state){
602  continue;
603  }
604 
605  if (twi_masterBufferIndex < length)
606  length = twi_masterBufferIndex;
607 
608  for(i = 0; i < length; ++i){
609  data[i] = twi_masterBuffer[i];
610  }
611 
612  return length;
613  }
614 
615  uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
616  {
617  uint8_t i;
618 
619  if(TWI_BUFFER_LENGTH < length){
620  return 1;
621  }
622 
623  while(TWI_READY != twi_state){
624  continue;
625  }
626  twi_state = TWI_MTX;
627  twi_sendStop = sendStop;
628  twi_error = 0xFF;
629 
630  twi_masterBufferIndex = 0;
631  twi_masterBufferLength = length;
632 
633  for(i = 0; i < length; ++i){
634  twi_masterBuffer[i] = data[i];
635  }
636 
637  twi_slarw = TW_WRITE;
638  twi_slarw |= address << 1;
639 
640  if (true == twi_inRepStart) {
641  twi_inRepStart = false;
642  TWDR = twi_slarw;
643  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
644  }
645  else
646  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
647 
648  while(wait && (TWI_MTX == twi_state)){
649  continue;
650  }
651 
652  if (twi_error == 0xFF)
653  return 0;
654  else if (twi_error == TW_MT_SLA_NACK)
655  return 2;
656  else if (twi_error == TW_MT_DATA_NACK)
657  return 3;
658  else
659  return 4;
660  }
661 
662  uint8_t twi_transmit(const uint8_t* data, uint8_t length) {
663  uint8_t i;
664 
665  if(TWI_BUFFER_LENGTH < length){
666  return 1;
667  }
668 
669  if(TWI_STX != twi_state){
670  return 2;
671  }
672 
673  twi_txBufferLength = length;
674  for(i = 0; i < length; ++i){
675  twi_txBuffer[i] = data[i];
676  }
677 
678  return 0;
679  }
680 
681  void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) {
682  twi_onSlaveReceive = function;
683  }
684 
685  void twi_attachSlaveTxEvent( void (*function)(void) ) {
686  twi_onSlaveTransmit = function;
687  }
688 
689  void twi_reply(uint8_t ack) {
690  if(ack){
691  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
692  }else{
693  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
694  }
695  }
696 
697 
698  void twi_stop(void) {
699  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
700 
701  while(TWCR & _BV(TWSTO)){
702  continue;
703  }
704 
705  twi_state = TWI_READY;
706  }
707 
708  void twi_releaseBus(void){
709  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
710  twi_state = TWI_READY;
711  }
712 
713  ISR(TWI_vect) {
714  switch(TW_STATUS){
715  case TW_START:
716  case TW_REP_START:
717  TWDR = twi_slarw;
718  twi_reply(1);
719  break;
720 
721  case TW_MT_SLA_ACK:
722  case TW_MT_DATA_ACK:
723  if(twi_masterBufferIndex < twi_masterBufferLength){
724  TWDR = twi_masterBuffer[twi_masterBufferIndex++];
725  twi_reply(1);
726  }else{
727  if (twi_sendStop)
728  twi_stop();
729  else {
730  twi_inRepStart = true;
731  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
732  twi_state = TWI_READY;
733  }
734  }
735  break;
736  case TW_MT_SLA_NACK:
737  twi_error = TW_MT_SLA_NACK;
738  twi_stop();
739  break;
740  case TW_MT_DATA_NACK:
741  twi_error = TW_MT_DATA_NACK;
742  twi_stop();
743  break;
744  case TW_MT_ARB_LOST:
745  twi_error = TW_MT_ARB_LOST;
746  twi_releaseBus();
747  break;
748 
749  case TW_MR_DATA_ACK:
750  twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
751  case TW_MR_SLA_ACK:
752  if(twi_masterBufferIndex < twi_masterBufferLength){
753  twi_reply(1);
754  }else{
755  twi_reply(0);
756  }
757  break;
758  case TW_MR_DATA_NACK:
759  twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
760  if (twi_sendStop)
761  twi_stop();
762  else {
763  twi_inRepStart = true;
764  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
765  twi_state = TWI_READY;
766  }
767  break;
768  case TW_MR_SLA_NACK:
769  twi_stop();
770  break;
771  case TW_SR_SLA_ACK:
772  case TW_SR_GCALL_ACK:
773  case TW_SR_ARB_LOST_SLA_ACK:
774  case TW_SR_ARB_LOST_GCALL_ACK:
775  twi_state = TWI_SRX;
776  twi_rxBufferIndex = 0;
777  twi_reply(1);
778  break;
779  case TW_SR_DATA_ACK:
780  case TW_SR_GCALL_DATA_ACK:
781  if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
782  twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
783  twi_reply(1);
784  }else{
785  twi_reply(0);
786  }
787  break;
788  case TW_SR_STOP:
789  if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
790  twi_rxBuffer[twi_rxBufferIndex] = '\0';
791  }
792  twi_stop();
793  twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
794  twi_rxBufferIndex = 0;
795  twi_releaseBus();
796  break;
797  case TW_SR_DATA_NACK:
798  case TW_SR_GCALL_DATA_NACK:
799  twi_reply(0);
800  break;
801  case TW_ST_SLA_ACK:
802  case TW_ST_ARB_LOST_SLA_ACK:
803  twi_state = TWI_STX;
804  twi_txBufferIndex = 0;
805  twi_txBufferLength = 0;
806  twi_onSlaveTransmit();
807  if(0 == twi_txBufferLength){
808  twi_txBufferLength = 1;
809  twi_txBuffer[0] = 0x00;
810  }
811  case TW_ST_DATA_ACK:
812  TWDR = twi_txBuffer[twi_txBufferIndex++];
813  if(twi_txBufferIndex < twi_txBufferLength){
814  twi_reply(1);
815  }else{
816  twi_reply(0);
817  }
818  break;
819  case TW_ST_DATA_NACK:
820  case TW_ST_LAST_DATA:
821  twi_reply(1);
822  twi_state = TWI_READY;
823  break;
824 
825  case TW_NO_INFO:
826  break;
827  case TW_BUS_ERROR:
828  twi_error = TW_BUS_ERROR;
829  twi_stop();
830  break;
831  }
832  }
834  #include <inttypes.h>
835  #include "Stream.h"
836 
837  #define BUFFER_LENGTH 32
838  namespace eagle_impl {
855  class TwoWire : public Stream {
856  private:
858  static uint8_t rxBuffer[];
860  static uint8_t rxBufferIndex;
862  static uint8_t rxBufferLength;
863 
865  static uint8_t txAddress;
867  static uint8_t txBuffer[];
869  static uint8_t txBufferIndex;
871  static uint8_t txBufferLength;
872 
874  static uint8_t transmitting;
876  static void (*user_onRequest)(void);
881  static void (*user_onReceive)(int numBytes);
883  static void onRequestService(void);
889  static void onReceiveService(uint8_t* inBytes, int numBytes);
890 
891  public:
893  TwoWire();
895  void begin();
900  void begin(uint8_t address);
906  inline void begin(int address);
911  void beginTransmission(uint8_t address);
917  inline void beginTransmission(int address);
928  inline uint8_t endTransmission(void);
939  uint8_t endTransmission(uint8_t sendStop);
947  inline uint8_t requestFrom(uint8_t address, uint8_t quantity);
955  uint8_t requestFrom(uint8_t address , uint8_t quantity, uint8_t sendStop);
963  inline uint8_t requestFrom(int address, int quantity);
972  inline uint8_t requestFrom(int address, int quantity, int sendStop);
981  virtual size_t write(uint8_t data);
989  virtual size_t write(const uint8_t *data, size_t quantity);
994  virtual int available(void);
1000  virtual int read(void);
1006  virtual int peek(void);
1008  virtual void flush(void);
1015  void onReceive( void (*function)(int) );
1022  void onRequest( void (*function)(void) );
1023 
1024  /* Removed due to: not needed
1025  inline size_t write(unsigned long n) { return write((uint8_t)n); }
1026  inline size_t write(long n) { return write((uint8_t)n); }
1027  inline size_t write(unsigned int n) { return write((uint8_t)n); }
1028  inline size_t write(int n) { return write((uint8_t)n); }
1029  */
1030  using Print::write;
1031  };
1032  }
1033  extern "C" {
1034  #include <stdlib.h>
1035  #include <string.h>
1036  #include <inttypes.h>
1037  //#include "twi.h"
1038  }
1039 
1042  uint8_t TwoWire::rxBufferIndex = 0;
1043  uint8_t TwoWire::rxBufferLength = 0;
1044 
1045  uint8_t TwoWire::txAddress = 0;
1047  uint8_t TwoWire::txBufferIndex = 0;
1048  uint8_t TwoWire::txBufferLength = 0;
1049 
1050  uint8_t TwoWire::transmitting = 0;
1051  void (*TwoWire::user_onRequest)(void);
1052  void (*TwoWire::user_onReceive)(int);
1053 
1054  TwoWire::TwoWire() {}
1055 
1056  void TwoWire::begin(void) {
1057  rxBufferIndex = 0;
1058  rxBufferLength = 0;
1059 
1060  txBufferIndex = 0;
1061  txBufferLength = 0;
1062 
1063  twi_init();
1064  }
1065 
1066  void TwoWire::begin(uint8_t address) {
1067  twi_setAddress(address);
1068  twi_attachSlaveTxEvent(onRequestService);
1069  twi_attachSlaveRxEvent(onReceiveService);
1070  begin();
1071  }
1072 
1073  void TwoWire::begin(int address) {
1074  begin((uint8_t)address);
1075  }
1076 
1077  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
1078  if(quantity > BUFFER_LENGTH){
1079  quantity = BUFFER_LENGTH;
1080  }
1081  uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
1082  rxBufferIndex = 0;
1083  rxBufferLength = read;
1084 
1085  return read;
1086  }
1087 
1088  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
1089  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
1090  }
1091 
1092  uint8_t TwoWire::requestFrom(int address, int quantity) {
1093  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
1094  }
1095 
1096  uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
1097  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
1098  }
1099 
1100  void TwoWire::beginTransmission(uint8_t address) {
1101  transmitting = 1;
1102  txAddress = address;
1103  txBufferIndex = 0;
1104  txBufferLength = 0;
1105  }
1106 
1107  void TwoWire::beginTransmission(int address) {
1108  beginTransmission((uint8_t)address);
1109  }
1110 
1111  uint8_t TwoWire::endTransmission(uint8_t sendStop) {
1112  int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
1113  txBufferIndex = 0;
1114  txBufferLength = 0;
1115  transmitting = 0;
1116  return ret;
1117  }
1118 
1119  uint8_t TwoWire::endTransmission(void){
1120  return endTransmission(true);
1121  }
1122 
1123  size_t TwoWire::write(uint8_t data) {
1124  if(transmitting) {
1125  if(txBufferLength >= BUFFER_LENGTH) {
1126  setWriteError();
1127  return 0;
1128  }
1129  txBuffer[txBufferIndex] = data;
1130  ++txBufferIndex;
1132  }else{
1133  twi_transmit(&data, 1);
1134  }
1135  return 1;
1136  }
1137 
1138  size_t TwoWire::write(const uint8_t *data, size_t quantity) {
1139  if(transmitting){
1140  for(size_t i = 0; i < quantity; ++i) {
1141  write(data[i]);
1142  }
1143  }else{
1144  twi_transmit(data, quantity);
1145  }
1146  return quantity;
1147  }
1148 
1149  int TwoWire::available(void) {
1150  return rxBufferLength - rxBufferIndex;
1151  }
1152 
1153  int TwoWire::read(void) {
1154  int value = -1;
1155 
1157  value = rxBuffer[rxBufferIndex];
1158  ++rxBufferIndex;
1159  }
1160 
1161  return value;
1162  }
1163 
1164  int TwoWire::peek(void) {
1165  int value = -1;
1166 
1168  value = rxBuffer[rxBufferIndex];
1169  }
1170 
1171  return value;
1172  }
1173 
1174  void TwoWire::flush(void) {
1175  // XXX: to be implemented.
1176  }
1177 
1178  void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) {
1179  if(!user_onReceive){
1180  return;
1181  }
1182 
1184  return;
1185  }
1186 
1187  for(uint8_t i = 0; i < numBytes; ++i) {
1188  rxBuffer[i] = inBytes[i];
1189  }
1190  rxBufferIndex = 0;
1191  rxBufferLength = numBytes;
1192  user_onReceive(numBytes);
1193  }
1194 
1195  void TwoWire::onRequestService(void) {
1196  if(!user_onRequest) {
1197  return;
1198  }
1199 
1200  txBufferIndex = 0;
1201  txBufferLength = 0;
1202  user_onRequest();
1203  }
1204 
1205  void TwoWire::onReceive( void (*function)(int) ) {
1206  user_onReceive = function;
1207  }
1208 
1209  void TwoWire::onRequest( void (*function)(void) ) {
1210  user_onRequest = function;
1211  }
1212 
1214 
1216  TwoWire Wire = TwoWire();
1217 
1218  #endif
1219 
1222  #ifndef EBOARD_USE_SPI
1223  #define EBOARD_USE_SPI 0x1
1224  #endif
1225  #if EBOARD_USE_SPI > 0x0
1226  #define _SPI_H_INCLUDED
1228 
1229  #include <stdio.h>
1231  #define SPI_CLOCK_DIV4 0x00
1232  #define SPI_CLOCK_DIV16 0x01
1234  #define SPI_CLOCK_DIV64 0x02
1236  #define SPI_CLOCK_DIV128 0x03
1238  #define SPI_CLOCK_DIV2 0x04
1240  #define SPI_CLOCK_DIV8 0x05
1242  #define SPI_CLOCK_DIV32 0x06
1244 
1246  #define SPI_MODE0 0x00
1247  #define SPI_MODE1 0x04
1249  #define SPI_MODE2 0x08
1251  #define SPI_MODE3 0x0C
1253 
1255  #define SPI_MODE_MASK 0x0C
1256  #define SPI_CLOCK_MASK 0x03
1258  #define SPI_2XCLOCK_MASK 0x01
1260  namespace eagle_impl {
1274  struct SPIClass {
1280  inline static byte transfer(byte _data);
1284  inline static void attachInterrupt(void);
1288  inline static void detachInterrupt(void); // Default
1292  static void begin(void); // Default
1296  inline static void end(void);
1301  inline static void setBitOrder(uint8_t bitOrder);
1306  inline static void setDataMode(uint8_t mode);
1311  inline static void setClockDivider(uint8_t rate);
1312  };
1313  }
1315  byte SPIClass::transfer(byte _data) {
1316  SPDR = _data;
1317  while (!(SPSR & _BV(SPIF)));
1318  return SPDR;
1319  }
1320 
1321  void SPIClass::attachInterrupt() { SPCR |= _BV(SPIE);}
1322 
1323  void SPIClass::detachInterrupt() { SPCR &= ~_BV(SPIE);}
1324 
1325  void SPIClass::begin() {
1326  digitalWrite(SS, HIGH);
1327  pinMode(SS, OUTPUT); //doesn't block common use as_ OUTPUT!
1328  SPCR |= _BV(MSTR);
1329  SPCR |= _BV(SPE);
1330  pinMode(SCK, OUTPUT);
1331  pinMode(MOSI, OUTPUT);
1332  }
1333 
1334  void SPIClass::end() {SPCR &= ~_BV(SPE);}
1335 
1336  void SPIClass::setBitOrder(uint8_t bitOrder) {
1337  if(bitOrder == LSBFIRST) SPCR |= _BV(DORD);
1338  else SPCR &= ~(_BV(DORD));
1339  }
1340 
1341  void SPIClass::setDataMode(uint8_t mode) { SPCR = (SPCR & ~SPI_MODE_MASK) | mode; }
1342 
1343  void SPIClass::setClockDivider(uint8_t rate) {
1344  SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
1345  SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
1346  }
1348 
1349  SPIClass SPI;
1350 
1351  #endif
1352  #if (EBOARD_I2C > 0x0) && (EBOARD_LCD > 0x0)
1353  #include <avr/pgmspace.h>
1354  #endif
1355 
1361  static bool STOP = false;
1362 
1366  #ifdef IGNORE_SIZE
1367  typedef byte optVAL_t;
1368  #else
1369  typedef int optVAL_t;
1370  #endif
1371 
1375  #ifndef EBOARD_DEBUG_MODE
1376  #define EBOARD_DEBUG_MODE 0x1
1377  #endif
1378 
1382  #ifndef EBOARD_NANO
1383  #define EBOARD_NANO 0x0
1384  #endif
1385 
1388  #ifndef EBOARD_CHECK_PINS
1389  #define EBOARD_CHECK_PINS 0x1
1390  #endif
1391 
1392  #ifndef EBOARD_SHIFT_REGISTER
1393 
1396  #define EBOARD_SHIFT_REGISTER 0x0
1397  #endif
1398 
1402  #ifndef EBOARD_CHECK_PINS_PWM
1403  #define EBOARD_CHECK_PINS_PWM 0x1
1404  #endif
1405 
1409  #ifndef EBOARD_DEBUG_SPEED
1410  #define EBOARD_DEBUG_SPEED 9600
1411  #endif
1412 
1415  #ifndef EBOARD_SPI_SERVO_MAX
1416  #define EBOARD_SPI_SERVO_MAX 2
1417  #endif
1418 
1421  #ifndef EBOARD_USE_UTILITY
1422  #define EBOARD_USE_UTILITY 0x1
1423  #endif
1424 
1427  #define EBOARD_COPY_AND_PASTE 0x1
1428 
1431  #ifndef EBOARD_PWM_SPE
1432  #define EBOARD_PWM_SPE 1
1433  #endif
1434 
1435  #ifndef EBOARD_I2C
1436 
1439  #define EBOARD_I2C 0x0 //disabled by default
1440  #endif
1441 
1442  #ifndef EBOARD_BLUETOOTH
1443 
1446  #define EBOARD_BLUETOOTH 0x0
1447  #endif
1448 
1451  #ifndef EBOARD_CLAMP
1452  #define EBOARD_CLAMP 0x1
1453  #endif
1454 
1455 
1456  #ifndef EBOARD_NEO
1457 
1460  #define EBOARD_NEO 0x0
1461  #endif
1462 
1463 
1467  #ifndef EBOARD_USE_RESET
1468  #define EBOARD_USE_RESET 0x1
1469  #endif
1470 
1471  #if EBOARD_USE_RESET > 0x0
1472  #include <avr/wdt.h>
1473  #endif
1474 
1478  #ifndef PIN_BLUETOOTH_STATE
1479  #if defined(__AVR_ATmega2560__)
1480  #define PIN_BLUETOOTH_STATE 0x13 // 19
1481  #else
1482  #define PIN_BLUETOOTH_STATE 0x2
1483  #endif
1484  #endif
1485 
1489  #ifndef PIN_BLUETOOTH_RX
1490  #if defined(__AVR_ATmega2560__)
1491  #define PIN_BLUETOOTH_RX 0x13 // 19
1492  #else
1493  #define PIN_BLUETOOTH_RX 0x2
1494  #endif
1495  #endif
1496 
1500  #ifndef PIN_BLUETOOTH_TX
1501  #if defined(__AVR_ATmega2560__)
1502  #define PIN_BLUETOOTH_TX 0x12 // 18
1503  #else
1504  #define PIN_BLUETOOTH_TX 0x3
1505  #endif
1506  #endif
1507 
1511  #ifndef PIN_MOTOR_DIR
1512  #define PIN_MOTOR_DIR 0x4
1513  #endif
1514 
1518  #ifndef PIN_MOTOR_SPE
1519  #define PIN_MOTOR_SPE 0x5
1520  #endif
1521 
1525  #ifndef PIN_SHIFT_CLK
1526  #define PIN_SHIFT_CLK 0x6
1527  #endif
1528 
1531  #ifndef PIN_SHIFT_DAT
1532  #define PIN_SHIFT_DAT 0x7
1533  #endif
1534 
1537  #ifndef PIN_SHIFT_LAT
1538  #define PIN_SHIFT_LAT 0x8
1539  #endif
1540 
1541 
1542  //done by arduino
1543  //if this has an effect... something went wrong :D
1544  #ifndef HIGH
1545  #define HIGH 1
1546  #endif
1547  #ifndef LOW
1548  #define LOW 0
1549  #endif
1550 
1551  #if (EBOARD_BLUETOOTH > 0x0) && defined(__AVR_ATmega328P__)
1552  #if EBOARD_GUESSPATH > 0x0
1553  //again to resolve including errors we'll include the SoftwareSerial cpp file
1554 
1555  #define _SS_MAX_RX_BUFF 64 // RX buffer size
1556  #ifndef GCC_VERSION
1557  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
1558  #endif
1559  namespace eagle_impl {
1581  class SoftwareSerial : public Stream {
1582  private:
1584  uint8_t _receivePin;
1586  uint8_t _receiveBitMask;
1588  volatile uint8_t *_receivePortRegister;
1590  uint8_t _transmitBitMask;
1592  volatile uint8_t *_transmitPortRegister;
1593 
1595  uint16_t _rx_delay_centering;
1597  uint16_t _rx_delay_intrabit;
1599  uint16_t _rx_delay_stopbit;
1601  uint16_t _tx_delay;
1602 
1604  uint16_t _buffer_overflow:1;
1606  uint16_t _inverse_logic:1;
1608  static char _receive_buffer[_SS_MAX_RX_BUFF];
1610  static volatile uint8_t _receive_buffer_tail;
1612  static volatile uint8_t _receive_buffer_head;
1614  static SoftwareSerial *active_object;
1615 
1617  void recv(void);
1622  inline uint8_t rx_pin_read(void);
1627  inline void tx_pin_write(uint8_t pin_state);
1632  void setTX(uint8_t transmitPin);
1637  void setRX(uint8_t receivePin);
1642  static inline void tunedDelay(uint16_t delay);
1643 
1644  public:
1645  // public methods
1652  SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
1658  ~SoftwareSerial(void);
1674  void begin(long speed);
1679  bool listen(void);
1681  inline void end(void);
1686  inline bool isListening(void);
1691  inline bool overflow(void);
1696  int peek(void);
1703  virtual size_t write(uint8_t byte);
1708  virtual int read(void);
1713  virtual int available(void);
1717  virtual void flush(void);
1718  //used to save codespace
1719  using Print::write;
1721  static inline void handle_interrupt(void);
1722  };
1723  }
1725 
1726  bool SoftwareSerial::isListening(void) {
1727  return this == active_object;
1728  }
1729 
1730  bool SoftwareSerial::overflow(void) {
1731  bool ret = _buffer_overflow;
1732  _buffer_overflow = false;
1733  return ret;
1734  }
1735  /* was a workaround for arduino 0012 but not needed
1736  #undef int
1737  #undef char
1738  #undef long
1739  #undef byte
1740  #undef float
1741  #undef abs
1742  #undef round
1743  */
1744  #if EBOARD_DEBUG_MODE > 0x0
1745  #define _DEBUG 0
1746  #define _DEBUG_PIN1 11
1747  #define _DEBUG_PIN2 13
1748  #endif
1749  typedef struct _DELAY_TABLE {
1750  long baud;
1751  unsigned short rx_delay_centering;
1752  unsigned short rx_delay_intrabit;
1753  unsigned short rx_delay_stopbit;
1754  unsigned short tx_delay;
1755  } DELAY_TABLE;
1756 
1757  #if F_CPU == 16000000
1758 
1759  static const DELAY_TABLE PROGMEM table[] = {
1760  // baud rxcenter rxintra rxstop tx
1761  { 115200, 1, 17, 17, 12, },
1762  { 57600, 10, 37, 37, 33, },
1763  { 38400, 25, 57, 57, 54, },
1764  { 31250, 31, 70, 70, 68, },
1765  { 28800, 34, 77, 77, 74, },
1766  { 19200, 54, 117, 117, 114, },
1767  { 14400, 74, 156, 156, 153, },
1768  { 9600, 114, 236, 236, 233, },
1769  { 4800, 233, 474, 474, 471, },
1770  { 2400, 471, 950, 950, 947, },
1771  { 1200, 947, 1902, 1902, 1899, },
1772  { 600, 1902, 3804, 3804, 3800, },
1773  { 300, 3804, 7617, 7617, 7614, },
1774  };
1775 
1776  const int XMIT_START_ADJUSTMENT = 5;
1777 
1778  #elif F_CPU == 8000000
1779 
1780  static const DELAY_TABLE table[] PROGMEM = {
1781  // baud rxcenter rxintra rxstop tx
1782  { 115200, 1, 5, 5, 3, },
1783  { 57600, 1, 15, 15, 13, },
1784  { 38400, 2, 25, 26, 23, },
1785  { 31250, 7, 32, 33, 29, },
1786  { 28800, 11, 35, 35, 32, },
1787  { 19200, 20, 55, 55, 52, },
1788  { 14400, 30, 75, 75, 72, },
1789  { 9600, 50, 114, 114, 112, },
1790  { 4800, 110, 233, 233, 230, },
1791  { 2400, 229, 472, 472, 469, },
1792  { 1200, 467, 948, 948, 945, },
1793  { 600, 948, 1895, 1895, 1890, },
1794  { 300, 1895, 3805, 3805, 3802, },
1795  };
1796 
1797  const int XMIT_START_ADJUSTMENT = 4;
1798 
1799  #elif F_CPU == 20000000
1800 
1801  static const DELAY_TABLE PROGMEM table[] = {
1802  // baud rxcenter rxintra rxstop tx
1803  { 115200, 3, 21, 21, 18, },
1804  { 57600, 20, 43, 43, 41, },
1805  { 38400, 37, 73, 73, 70, },
1806  { 31250, 45, 89, 89, 88, },
1807  { 28800, 46, 98, 98, 95, },
1808  { 19200, 71, 148, 148, 145, },
1809  { 14400, 96, 197, 197, 194, },
1810  { 9600, 146, 297, 297, 294, },
1811  { 4800, 296, 595, 595, 592, },
1812  { 2400, 592, 1189, 1189, 1186, },
1813  { 1200, 1187, 2379, 2379, 2376, },
1814  { 600, 2379, 4759, 4759, 4755, },
1815  { 300, 4759, 9523, 9523, 9520, },
1816  };
1817 
1818  const int XMIT_START_ADJUSTMENT = 6;
1819 
1820  #else
1821  #error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
1822  #endif
1823 
1826  volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
1827  volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
1828  #if EBOARD_DEBUG_MODE > 0x0
1829  inline void DebugPulse(uint8_t pin, uint8_t count) {
1830  #if _DEBUG
1831  volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
1832 
1833  uint8_t val = *pport;
1834  while (count--)
1835  {
1836  *pport = val | digitalPinToBitMask(pin);
1837  *pport = val;
1838  }
1839  #endif
1840  }
1841  #endif
1842  inline void SoftwareSerial::tunedDelay(uint16_t delay) {
1843  uint8_t tmp=0;
1844 
1845  asm volatile("sbiw %0, 0x01 \n\t"
1846  "ldi %1, 0xFF \n\t"
1847  "cpi %A0, 0xFF \n\t"
1848  "cpc %B0, %1 \n\t"
1849  "brne .-10 \n\t"
1850  : "+r" (delay), "+a" (tmp)
1851  : "0" (delay)
1852  );
1853  }
1854 
1855  bool SoftwareSerial::listen() {
1856  if (active_object != this)
1857  {
1858  _buffer_overflow = false;
1859  uint8_t oldSREG = SREG;
1860  cli();
1862  active_object = this;
1863  SREG = oldSREG;
1864  return true;
1865  }
1866 
1867  return false;
1868  }
1869 
1870  void SoftwareSerial::recv() {
1871 
1872  #if GCC_VERSION < 40302
1873  asm volatile(
1874  "push r18 \n\t"
1875  "push r19 \n\t"
1876  "push r20 \n\t"
1877  "push r21 \n\t"
1878  "push r22 \n\t"
1879  "push r23 \n\t"
1880  "push r26 \n\t"
1881  "push r27 \n\t"
1882  ::);
1883  #endif
1884 
1885  uint8_t d = 0;
1886 
1887  if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) {
1888  // Wait approximately 1/2 of a bit width to "center" the sample
1890  #if EBOARD_DEBUG_MODE > 0x0
1891  DebugPulse(_DEBUG_PIN2, 1);
1892  #endif
1893  // Read each of the 8 bits
1894  for (uint8_t i=0x1; i; i <<= 1)
1895  {
1897  #if EBOARD_DEBUG_MODE > 0x0
1898  DebugPulse(_DEBUG_PIN2, 1);
1899  #endif
1900  uint8_t noti = ~i;
1901  if (rx_pin_read())
1902  d |= i;
1903  else
1904  d &= noti;
1905  }
1906 
1907  // skip the stop bit
1909  #if EBOARD_DEBUG_MODE > 0x0
1910  DebugPulse(_DEBUG_PIN2, 1);
1911  #endif
1912  if (_inverse_logic)
1913  d = ~d;
1914 
1916  _receive_buffer[_receive_buffer_tail] = d; // save new byte
1918  }
1919  else {
1920  #if EBOARD_DEBUG_MODE > 0x0
1921  #if _DEBUG // for scope: pulse pin as overflow indictator
1922  DebugPulse(_DEBUG_PIN1, 1);
1923  #endif
1924  #endif
1925  _buffer_overflow = true;
1926  }
1927  }
1928 
1929  #if GCC_VERSION < 40302
1930  asm volatile(
1931  "pop r27 \n\t"
1932  "pop r26 \n\t"
1933  "pop r23 \n\t"
1934  "pop r22 \n\t"
1935  "pop r21 \n\t"
1936  "pop r20 \n\t"
1937  "pop r19 \n\t"
1938  "pop r18 \n\t"
1939  ::);
1940  #endif
1941  }
1942 
1943  void SoftwareSerial::tx_pin_write(uint8_t pin_state) {
1944  if (pin_state == LOW)
1946  else
1948  }
1949 
1950  uint8_t SoftwareSerial::rx_pin_read() {
1952  }
1953 
1954  inline void SoftwareSerial::handle_interrupt() {
1955  if (active_object) {
1956  active_object->recv();
1957  }
1958  }
1959 
1960  #if defined(PCINT0_vect)
1961  ISR(PCINT0_vect) {
1963  }
1964  #endif
1965 
1966  #if defined(PCINT1_vect)
1967  ISR(PCINT1_vect) {
1969  }
1970  #endif
1971 
1972  #if defined(PCINT2_vect)
1973  ISR(PCINT2_vect) {
1975  }
1976  #endif
1977 
1978  #if defined(PCINT3_vect)
1979  ISR(PCINT3_vect) {
1981  }
1982  #endif
1983 
1984  SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
1985  _rx_delay_centering(0),
1986  _rx_delay_intrabit(0),
1987  _rx_delay_stopbit(0),
1988  _tx_delay(0),
1989  _buffer_overflow(false),
1990  _inverse_logic(inverse_logic) {
1991  setTX(transmitPin);
1992  setRX(receivePin);
1993  }
1994 
1995  SoftwareSerial::~SoftwareSerial() {
1996  end();
1997  }
1998 
1999  void SoftwareSerial::setTX(uint8_t tx) {
2000  pinMode(tx, OUTPUT);
2001  digitalWrite(tx, HIGH);
2002  _transmitBitMask = digitalPinToBitMask(tx);
2003  uint8_t port = digitalPinToPort(tx);
2004  _transmitPortRegister = portOutputRegister(port);
2005  }
2006 
2007  void SoftwareSerial::setRX(uint8_t rx) {
2008  pinMode(rx, INPUT);
2009  if (!_inverse_logic)
2010  digitalWrite(rx, HIGH);
2011  _receivePin = rx;
2012  _receiveBitMask = digitalPinToBitMask(rx);
2013  uint8_t port = digitalPinToPort(rx);
2014  _receivePortRegister = portInputRegister(port);
2015  }
2016 
2017  void SoftwareSerial::begin(long speed) {
2019 
2020  for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
2021  long baud = pgm_read_dword(&table[i].baud);
2022  if (baud == speed) {
2023  _rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
2024  _rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
2025  _rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
2026  _tx_delay = pgm_read_word(&table[i].tx_delay);
2027  break;
2028  }
2029  }
2030 
2031  if (_rx_delay_stopbit) {
2032  if (digitalPinToPCICR(_receivePin)) {
2033  *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
2034  *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
2035  }
2037  }
2038 
2039  #if _DEBUG
2040  pinMode(_DEBUG_PIN1, OUTPUT);
2041  pinMode(_DEBUG_PIN2, OUTPUT);
2042  #endif
2043 
2044  listen();
2045  }
2046 
2047  void SoftwareSerial::end() {
2048  if (digitalPinToPCMSK(_receivePin))
2049  *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
2050  }
2051 
2052 
2053  int SoftwareSerial::read() {
2054  if (!isListening())
2055  return -1;
2056 
2058  return -1;
2059 
2060  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
2062  return d;
2063  }
2064 
2066  if (!isListening())
2067  return 0;
2068 
2070  }
2071 
2072  size_t SoftwareSerial::write(uint8_t b) {
2073  if (_tx_delay == 0) {
2074  setWriteError();
2075  return 0;
2076  }
2077 
2078  uint8_t oldSREG = SREG;
2079  cli();
2080 
2081  tx_pin_write(_inverse_logic ? HIGH : LOW);
2082  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
2083 
2084  if (_inverse_logic) {
2085  for (byte mask = 0x01; mask; mask <<= 1) {
2086  if (b & mask)
2087  tx_pin_write(LOW);
2088  else
2089  tx_pin_write(HIGH);
2090 
2092  }
2093 
2094  tx_pin_write(LOW);
2095  }
2096  else {
2097  for (byte mask = 0x01; mask; mask <<= 1) {
2098  if (b & mask)
2099  tx_pin_write(HIGH);
2100  else
2101  tx_pin_write(LOW);
2103  }
2104 
2105  tx_pin_write(HIGH);
2106  }
2107 
2108  SREG = oldSREG;
2110 
2111  return 1;
2112  }
2113 
2114  void SoftwareSerial::flush() {
2115  if (!isListening())
2116  return;
2117 
2118  uint8_t oldSREG = SREG;
2119  cli();
2121  SREG = oldSREG;
2122  }
2123 
2124  int SoftwareSerial::peek() {
2125  if (!isListening())
2126  return -1;
2127 
2129  return -1;
2130 
2132  }
2134  #endif
2135 
2141  #endif
2142 
2143  #if EBOARD_DEBUG_MODE > 0x0
2144 
2147  #define __ASSERT_USE_STDERR
2148  #include <assert.h>
2166  void __assert (const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp);
2168  void __assert (const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp){
2169  Serial.print("Error with: "); Serial.print(__func);
2170  Serial.print(" in "); Serial.print(__file);
2171  Serial.print(" @"); Serial.println(__lineno, DEC);
2172  Serial.print(" >>");
2173  Serial.println(__sexp);
2174  if(strcmp(__func,"checkIdx")==0){
2175  Serial.println(" This happens if an out of bounds exception");
2176  Serial.println(" has occured. Following pins shouldn't be used:");
2177  Serial.print(" D");Serial.print(PIN_BLUETOOTH_RX);Serial.print("&");
2178  Serial.print("D");Serial.print(PIN_BLUETOOTH_TX);
2179  Serial.println(" : Used for Bluetooth communication");
2180  Serial.print(" D");Serial.print(PIN_MOTOR_DIR);Serial.print("&");
2181  Serial.print("D");Serial.print(PIN_MOTOR_SPE);
2182  Serial.println(" : Used for main motor control");
2183  #if EBOARD_USE_SPI > 0x0
2184  Serial.print(" D10-13");
2185  Serial.println(": Used for smart-servo-shield");
2186  #endif
2187  } else if (strcmp(__func,"readPin")==0){
2188  Serial.println("You've tried to access an analogPin that isn't present on the board you're currently working on!");
2189  }
2190  Serial.flush();
2191  abort(); // halt after outputting information
2192  }
2194  #endif
2195 
2202  inline void checkIdx(optVAL_t idx);
2204  inline void checkIdx(optVAL_t idx){
2205  #if EBOARD_DEBUG_MODE > 0x0
2206  assert(idx>=0x0 && idx < PIN_MAX); //changed pins? change me! (didn't want to use macros)
2207  assert(idx!=PIN_BLUETOOTH_RX&&idx!=PIN_BLUETOOTH_TX);
2208  #endif
2209  }
2211 
2212  #if EBOARD_COPY_AND_PASTE > 0x0
2213  #if EBOARD_CHECK_PINS_PWM > 0x0
2214 
2223  optVAL_t count; //dont't want to overuse global space^^
2224  for (count = 0; x; count++)
2225  x &= x - 1;
2226  return count;
2227  }
2229  #endif
2230 
2231  #if EBOARD_CHECK_PINS > 0x0
2232 
2237  #if defined(__AVR_ATmega328P__) && not defined(__AVR_ATmega2560__)
2238  uint16_t pin_out = 0x0;
2239  #elif defined(__AVR_ATmega2560__)
2240  uint64_t pin_out = 0x0;
2241  #endif
2242 
2245  #if defined(__AVR_ATmega328P__) && not defined(__AVR_ATmega2560__)
2246  uint16_t pin_in = 0x0;
2247  #elif defined(__AVR_ATmega2560__)
2248  uint64_t pin_in = 0x0;
2249  #endif
2250 
2260  inline bool checkPin(optVAL_t idx, optVAL_t mode = OUTPUT);
2262  inline bool checkPin(optVAL_t idx, optVAL_t mode){
2263  checkIdx(idx);
2264  return (mode == OUTPUT)? ((pin_out & (1<<idx))>0x0):((pin_in & (1<<idx))>0x0);
2265  }
2267  #endif
2268 
2274  void setPin(optVAL_t idx, optVAL_t mode = OUTPUT);
2276  void setPin(optVAL_t idx, optVAL_t mode){
2277  #if EBOARD_CHECK_PINS > 0x0
2278  checkIdx(idx);
2279  if(mode==OUTPUT) { //possible to read from OUTPUT digital ... we won't do it
2280  pin_out |= (1<<idx);
2281  pin_in &= ~(1<<idx);
2282  }
2283  else {
2284  pin_in |= (1<<idx);
2285  pin_out &= ~(1<<idx);
2286  }
2287  #endif
2288  pinMode(idx, mode);
2289  }
2291  #endif
2292 
2293  #if EBOARD_BLUETOOTH > 0x0
2294 
2302  inline char readVal(char oF = '.');
2310  inline bool checkOverflow(void);
2315  template <typename T>
2316  inline void writeVal(const T& val);
2317 
2329  inline bool isConnected(void);
2331  inline bool checkOverflow(void) {
2332  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
2333  return false; //there is no hardware provided control for hardwareserial overflow
2334  #else
2335  return (_serial.overflow());
2336  #endif
2337  }
2338  inline char readVal(char oF) {
2339  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
2340  return ((Serial1.available())?(Serial1.read()):(oF));
2341  #else
2342  return ((_serial.available())?(_serial.read()):(oF));
2343  #endif
2344  }
2345  template<typename T>
2346  inline void writeVal(const T& val){
2347  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
2348  Serial1.write(val);
2349  #else
2350  _serial.write(val);
2351  #endif
2352  }
2353  inline bool isConnected(void) {
2354  #if PIN_BLUETOOTH_RX != PIN_BLUETOOTH_STATE
2355  return digitalRead(PIN_BLUETOOTH_STATE);
2356  #else
2357  return true;
2358  #endif
2359  }
2361  #endif
2362 
2363  #if EBOARD_SHIFT_REGISTER > 0x0
2364 
2367  long store_bits = 0L;
2376  inline void shiftSingle(optVAL_t idx, bool val);
2380  void shiftAll(void);
2382  inline void shiftSingle(optVAL_t idx, bool val) {
2383  bitWrite(store_bits,idx,val);
2384  shiftAll();
2385  }
2386 
2387  void shiftAll(void){
2388  digitalWrite(PIN_SHIFT_LAT,LOW);
2389  for(optVAL_t c = 0; (c<32 && !STOP); c++){
2390  digitalWrite(PIN_SHIFT_CLK,LOW);
2391  shiftOut(PIN_SHIFT_DAT,PIN_SHIFT_CLK,MSBFIRST,bitRead(store_bits,c));
2392  }
2393  digitalWrite(PIN_SHIFT_LAT,LOW);
2394  }
2396  #endif
2397 
2399  optVAL_t _pwmValue = 0x0, _OpwmValue = 0x0;
2400 
2408  inline void writePWM (optVAL_t val);
2410  inline void writePWM(optVAL_t val){
2411  val = min(val,0xFF); val = max(0x0,val);
2412  _pwmValue = val;
2413  }
2414 
2415  #ifdef REPT_TASK
2416  extern void rept_task(void);
2417  #endif
2418 
2419  ISR(TIMER1_COMPA_vect) {
2420  if (_pwmValue!=_OpwmValue){
2421  analogWrite(PIN_MOTOR_SPE,_pwmValue);
2423  }
2424  #ifdef REPT_TASK
2425  rept_task();
2426  #endif
2427  }
2428 
2430 
2439  inline void writePin(optVAL_t idx,bool val);
2441  inline void writePin(optVAL_t idx,bool val){
2442  #if EBOARD_SHIFT_REGISTER > 0x0
2443  if(idx>0x63) {
2444  idx -= 0x64;
2445  shiftSingle(idx,val);
2446  return;
2447  }
2448  #endif
2449  #if EBOARD_CHECK_PINS > 0x0
2450  checkIdx(idx);
2451  if(!checkPin(idx))
2452  #endif
2453  #if EBOARD_COPY_AND_PASTE > 0x0
2454  setPin(idx);
2455  #else
2456  pinMode(idx,OUTPUT);
2457  #endif
2458  digitalWrite(idx,val);
2459  }
2461 
2471  inline optVAL_t readPin(optVAL_t idx,bool dig = true);
2473  inline optVAL_t readPin(optVAL_t idx,bool dig){
2474  #if EBOARD_CHECK_PINS > 0x0
2475  if(dig) checkIdx(idx);
2476  #if defined (__AVR_ATmega2560__)
2477  else if (idx<0||idx>0xF){ //use I2C? change => Wire
2478  #else
2479  else if (idx<0||idx>0x7){ //use I2C? change => Wire
2480  #endif
2481  #if EBOARD_DEBUG_MODE > 0x0
2482  assert(false);
2483  #endif
2484  return 0;
2485  }
2486  if(dig && !checkPin(idx,INPUT))
2487  #endif
2488  #if EBOARD_COPY_AND_PASTE > 0x0
2489  setPin(idx,INPUT);
2490  #else
2491  pinMode(idx,INPUT);
2492  #endif
2493  return((dig)? digitalRead(idx) : analogRead(idx));
2494  }
2496 
2497  #if EBOARD_USE_SPI > 0x0 && (EBOARD_NANO == 0x0)
2498  namespace eagle_impl {
2525  struct ServoCds55 {
2533  #if defined(__AVR_ATmega2560__)
2534  ServoCds55(optVAL_t CS=53);
2535  #else
2536  ServoCds55(optVAL_t CS=10);
2537  #endif
2538  void begin();
2548  void WritePos(optVAL_t ID,optVAL_t Pos);
2555  inline void write(optVAL_t ID,optVAL_t Pos);
2561  void setVelocity(optVAL_t velocity);
2569  void setPosLimit(optVAL_t posLimit);
2573  void rotate(optVAL_t,optVAL_t);
2582  void SetServoLimit(optVAL_t ID,optVAL_t upperLimit);
2591  void SetMotormode(optVAL_t ID, optVAL_t velocity);
2600  void SetID(optVAL_t ID, optVAL_t newID);
2606  void Reset(optVAL_t ID);
2615  byte sendWait(const byte what);
2616 
2618  int upperLimit_temp;
2619 
2620  private:
2624  optVAL_t cs;
2625  // @brief prevents arduino from endless recallocating memory
2626  byte tmp;
2627  };
2628  }
2630  ServoCds55::ServoCds55 (optVAL_t CS):cs(CS) {
2631  this->velocity_temp = 0x96;
2632  this->upperLimit_temp = 0x12C; //keep default range of +-300
2633  }
2634 
2635  void ServoCds55::begin() {
2636  pinMode(this->cs,OUTPUT);
2637  digitalWrite(this->cs,HIGH);
2638  SPI.begin ();
2640  }
2641 
2642  byte ServoCds55::sendWait(const byte what) {
2643  this->tmp = SPI.transfer (what);
2644  delayMicroseconds (20);
2645  return this->tmp;
2646  }
2647 
2648  inline void ServoCds55::setVelocity(optVAL_t velocity){this->velocity_temp = velocity;}
2649  inline void ServoCds55::setPosLimit(optVAL_t posLimit){this->upperLimit_temp = posLimit;}
2650 
2651  inline void ServoCds55::write(optVAL_t ID,optVAL_t Pos){
2652  WritePos(ID,Pos);
2653  }
2654 
2655  void ServoCds55::rotate(optVAL_t ID,optVAL_t velocity){}
2656 
2657  void ServoCds55::WritePos(optVAL_t ID,optVAL_t Pos){
2658  digitalWrite(this->cs, LOW);
2659  sendWait('p'); sendWait(ID); sendWait((Pos>>0x8 & 0xff));
2660  sendWait((Pos & 0xff)); sendWait((this->velocity_temp>>0x8 & 0xff)); sendWait((this->velocity_temp & 0xff));
2661  sendWait('\t'); sendWait('\r'); sendWait('\n');
2662  digitalWrite(this->cs, HIGH);
2663  delay(8);
2664  }
2665 
2666  void ServoCds55::SetServoLimit(optVAL_t ID,optVAL_t upperLimit_tempT){
2667  digitalWrite(this->cs, LOW);
2668  sendWait('s'); sendWait(ID); sendWait((upperLimit_tempT>>0x8 & 0xff));
2669  sendWait((upperLimit_tempT & 0xff)); sendWait('\t'); sendWait('\r');
2670  sendWait('\n');
2671  digitalWrite(this->cs, HIGH);
2672  delay(8);
2673  }
2674 
2675  void ServoCds55::SetMotormode(optVAL_t ID, optVAL_t velocity){
2676  digitalWrite(this->cs, LOW);
2677  sendWait('m'); sendWait(ID); sendWait((velocity>>0x8 & 0xff));
2678  sendWait((velocity & 0xff)); sendWait('\t'); sendWait('\r');
2679  sendWait('\n');
2680  digitalWrite(this->cs, HIGH);
2681  delay(8);
2682  }
2683 
2684  void ServoCds55::SetID(optVAL_t ID, optVAL_t newID){
2685  digitalWrite(this->cs, LOW);
2686  sendWait('i'); sendWait(ID); sendWait(newID);
2687  sendWait('\t'); sendWait('\r'); sendWait('\n');
2688  digitalWrite(this->cs, HIGH);
2689  delay(8);
2690  }
2691 
2692  void ServoCds55::Reset(optVAL_t ID){
2693  digitalWrite(this->cs, LOW);
2694  sendWait('r'); sendWait(ID); sendWait('\t');
2695  sendWait('\r'); sendWait('\n');
2696  digitalWrite(this->cs, HIGH);
2697  delay(8);
2698  }
2700 
2703  #endif
2704 
2705  #if EBOARD_COPY_AND_PASTE > 0x0 && EBOARD_NANO == 0
2706 
2730  struct SoccerBoard {
2735  inline SoccerBoard(void);
2736  //inline ~SoccerBoard(void) {}
2737  #if EBOARD_USE_UTILITY > 0x0 or defined(__AVR_ATmega2560__) //won't shrink space... just speed things up
2738 
2746  inline void led(int idx,bool state);
2754  inline void ledOn(int idx);
2762  inline void ledOff(int idx);
2768  inline void ledsOff(void);
2774  inline void ledMeter(int);
2775 
2776  #endif
2777  #if EBOARD_USE_UTILITY > 0x0
2778  inline void /*bool*/ button(int);
2781  inline void waitForButton(int);
2782  #endif
2783 
2793  inline void motor(uint8_t id,int16_t val);
2795  inline void motorsOff(void);
2796  //ARDUINO UNO PINOUT
2797  //D0,D1 => Bluetooth connection
2798  //D4,D5 => MotorControl (D5: 980Hz)
2799  //D10,D13 => SPI
2800 
2810  inline void power(optVAL_t id, bool state);
2820  inline void powerOn(optVAL_t id);
2830  inline void powerOff(optVAL_t id);
2836  inline void sleep(uint16_t t);
2842  inline void msleep(uint16_t t);
2850  inline bool digital (optVAL_t id);
2858  inline optVAL_t analog (optVAL_t id);
2860  inline void reset(void); /* use crash-reset? =>*/ /* wdt_enable(WDTO_15MS); while(1) {} */
2861  };
2863  SoccerBoard::SoccerBoard(void) {}
2864 
2865  #if defined(__AVR_ATmega2560__)
2866  inline void SoccerBoard::led(int idx, bool state) {writePin(13,state);}
2867  void SoccerBoard::ledOn(int) {writePin(13,HIGH);}
2868  void SoccerBoard::ledOff(int) {writePin(13,LOW);}
2869  void SoccerBoard::ledsOff(void) {writePin(13,LOW);}
2870  void SoccerBoard::ledMeter(int) {writePin(13,HIGH);}
2871  #elif EBOARD_USE_UTILITY > 0x0
2872  void SoccerBoard::led(int, bool) {}
2873  void SoccerBoard::ledOn(int) {}
2874  void SoccerBoard::ledOff(int) {}
2875  void SoccerBoard::ledsOff(void) {}
2876  void SoccerBoard::ledMeter(int) {}
2877  #endif
2878 
2879  #if EBOARD_USE_UTILITY > 0x0
2880  void SoccerBoard::button(int) {}
2881  void SoccerBoard::waitForButton(int) {}
2882  #endif
2883 
2884  void SoccerBoard::motor(uint8_t id,int16_t val) {
2885  if(id==0&&(val>-256 && val < 256)) {setPin(PIN_MOTOR_DIR,val<0); writePWM(abs(val));}
2886  else if(id>0&&id<3&&(val>-0 && val < 1024)) {_servoHandler.write((id-1),(val *600/1023 - 300));}
2887  }
2888  void SoccerBoard::motorsOff(void) {writePWM(0);}
2889 
2890  void SoccerBoard::reset(void) {
2891  #if EBOARD_USE_RESET > 0x0
2892  wdt_enable(WDTO_15MS);
2893  while(true) {}
2894  #endif
2895  }
2896 
2897  void SoccerBoard::power(optVAL_t id, bool state) {writePin(id,state);}
2898  void SoccerBoard::powerOn(optVAL_t id) {this->power(id,1);}
2899  void SoccerBoard::powerOff(optVAL_t id) {this->power(id,0);}
2900  void SoccerBoard::sleep(uint16_t t) {delay(1000*t);}
2901  void SoccerBoard::msleep(uint16_t t) {delay(t);}
2902  bool SoccerBoard::digital (optVAL_t id) {return readPin(id);}
2903  optVAL_t SoccerBoard::analog (optVAL_t id) {return readPin(id,0);}
2904 
2905  //@endcond
2906  //To avoid not_found issues
2908  #define DIGITAL_IN 0x0
2909  #define DIGITAL_IN_INV 0x1
2911  #define DIGITAL_IN_PULLUP 0x2
2913  #define DIGITAL_IN_PULLUP_INV 0x3
2915  #define DIGITAL_OUT 0x4
2917  #define DIGITAL_OUT_INV 0x5
2919  #define DIGITAL_OUT_LOW 0x6
2921  #define DIGITAL_OUT_HIGH 0x7
2923  #define ANALOG_IN_8_BIT 0x8
2925  #define ANALOG_IN_10_BIT 0x9
2927  #define ANALOG_IN_MEAN_8_BIT 0xA
2929  #define ANALOG_IN_MEAN_10_BIT 0xB
2931  #define COUNTER_8_BIT 0xC
2933  #define COUNTER_16_BIT 0xD
2935  #define COUNTER_RISE_8_BIT 0xE
2937  #define COUNTER_RISE_16_BIT 0xF
2939  #define PWM_SLOW 0x8
2941  #define PWM_FAST 0x9
2943  #define FREQ_LOW 0xA
2945  #define FREQ_HIGH 0xB
2947  #define COUNTER_B_DIR 0xC
2949  #define COUNTER_B_DIR_PULLUP 0xD
2951  #define COUNTER_MEAN_8_BIT 0xE
2953  #define COUNTER_MEAN_16_BIT 0xF
2955 
2979  struct I2CInOut{
2986  #if EBOARD_USE_UTILITY > 0x0
2987  inline void read(void);
2990  inline void changeAddress(optVAL_t);
2992  inline void changeModes(optVAL_t,optVAL_t,optVAL_t);
2993  #endif
2994 
2998  inline void write(void);
2999 
3001  optVAL_t A; //if you've used uint16_t values you'll have to replace it here
3002  //we only have B - DiOut and C - AO [OUT]
3004  optVAL_t B;
3006  optVAL_t C;
3007  };
3010  this->A=0x0;this->B=0x0;this->C=0x0;
3011  }
3012  #if EBOARD_USE_UTILITY > 0x0
3013  void I2CInOut::read(void) {}
3016  #endif
3017  void I2CInOut::write(void){
3018  setPin(PIN_MOTOR_DIR,((this->B)!=0x0));
3019  writePWM(this->C);
3020  }
3022 
3024  struct DynamixelBoard;
3026 
3049  struct AX12Servo {
3054  AX12Servo(void);
3061  AX12Servo(DynamixelBoard &dBoard, optVAL_t servoID); //if borders => setPosLimit
3062 
3063  DynamixelBoard *_conBoard;
3064 
3065  #if EBOARD_USE_UTILITY > 0x0
3066 
3073  inline void setID(optVAL_t newID);
3082  inline void changeMotorID(optVAL_t newID); //this should change the hardwareaddress...
3088  inline void setPositionMode(void);
3094  inline void setSpeedMode(void);
3100  inline void setSpeed(optVAL_t);
3102  inline void ledOff(void);
3104  inline void ledOn(void);
3106  inline void setTorque(uint16_t);
3107  #endif
3108 
3116  void setPosition(int pos, int speed=0x3FF);
3124  inline void storePosition(int pos, int speed = 0x3FF);
3130  inline optVAL_t getPosition(void);
3138  inline bool isMoving(void);
3144  int storedPos;
3150  int storedSpe;
3151 
3152  //bool posMode; //we don't care wich mode we are in ^^
3153 
3155  optVAL_t id;
3156  private:
3158  int actPos;
3160  int actSpe;
3161 
3162  }; //shield //set limits auto register for begin
3163 
3165  AX12Servo::AX12Servo(void) {}
3166  #if EBOARD_USE_UTILITY > 0x0
3167  void AX12Servo::setID(optVAL_t newID) {this->id = newID;_servoHandler.SetServoLimit(this->id,_servoHandler.upperLimit_temp);}
3168  void AX12Servo::changeMotorID(optVAL_t newID) {this->id = newID;} //this should change the hardwareaddress...
3169  //IF needed: _servoHandler.setID(this->id, newID);
3170  void AX12Servo::setPositionMode(void) {}
3171  void AX12Servo::setSpeedMode(void) {}
3172  void AX12Servo::setSpeed(optVAL_t) {} //i won't use the rotate functions...
3173  void AX12Servo::ledOff(void) {} //noone needs the AX12-Servo LED
3174  void AX12Servo::ledOn(void) {} //really.... noone ^^
3175  void AX12Servo::setTorque(uint16_t) {} //which damn register? xD
3176  #endif
3177 
3178  void AX12Servo::setPosition(int pos, int speed) {
3179  #if EBOARD_CLAMP > 0x0
3180  if(pos>1023 || speed > 1023) return;
3181  this->actPos=pos; this->storedPos=pos; this->storedSpe = speed;
3182  speed = speed*600/1023 - 300;
3183  pos = pos *600/1023 - 300;
3184 
3185  #else
3186  if(pos>300 || speed > 300) return;
3187  this->actPos=pos; this->storedPos=pos; this->storedSpe = speed;
3188  #endif
3189  if(speed != actSpe){ _servoHandler.setVelocity(speed); this->actSpe=speed;}
3190  _servoHandler.write(this->id,pos);
3191  }
3193  return this->actPos; //when moving... false value;
3194  }
3195  bool AX12Servo::isMoving(void) {return false;} //we don't know^^
3197 
3220  struct DynamixelBoard {
3224  inline DynamixelBoard(SoccerBoard&);
3225  //inline ~DynamixelBoard(void) {}
3226  #if EBOARD_USE_UTILITY > 0x0
3227  inline void changeId(optVAL_t);
3230  inline void changeMotorID(optVAL_t);
3232  inline void ledOn(optVAL_t);
3234  inline void ledOff(optVAL_t);
3235  #endif
3236  inline void action(void);
3238 
3240  friend struct AX12Servo;
3241  protected:
3247  AX12Servo* connected[EBOARD_SPI_SERVO_MAX];
3248  };
3251  for(optVAL_t i = 0; i < EBOARD_SPI_SERVO_MAX; i++ ) {this->connected[i] = NULL;} //wanna use nullptr... wanna have c++11^^
3252  }
3253  //inline ~DynamixelBoard(void) {}
3254  #if EBOARD_USE_UTILITY > 0x0
3259  #endif
3260  void DynamixelBoard::action(void) {
3261  for(optVAL_t i = 0; (i < EBOARD_SPI_SERVO_MAX && !STOP); i++ ){
3262  if(this->connected[i] != NULL)
3263  (*connected[i]).setPosition((*connected[i]).storedPos,(*connected[i]).storedSpe);
3264  }
3265  }
3266 
3267 
3268  void AX12Servo::storePosition(int pos, int speed){
3269  if(this->id < EBOARD_SPI_SERVO_MAX) _conBoard->connected[this->id] = this;
3270  this->storedPos=pos;this->storedSpe=speed;
3271  }
3272  AX12Servo::AX12Servo(DynamixelBoard &dBoard, optVAL_t servoID): _conBoard( &dBoard),id(servoID-1), actSpe(0x96) {
3273  //#if EBOARD_DEBUG_MODE > 0x0
3274  // assert(servoID<EBOARD_SPI_SERVO_MAX);
3275  //#endif
3276  }
3278  #endif
3279  #if EBOARD_BLUETOOTH > 0x0
3280 
3308  struct RB14Scan {
3312  inline RB14Scan(void);
3315  inline int raw(optVAL_t);
3318  inline char channel(optVAL_t);
3324  inline void write(const char* const val);
3325  };
3326 
3328  inline RB14Scan::RB14Scan(void) {}
3329  inline int RB14Scan::raw(optVAL_t) {return isConnected();}
3330  inline char RB14Scan::channel(optVAL_t) {return ((isConnected())?(readVal()):(-1));}
3331  inline void RB14Scan::write(const char* const val) {writeVal(val);}
3333 
3341  #endif
3342 #if EBOARD_I2C > 0x0
3343 
3358  inline optVAL_t sendI2C(optVAL_t deviceID,byte *buf, byte buf_len);
3359 
3374  inline optVAL_t sendI2C(optVAL_t deviceID, byte buf);
3375 
3384  inline void pingI2C(optVAL_t ret[], optVAL_t ret_len);
3386  inline void pingI2C(optVAL_t ret[], optVAL_t ret_len){
3387  optVAL_t count = 0;
3388  for (byte i = 1; (i < 255 && !STOP); i++) /*ignore special*/ {
3389  if(i==200)continue; //internal
3390  Wire.beginTransmission (i);
3391  if (Wire.endTransmission () == 0) {
3392  if(count < ret_len) ret[count] = i;
3393  count++;
3394  delay (1);
3395  }
3396  }
3397  }
3398  inline optVAL_t sendI2C(optVAL_t deviceID,byte *buf, byte buf_len) {
3399  Wire.beginTransmission(deviceID);
3400  Wire.write(buf,buf_len);
3401  return Wire.endTransmission();
3402  }
3403 
3404  inline optVAL_t sendI2C(optVAL_t deviceID, byte buf){
3405  Wire.beginTransmission(deviceID);
3406  Wire.write(buf);
3407  return Wire.endTransmission();
3408  }
3410 
3421  inline void readI2C(optVAL_t deviceID, optVAL_t ret[], optVAL_t ret_len,bool blocking=true);
3423  inline void readI2C(optVAL_t deviceID,optVAL_t ret[] , optVAL_t ret_len,bool blocking) {
3424  for(optVAL_t rect = 0x0; (Wire.available() || (((blocking && (rect < ret_len))) && (!STOP))); rect++)
3425  ret[rect] = Wire.read();
3426  }
3428 
3429  //Beginof LCD configuration
3430  #if EBOARD_LCD > 0x0
3431 
3432  PROGMEM const byte basicFont[][8] = {
3433  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
3434  {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
3435  {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
3436  {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
3437  {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
3438  {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
3439  {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
3440  {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
3441  {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
3442  {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
3443  {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
3444  {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
3445  {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
3446  {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
3447  {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
3448  {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
3449  {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
3450  {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
3451  {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
3452  {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
3453  {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
3454  {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
3455  {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
3456  {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
3457  {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
3458  {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
3459  {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
3460  {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
3461  {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
3462  {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
3463  {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
3464  {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
3465  {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
3466  {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
3467  {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
3468  {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
3469  {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
3470  {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
3471  {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
3472  {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
3473  {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
3474  {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
3475  {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
3476  {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
3477  {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
3478  {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
3479  {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
3480  {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
3481  {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
3482  {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
3483  {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
3484  {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
3485  {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
3486  {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
3487  {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
3488  {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
3489  {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
3490  {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
3491  {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
3492  {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
3493  {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
3494  {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
3495  {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
3496  {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
3497  {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
3498  {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
3499  {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
3500  {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
3501  {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
3502  {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
3503  {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
3504  {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
3505  {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
3506  {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
3507  {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
3508  {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
3509  {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
3510  {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
3511  {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
3512  {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
3513  {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
3514  {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
3515  {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
3516  {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
3517  {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
3518  {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
3519  {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
3520  {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
3521  {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
3522  {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
3523  {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
3524  {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
3525  {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
3526  {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
3527  {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
3528  {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
3529  };
3530  /*
3531  * @note if you don't mind the space this is the extended font set!
3532  *
3533  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x00
3534  {0x7E,0x81,0x95,0xB1,0xB1,0x95,0x81,0x7E}, // 0x01
3535  {0x7E,0xFF,0xEB,0xCF,0xCF,0xEB,0xFF,0x7E}, // 0x02
3536  {0x0E,0x1F,0x3F,0x7E,0x3F,0x1F,0x0E,0x00}, // 0x03
3537  {0x08,0x1C,0x3E,0x7F,0x3E,0x1C,0x08,0x00}, // 0x04
3538  {0x38,0x3A,0x9F,0xFF,0x9F,0x3A,0x38,0x00}, // 0x05
3539  {0x10,0x38,0xBC,0xFF,0xBC,0x38,0x10,0x00}, // 0x06
3540  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x07
3541  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x08
3542  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x09
3543  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0A
3544  {0x70,0xF8,0x88,0x88,0xFD,0x7F,0x07,0x0F}, // 0x0B
3545  {0x00,0x4E,0x5F,0xF1,0xF1,0x5F,0x4E,0x00}, // 0x0C
3546  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0D
3547  {0xC0,0xFF,0x7F,0x05,0x05,0x65,0x7F,0x3F}, // 0x0E
3548  {0x99,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x99}, // 0x0F
3549  {0x7F,0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00}, // 0x10
3550  {0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x7F,0x00}, // 0x11
3551  {0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00}, // 0x12
3552  {0x00,0x5F,0x5F,0x00,0x00,0x5F,0x5F,0x00}, // 0x13
3553  {0x06,0x0F,0x09,0x7F,0x7F,0x01,0x7F,0x7F}, // 0x14
3554  {0xDA,0xBF,0xA5,0xA5,0xFD,0x59,0x03,0x02}, // 0x15
3555  {0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00}, // 0x16
3556  {0x80,0x94,0xB6,0xFF,0xFF,0xB6,0x94,0x80}, // 0x17
3557  {0x00,0x04,0x06,0x7F,0x7F,0x06,0x04,0x00}, // 0x18
3558  {0x00,0x10,0x30,0x7F,0x7F,0x30,0x10,0x00}, // 0x19
3559  {0x08,0x08,0x08,0x2A,0x3E,0x1C,0x08,0x00}, // 0x1A
3560  {0x08,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x00}, // 0x1B
3561  {0x3C,0x3C,0x20,0x20,0x20,0x20,0x20,0x00}, // 0x1C
3562  {0x08,0x1C,0x3E,0x08,0x08,0x3E,0x1C,0x08}, // 0x1D
3563  {0x30,0x38,0x3C,0x3E,0x3E,0x3C,0x38,0x30}, // 0x1E
3564  {0x06,0x0E,0x1E,0x3E,0x3E,0x1E,0x0E,0x06}, // 0x1F
3565  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x20
3566  {0x00,0x06,0x5F,0x5F,0x06,0x00,0x00,0x00}, // 0x21
3567  {0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00}, // 0x22
3568  {0x14,0x7F,0x7F,0x14,0x7F,0x7F,0x14,0x00}, // 0x23
3569  {0x24,0x2E,0x6B,0x6B,0x3A,0x12,0x00,0x00}, // 0x24
3570  {0x46,0x66,0x30,0x18,0x0C,0x66,0x62,0x00}, // 0x25
3571  {0x30,0x7A,0x4F,0x5D,0x37,0x7A,0x48,0x00}, // 0x26
3572  {0x04,0x07,0x03,0x00,0x00,0x00,0x00,0x00}, // 0x27
3573  {0x00,0x1C,0x3E,0x63,0x41,0x00,0x00,0x00}, // 0x28
3574  {0x00,0x41,0x63,0x3E,0x1C,0x00,0x00,0x00}, // 0x29
3575  {0x08,0x2A,0x3E,0x1C,0x1C,0x3E,0x2A,0x08}, // 0x2A
3576  {0x08,0x08,0x3E,0x3E,0x08,0x08,0x00,0x00}, // 0x2B
3577  {0x00,0xA0,0xE0,0x60,0x00,0x00,0x00,0x00}, // 0x2C
3578  {0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00}, // 0x2D
3579  {0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00}, // 0x2E
3580  {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // 0x2F
3581  {0x3E,0x7F,0x59,0x4D,0x7F,0x3E,0x00,0x00}, // 0x30
3582  {0x42,0x42,0x7F,0x7F,0x40,0x40,0x00,0x00}, // 0x31
3583  {0x62,0x73,0x59,0x49,0x6F,0x66,0x00,0x00}, // 0x32
3584  {0x22,0x63,0x49,0x49,0x7F,0x36,0x00,0x00}, // 0x33
3585  {0x18,0x1C,0x16,0x13,0x7F,0x7F,0x10,0x00}, // 0x34
3586  {0x27,0x67,0x45,0x45,0x7D,0x39,0x00,0x00}, // 0x35
3587  {0x3C,0x7E,0x4B,0x49,0x79,0x30,0x00,0x00}, // 0x36
3588  {0x03,0x63,0x71,0x19,0x0F,0x07,0x00,0x00}, // 0x37
3589  {0x36,0x7F,0x49,0x49,0x7F,0x36,0x00,0x00}, // 0x38
3590  {0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00,0x00}, // 0x39
3591  {0x00,0x00,0x6C,0x6C,0x00,0x00,0x00,0x00}, // 0x3A
3592  {0x00,0xA0,0xEC,0x6C,0x00,0x00,0x00,0x00}, // 0x3B
3593  {0x08,0x1C,0x36,0x63,0x41,0x00,0x00,0x00}, // 0x3C
3594  {0x14,0x14,0x14,0x14,0x14,0x14,0x00,0x00}, // 0x3D
3595  {0x00,0x41,0x63,0x36,0x1C,0x08,0x00,0x00}, // 0x3E
3596  {0x02,0x03,0x51,0x59,0x0F,0x06,0x00,0x00}, // 0x3F
3597  {0x3E,0x7F,0x41,0x5D,0x5D,0x1F,0x1E,0x00}, // 0x40
3598  {0x7C,0x7E,0x13,0x13,0x7E,0x7C,0x00,0x00}, // 0x41
3599  {0x41,0x7F,0x7F,0x49,0x49,0x7F,0x36,0x00}, // 0x42
3600  {0x1C,0x3E,0x63,0x41,0x41,0x63,0x22,0x00}, // 0x43
3601  {0x41,0x7F,0x7F,0x41,0x63,0x7F,0x1C,0x00}, // 0x44
3602  {0x41,0x7F,0x7F,0x49,0x5D,0x41,0x63,0x00}, // 0x45
3603  {0x41,0x7F,0x7F,0x49,0x1D,0x01,0x03,0x00}, // 0x46
3604  {0x1C,0x3E,0x63,0x41,0x51,0x73,0x72,0x00}, // 0x47
3605  {0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00,0x00}, // 0x48
3606  {0x00,0x41,0x7F,0x7F,0x41,0x00,0x00,0x00}, // 0x49
3607  {0x30,0x70,0x40,0x41,0x7F,0x3F,0x01,0x00}, // 0x4A
3608  {0x41,0x7F,0x7F,0x08,0x1C,0x77,0x63,0x00}, // 0x4B
3609  {0x41,0x7F,0x7F,0x41,0x40,0x60,0x70,0x00}, // 0x4C
3610  {0x7F,0x7F,0x06,0x0C,0x06,0x7F,0x7F,0x00}, // 0x4D
3611  {0x7F,0x7F,0x06,0x0C,0x18,0x7F,0x7F,0x00}, // 0x4E
3612  {0x1C,0x3E,0x63,0x41,0x63,0x3E,0x1C,0x00}, // 0x4F
3613  {0x41,0x7F,0x7F,0x49,0x09,0x0F,0x06,0x00}, // 0x50
3614  {0x1E,0x3F,0x21,0x71,0x7F,0x5E,0x00,0x00}, // 0x51
3615  {0x41,0x7F,0x7F,0x19,0x39,0x6F,0x46,0x00}, // 0x52
3616  {0x26,0x67,0x4D,0x59,0x7B,0x32,0x00,0x00}, // 0x53
3617  {0x03,0x41,0x7F,0x7F,0x41,0x03,0x00,0x00}, // 0x54
3618  {0x7F,0x7F,0x40,0x40,0x7F,0x7F,0x00,0x00}, // 0x55
3619  {0x1F,0x3F,0x60,0x60,0x3F,0x1F,0x00,0x00}, // 0x56
3620  {0x7F,0x7F,0x30,0x18,0x30,0x7F,0x7F,0x00}, // 0x57
3621  {0x63,0x77,0x1C,0x08,0x1C,0x77,0x63,0x00}, // 0x58
3622  {0x07,0x4F,0x78,0x78,0x4F,0x07,0x00,0x00}, // 0x59
3623  {0x67,0x73,0x59,0x4D,0x47,0x63,0x71,0x00}, // 0x5A
3624  {0x00,0x7F,0x7F,0x41,0x41,0x00,0x00,0x00}, // 0x5B
3625  {0x01,0x03,0x06,0x0C,0x18,0x30,0x60,0x00}, // 0x5C
3626  {0x00,0x41,0x41,0x7F,0x7F,0x00,0x00,0x00}, // 0x5D
3627  {0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00}, // 0x5E
3628  {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}, // 0x5F
3629  {0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00}, // 0x60
3630  {0x20,0x74,0x54,0x54,0x3C,0x78,0x40,0x00}, // 0x61
3631  {0x41,0x3F,0x7F,0x44,0x44,0x7C,0x38,0x00}, // 0x62
3632  {0x38,0x7C,0x44,0x44,0x6C,0x28,0x00,0x00}, // 0x63
3633  {0x30,0x78,0x48,0x49,0x3F,0x7F,0x40,0x00}, // 0x64
3634  {0x38,0x7C,0x54,0x54,0x5C,0x18,0x00,0x00}, // 0x65
3635  {0x48,0x7E,0x7F,0x49,0x03,0x02,0x00,0x00}, // 0x66
3636  {0x98,0xBC,0xA4,0xA4,0xF8,0x7C,0x04,0x00}, // 0x67
3637  {0x41,0x7F,0x7F,0x08,0x04,0x7C,0x78,0x00}, // 0x68
3638  {0x00,0x44,0x7D,0x7D,0x40,0x00,0x00,0x00}, // 0x69
3639  {0x40,0xC4,0x84,0xFD,0x7D,0x00,0x00,0x00}, // 0x6A
3640  {0x41,0x7F,0x7F,0x10,0x38,0x6C,0x44,0x00}, // 0x6B
3641  {0x00,0x41,0x7F,0x7F,0x40,0x00,0x00,0x00}, // 0x6C
3642  {0x7C,0x7C,0x0C,0x18,0x0C,0x7C,0x78,0x00}, // 0x6D
3643  {0x7C,0x7C,0x04,0x04,0x7C,0x78,0x00,0x00}, // 0x6E
3644  {0x38,0x7C,0x44,0x44,0x7C,0x38,0x00,0x00}, // 0x6F
3645  {0x84,0xFC,0xF8,0xA4,0x24,0x3C,0x18,0x00}, // 0x70
3646  {0x18,0x3C,0x24,0xA4,0xF8,0xFC,0x84,0x00}, // 0x71
3647  {0x44,0x7C,0x78,0x44,0x1C,0x18,0x00,0x00}, // 0x72
3648  {0x48,0x5C,0x54,0x54,0x74,0x24,0x00,0x00}, // 0x73
3649  {0x00,0x04,0x3E,0x7F,0x44,0x24,0x00,0x00}, // 0x74
3650  {0x3C,0x7C,0x40,0x40,0x3C,0x7C,0x40,0x00}, // 0x75
3651  {0x1C,0x3C,0x60,0x60,0x3C,0x1C,0x00,0x00}, // 0x76
3652  {0x3C,0x7C,0x60,0x30,0x60,0x7C,0x3C,0x00}, // 0x77
3653  {0x44,0x6C,0x38,0x10,0x38,0x6C,0x44,0x00}, // 0x78
3654  {0x9C,0xBC,0xA0,0xA0,0xFC,0x7C,0x00,0x00}, // 0x79
3655  {0x4C,0x64,0x74,0x5C,0x4C,0x64,0x00,0x00}, // 0x7A
3656  {0x08,0x08,0x3E,0x77,0x41,0x41,0x00,0x00}, // 0x7B
3657  {0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00}, // 0x7C
3658  {0x41,0x41,0x77,0x3E,0x08,0x08,0x00,0x00}, // 0x7D
3659  {0x02,0x03,0x01,0x03,0x02,0x03,0x01,0x00}, // 0x7E
3660  {0x78,0x7C,0x46,0x43,0x46,0x7C,0x78,0x00}, // 0x7F
3661  {0x1E,0xBF,0xE1,0x61,0x33,0x12,0x00,0x00}, // 0x80
3662  {0x3A,0x7A,0x40,0x40,0x7A,0x7A,0x40,0x00}, // 0x81
3663  {0x38,0x7C,0x56,0x57,0x5D,0x18,0x00,0x00}, // 0x82
3664  {0x02,0x23,0x75,0x55,0x55,0x7D,0x7B,0x42}, // 0x83
3665  {0x21,0x75,0x54,0x54,0x7D,0x79,0x40,0x00}, // 0x84
3666  {0x20,0x75,0x57,0x56,0x7C,0x78,0x40,0x00}, // 0x85
3667  {0x00,0x22,0x77,0x55,0x55,0x7F,0x7A,0x40}, // 0x86
3668  {0x1C,0xBE,0xE2,0x62,0x36,0x14,0x00,0x00}, // 0x87
3669  {0x02,0x3B,0x7D,0x55,0x55,0x5D,0x1B,0x02}, // 0x88
3670  {0x39,0x7D,0x54,0x54,0x5D,0x19,0x00,0x00}, // 0x89
3671  {0x38,0x7D,0x57,0x56,0x5C,0x18,0x00,0x00}, // 0x8A
3672  {0x01,0x45,0x7C,0x7C,0x41,0x01,0x00,0x00}, // 0x8B
3673  {0x02,0x03,0x45,0x7D,0x7D,0x43,0x02,0x00}, // 0x8C
3674  {0x00,0x45,0x7F,0x7E,0x40,0x00,0x00,0x00}, // 0x8D
3675  {0x79,0x7D,0x26,0x26,0x7D,0x79,0x00,0x00}, // 0x8E
3676  {0x70,0x7A,0x2D,0x2D,0x7A,0x70,0x00,0x00}, // 0x8F
3677  {0x44,0x7C,0x7E,0x57,0x55,0x44,0x00,0x00}, // 0x90
3678  {0x20,0x74,0x54,0x54,0x7C,0x7C,0x54,0x54}, // 0x91
3679  {0x7C,0x7E,0x0B,0x09,0x7F,0x7F,0x49,0x00}, // 0x92
3680  {0x32,0x7B,0x49,0x49,0x7B,0x32,0x00,0x00}, // 0x93
3681  {0x32,0x7A,0x48,0x48,0x7A,0x32,0x00,0x00}, // 0x94
3682  {0x30,0x79,0x4B,0x4A,0x78,0x30,0x00,0x00}, // 0x95
3683  {0x3A,0x7B,0x41,0x41,0x7B,0x7A,0x40,0x00}, // 0x96
3684  {0x38,0x79,0x43,0x42,0x78,0x78,0x40,0x00}, // 0x97
3685  {0xBA,0xBA,0xA0,0xA0,0xFA,0x7A,0x00,0x00}, // 0x98
3686  {0x39,0x7D,0x44,0x44,0x44,0x7D,0x39,0x00}, // 0x99
3687  {0x3D,0x7D,0x40,0x40,0x7D,0x3D,0x00,0x00}, // 0x9A
3688  {0x38,0x7C,0x64,0x54,0x4C,0x7C,0x38,0x00}, // 0x9B
3689  {0x68,0x7E,0x7F,0x49,0x43,0x66,0x20,0x00}, // 0x9C
3690  {0x5C,0x3E,0x73,0x49,0x67,0x3E,0x1D,0x00}, // 0x9D
3691  {0x44,0x6C,0x38,0x38,0x6C,0x44,0x00,0x00}, // 0x9E
3692  {0x40,0xC8,0x88,0xFE,0x7F,0x09,0x0B,0x02}, // 0x9F
3693  {0x20,0x74,0x56,0x57,0x7D,0x78,0x40,0x00}, // 0xA0
3694  {0x00,0x44,0x7E,0x7F,0x41,0x00,0x00,0x00}, // 0xA1
3695  {0x30,0x78,0x48,0x4A,0x7B,0x31,0x00,0x00}, // 0xA2
3696  {0x38,0x78,0x40,0x42,0x7B,0x79,0x40,0x00}, // 0xA3
3697  {0x7A,0x7B,0x09,0x0B,0x7A,0x73,0x01,0x00}, // 0xA4
3698  {0x7A,0x7B,0x19,0x33,0x7A,0x7B,0x01,0x00}, // 0xA5
3699  {0x00,0x26,0x2F,0x29,0x2F,0x2F,0x28,0x00}, // 0xA6
3700  {0x00,0x26,0x2F,0x29,0x29,0x2F,0x26,0x00}, // 0xA7
3701  {0x30,0x78,0x4D,0x45,0x60,0x20,0x00,0x00}, // 0xA8
3702  {0x1C,0x22,0x7D,0x4B,0x5B,0x65,0x22,0x1C}, // 0xA9
3703  {0x08,0x08,0x08,0x08,0x38,0x38,0x00,0x00}, // 0xAA
3704  {0x61,0x3F,0x1F,0xCC,0xEE,0xAB,0xB9,0x90}, // 0xAB
3705  {0x61,0x3F,0x1F,0x4C,0x66,0x73,0xD9,0xF8}, // 0xAC
3706  {0x00,0x00,0x60,0xFA,0xFA,0x60,0x00,0x00}, // 0xAD
3707  {0x08,0x1C,0x36,0x22,0x08,0x1C,0x36,0x22}, // 0xAE
3708  {0x22,0x36,0x1C,0x08,0x22,0x36,0x1C,0x08}, // 0xAF
3709  {0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00}, // 0xB0
3710  {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55}, // 0xB1
3711  {0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF}, // 0xB2
3712  {0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00}, // 0xB3
3713  {0x10,0x10,0x10,0xFF,0xFF,0x00,0x00,0x00}, // 0xB4
3714  {0x70,0x78,0x2C,0x2E,0x7B,0x71,0x00,0x00}, // 0xB5
3715  {0x72,0x79,0x2D,0x2D,0x79,0x72,0x00,0x00}, // 0xB6
3716  {0x71,0x7B,0x2E,0x2C,0x78,0x70,0x00,0x00}, // 0xB7
3717  {0x1C,0x22,0x5D,0x55,0x55,0x41,0x22,0x1C}, // 0xB8
3718  {0x14,0x14,0xF7,0xF7,0x00,0xFF,0xFF,0x00}, // 0xB9
3719  {0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00}, // 0xBA
3720  {0x14,0x14,0xF4,0xF4,0x04,0xFC,0xFC,0x00}, // 0xBB
3721  {0x14,0x14,0x17,0x17,0x10,0x1F,0x1F,0x00}, // 0xBC
3722  {0x18,0x3C,0x24,0xE7,0xE7,0x24,0x24,0x00}, // 0xBD
3723  {0x2B,0x2F,0xFC,0xFC,0x2F,0x2B,0x00,0x00}, // 0xBE
3724  {0x10,0x10,0x10,0xF0,0xF0,0x00,0x00,0x00}, // 0xBF
3725  {0x00,0x00,0x00,0x1F,0x1F,0x10,0x10,0x10}, // 0xC0
3726  {0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10}, // 0xC1
3727  {0x10,0x10,0x10,0xF0,0xF0,0x10,0x10,0x10}, // 0xC2
3728  {0x00,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10}, // 0xC3
3729  {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10}, // 0xC4
3730  {0x10,0x10,0x10,0xFF,0xFF,0x10,0x10,0x10}, // 0xC5
3731  {0x22,0x77,0x55,0x57,0x7E,0x7B,0x41,0x00}, // 0xC6
3732  {0x72,0x7B,0x2D,0x2F,0x7A,0x73,0x01,0x00}, // 0xC7
3733  {0x00,0x00,0x1F,0x1F,0x10,0x17,0x17,0x14}, // 0xC8
3734  {0x00,0x00,0xFC,0xFC,0x04,0xF4,0xF4,0x14}, // 0xC9
3735  {0x14,0x14,0x17,0x17,0x10,0x17,0x17,0x14}, // 0xCA
3736  {0x14,0x14,0xF4,0xF4,0x04,0xF4,0xF4,0x14}, // 0xCB
3737  {0x00,0x00,0xFF,0xFF,0x00,0xF7,0xF7,0x14}, // 0xCC
3738  {0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14}, // 0xCD
3739  {0x14,0x14,0xF7,0xF7,0x00,0xF7,0xF7,0x14}, // 0xCE
3740  {0x66,0x3C,0x3C,0x24,0x3C,0x3C,0x66,0x00}, // 0xCF
3741  {0x05,0x27,0x72,0x57,0x7D,0x38,0x00,0x00}, // 0xD0
3742  {0x49,0x7F,0x7F,0x49,0x63,0x7F,0x1C,0x00}, // 0xD1
3743  {0x46,0x7D,0x7D,0x55,0x55,0x46,0x00,0x00}, // 0xD2
3744  {0x45,0x7D,0x7C,0x54,0x55,0x45,0x00,0x00}, // 0xD3
3745  {0x44,0x7D,0x7F,0x56,0x54,0x44,0x00,0x00}, // 0xD4
3746  {0x0A,0x0E,0x08,0x00,0x00,0x00,0x00,0x00}, // 0xD5
3747  {0x00,0x44,0x7E,0x7F,0x45,0x00,0x00,0x00}, // 0xD6
3748  {0x02,0x45,0x7D,0x7D,0x45,0x02,0x00,0x00}, // 0xD7
3749  {0x01,0x45,0x7C,0x7C,0x45,0x01,0x00,0x00}, // 0xD8
3750  {0x10,0x10,0x10,0x1F,0x1F,0x00,0x00,0x00}, // 0xD9
3751  {0x00,0x00,0x00,0xF0,0xF0,0x10,0x10,0x10}, // 0xDA
3752  {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, // 0xDB
3753  {0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0}, // 0xDC
3754  {0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00}, // 0xDD
3755  {0x00,0x45,0x7F,0x7E,0x44,0x00,0x00,0x00}, // 0xDE
3756  {0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}, // 0xDF
3757  {0x38,0x7C,0x46,0x47,0x45,0x7C,0x38,0x00}, // 0xE0
3758  {0xFC,0xFE,0x2A,0x2A,0x3E,0x14,0x00,0x00}, // 0xE1
3759  {0x3A,0x7D,0x45,0x45,0x45,0x7D,0x3A,0x00}, // 0xE2
3760  {0x38,0x7C,0x45,0x47,0x46,0x7C,0x38,0x00}, // 0xE3
3761  {0x32,0x7B,0x49,0x4B,0x7A,0x33,0x01,0x00}, // 0xE4
3762  {0x3A,0x7F,0x45,0x47,0x46,0x7F,0x39,0x00}, // 0xE5
3763  {0x80,0xFE,0x7E,0x20,0x20,0x3E,0x1E,0x00}, // 0xE6
3764  {0x42,0x7E,0x7E,0x54,0x1C,0x08,0x00,0x00}, // 0xE7
3765  {0x41,0x7F,0x7F,0x55,0x14,0x1C,0x08,0x00}, // 0xE8
3766  {0x3C,0x7C,0x42,0x43,0x7D,0x3C,0x00,0x00}, // 0xE9
3767  {0x3A,0x79,0x41,0x41,0x79,0x3A,0x00,0x00}, // 0xEA
3768  {0x3C,0x7D,0x43,0x42,0x7C,0x3C,0x00,0x00}, // 0xEB
3769  {0xB8,0xB8,0xA2,0xA3,0xF9,0x78,0x00,0x00}, // 0xEC
3770  {0x0C,0x5C,0x72,0x73,0x5D,0x0C,0x00,0x00}, // 0xED
3771  {0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00}, // 0xEE
3772  {0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x00}, // 0xEF
3773  {0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00}, // 0xF0
3774  {0x44,0x44,0x5F,0x5F,0x44,0x44,0x00,0x00}, // 0xF1
3775  {0x28,0x28,0x28,0x28,0x28,0x28,0x00,0x00}, // 0xF2
3776  {0x71,0x35,0x1F,0x4C,0x66,0x73,0xD9,0xF8}, // 0xF3
3777  {0x06,0x0F,0x09,0x7F,0x7F,0x01,0x7F,0x7F}, // 0xF4
3778  {0xDA,0xBF,0xA5,0xA5,0xFD,0x59,0x03,0x02}, // 0xF5
3779  {0x08,0x08,0x6B,0x6B,0x08,0x08,0x00,0x00}, // 0xF6
3780  {0x00,0x80,0xC0,0x40,0x00,0x00,0x00,0x00}, // 0xF7
3781  {0x00,0x06,0x0F,0x09,0x0F,0x06,0x00,0x00}, // 0xF8
3782  {0x02,0x02,0x00,0x00,0x02,0x02,0x00,0x00}, // 0xF9
3783  {0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00}, // 0xFA
3784  {0x00,0x12,0x13,0x1F,0x1F,0x10,0x10,0x00}, // 0xFB
3785  {0x00,0x11,0x15,0x15,0x1F,0x1F,0x0A,0x00}, // 0xFC
3786  {0x00,0x19,0x1D,0x15,0x17,0x12,0x00,0x00}, // 0xFD
3787  {0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00}, // 0xFE
3788  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0xFF
3789  */
3790 
3791  //Definition of OLED Constants
3793  #define LCD_COMMAND_MODE 0x80
3794  #define LCD_DATA_MODE 0x40
3796  #define LCD_COMMAND_DISPLAY_OFF 0xAE
3798  #define LCD_COMMAND_DISPLAY_ON 0xAF
3800  #define LCD_COMMAND_BLACK_BACKGROUND 0xA6
3802  #define LCD_COMMAND_WHITE_BACKGROUND 0xA7
3804  #define LCD_COMMAND_SET_BRIGHTNESS 0x81
3806  #define LCD_PAGE_ADDRESSING 0x02
3808  #define LCD_HORIZONTAL_ADDRESSING 0x00
3810  //The regulator
3812  #define LCD_COMMAND_CHARGE_PUMP_SETTING 0x8d
3813  #define LCD_COMMAND_CHARGE_PUMP_ENABLE 0x14
3815 
3816  #ifndef LCD_WIDTH
3817  #define LCD_WIDTH 128
3819  #endif
3820  #ifndef LCD_HEIGHT
3821  #define LCD_HEIGHT 64
3823  #endif
3824 
3864  struct LCD {
3865  #if EBOARD_NANO == 0
3866 
3874  LCD(SoccerBoard &soccerBoard, optVAL_t id=0x3C);
3875  #else
3876  LCD(optVAL_t id=0x3C);
3877  #endif
3878 
3892  inline bool changeID(optVAL_t newID = 0x3C);
3903  inline bool clear(void);
3909  inline void print(const char* data);
3915  inline void print(int data);
3923  inline void print(optVAL_t line, optVAL_t col, const char* data);
3931  inline void print(optVAL_t line, optVAL_t col, int data);
3940  inline void lightOn(void);
3949  inline void lightOff(void);
3960  inline bool reset(void);
3961 
3962  //added features
3975  inline bool init(void);
3985  inline void drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY);
3993  inline void changeMode(bool newMode = true);
4007  inline bool setCursor(byte posX = 0x0, byte posY = 0x0);
4020  inline bool changeBrightness (byte val = 0x64);
4030  inline void changeBackground(bool newBackground = false);
4032  optVAL_t ID;
4033  private:
4039  byte pX;
4042  byte pY;
4044  bool _cI;
4045 
4052  inline void s2Cmd(optVAL_t o, optVAL_t t);
4058  inline void s1Cmd(optVAL_t o);
4064  inline void s1Dat(optVAL_t o);
4065 
4066  };
4068  #if EBOARD_NANO == 0x0
4069  LCD::LCD(SoccerBoard &soccerBoard, optVAL_t id) {
4070  this->_cI = false;
4071  this->ID = id;
4072  //this->init();
4073  }
4074  #else
4075  LCD::LCD( optVAL_t id) {
4076  this->_cI = false;
4077  this->ID = id;
4078  //this->init();
4079  }
4080  #endif
4081  inline bool LCD::changeID(optVAL_t newID) {
4082  this->ID = newID;
4083  return this->init();
4084  }
4085  inline bool LCD::clear(void) {
4086  if(!this->_cI) this->init();
4087  for(byte i = 0; i < 8; i++){
4088  //maybe *8
4089  setCursor(0,i);
4090 
4091  for (byte j = 0; j < 128; j++) {
4092  this->s1Dat(0);
4093  }
4094  }
4095  return setCursor(0,0);
4096  }
4097  void LCD::print(optVAL_t line, optVAL_t col, const char *data) {
4098  if(!this->_cI) this->init();
4099  byte i = 0x0;
4100  if(col < ((LCD_WIDTH-1)/8.0) && line < ((LCD_HEIGHT-1)/8.0)) {
4101  setCursor(col,line);
4102  }
4103  while(data[i] && (pX*8) < LCD_WIDTH){
4104  //Serial.print(data[i]); Serial.print(" ");
4105  //Serial.print(i); Serial.print(" "); Serial.print(pX); Serial.print(" ");
4106  //Serial.println(this->pY);
4107  if(data[i] == '\n' || this->pX >= LCD_WIDTH) {
4108  setCursor(0,(pY+1));
4109  } else if (this->pY >= LCD_HEIGHT){
4110  setCursor(0,0);
4111  }
4112  if(data[i] < 32 || data[i] > 127){ i++; continue;}
4113  for (byte j = 0; j < 8; j++){
4114  this->s1Dat(pgm_read_byte(&basicFont[data[i]-32][j]));
4115  }
4116  i++;this->pX++;
4117  }
4118  }
4119  void LCD::print(optVAL_t line, optVAL_t col, int data){
4120  char buffer[11] = "";
4121  itoa(data,buffer,10);
4122  this->print(line,col,buffer);
4123  }
4124  inline void LCD::lightOn(void) {
4125  this->changeBrightness(255);
4126  }
4127  inline void LCD::lightOff(void) {
4128  this->changeBrightness(0);
4129  }
4130  inline bool LCD::reset(void) {
4131  return this->clear();
4132  }
4133  inline void LCD::print(int data) {this->print(255,255,data);}
4134  inline void LCD::print(const char* data) {this->print(255,255,data);}
4135  inline bool LCD::init() {
4136  #ifdef HIGHSPEED
4137  TWBR = 0xC;
4138  #endif
4139  this->_cI = true;
4141  this->changeMode(false);
4142  this->changeBackground(false);
4143  this->changeBrightness(255);
4144  this->s2Cmd(0x20,LCD_PAGE_ADDRESSING);
4145  this->changeMode(true);
4146 
4147  //this->print("eBoard \n written by \n EagleoutIce");
4148  return this->clear();
4149  }
4150 
4151  inline void LCD::drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY){
4152  if(!this->_cI) this->init();
4153  setCursor(posX,posY);
4154  byte col = 0x0;
4155  for(int i = 0x0; i < (hiX * 8 * hiY); i++){
4156  this->s1Dat(pgm_read_byte(&bitmap[i]));
4157  if(++col == (hiX * 8)) {
4158  col = 0x0;
4159  setCursor(posX,++posY);
4160  }
4161  }
4162  }
4163  inline void LCD::changeMode(bool newMode) {
4164  if(!this->_cI) this->init();
4165  if(newMode) this->s1Cmd(LCD_COMMAND_DISPLAY_ON);
4166  else this->s1Cmd(LCD_COMMAND_DISPLAY_OFF);
4167  }
4168  inline bool LCD::setCursor(byte posX, byte posY) {
4169  if(!this->_cI) this->init();
4170  this->s2Cmd((0x00 + (8 *posX & 0x0F)),(0x10 + ((8 * posX >> 4) & 0x0F))); //lower and higher address
4171  Wire.beginTransmission(this->ID);
4172  Wire.write(LCD_COMMAND_MODE); Wire.write(0xB0 + posY); //page address
4173  this->pX = posX; this->pY = posY;
4174  return (Wire.endTransmission() == 0);
4175  }
4176 
4177  inline bool LCD::changeBrightness(byte val) {
4178  if(!this->_cI) this->init();
4179  this->s2Cmd(0x81,val); //brightness mode
4180  Wire.beginTransmission(this->ID);
4181  return (Wire.endTransmission() == 0);
4182  }
4183  inline void LCD::changeBackground(bool newBackground) {
4184  if(!this->_cI) this->init();
4185  if(newBackground) this->s1Cmd(LCD_COMMAND_WHITE_BACKGROUND);
4186  else this->s1Cmd(LCD_COMMAND_BLACK_BACKGROUND);
4187  }
4188 
4189  inline void LCD::s2Cmd(optVAL_t o, optVAL_t t){
4190  if(!this->_cI) this->init();
4191  this->s1Cmd(o); this->s1Cmd(t);
4192  }
4193 
4194  inline void LCD::s1Cmd(optVAL_t C) {
4195  if(!this->_cI) this->init();
4196  Wire.beginTransmission(this->ID);
4199  }
4200  inline void LCD::s1Dat(optVAL_t o){
4201  if(!this->_cI) this->init();
4202  Wire.beginTransmission(this->ID);
4205  }
4206 
4207  //@endcond
4208  #endif
4209 
4210  #if EBOARD_NEO > 0x0
4211  // Codesection based on official NeoPixel library
4212  // RGB NeoPixel permutations; white and red offsets are always same
4213  // Offset: W R G B
4215  #define EBOARD_NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2))
4216  #define EBOARD_NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1))
4218  #define EBOARD_NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2))
4220  #define EBOARD_NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1))
4222  #define EBOARD_NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0))
4224  #define EBOARD_NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0))
4226 
4227  // RGBW NeoPixel permutations; all 4 offsets are distinct
4228  // Offset: W R G B
4230  #define EBOARD_NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3))
4231  #define EBOARD_NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2))
4233  #define EBOARD_NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3))
4235  #define EBOARD_NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2))
4237  #define EBOARD_NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1))
4239  #define EBOARD_NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1))
4241  #define EBOARD_NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3))
4243  #define EBOARD_NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2))
4245  #define EBOARD_NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3))
4247  #define EBOARD_NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2))
4249  #define EBOARD_NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1))
4251  #define EBOARD_NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1))
4253  #define EBOARD_NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3))
4255  #define EBOARD_NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2))
4257  #define EBOARD_NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3))
4259  #define EBOARD_NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2))
4261  #define EBOARD_NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1))
4263  #define EBOARD_NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1))
4265  #define EBOARD_NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0))
4267  #define EBOARD_NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0))
4269  #define EBOARD_NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0))
4271  #define EBOARD_NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0))
4273  #define EBOARD_NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0))
4275  #define EBOARD_NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0))
4277 
4278 
4280  #define EBOARD_NEO_800KHZ 0x0000
4281  #define EBOARD_NEO_400KHZ 0x0100
4283 
4284  // uint16_t can be uint8_t in 800Khz mode ^^
4312  struct NeoPixel{
4320  NeoPixel(uint16_t n, uint8_t p = 6, uint16_t t = EBOARD_NEO_RGB + EBOARD_NEO_800KHZ);
4328  NeoPixel(void);
4330  ~NeoPixel(void);
4334  void begin(void);
4338  void show(void);
4343  void setPin(uint8_t p);
4351  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
4360  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
4366  void setPixelColor(uint16_t n, uint32_t c);
4371  void setBrightness(uint8_t val);
4375  void clear(void);
4380  void updateLength(uint16_t n);
4385  void updateType(uint16_t t);
4390  inline uint8_t *getPixels(void) const;
4395  inline uint8_t getBrightness(void) const;
4401  uint8_t sine8(uint8_t x) const;
4407  uint8_t gamma8(uint8_t x) const;
4412  inline int8_t getPin(void);
4417  inline uint16_t numPixels(void) const;
4424  static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b);
4432  static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w);
4437  uint32_t getPixelColor(uint16_t n) const;
4442  inline bool canShow(void);
4443  protected:
4445  bool is800kHz;
4447  bool begun;
4449  uint16_t numLEDs; //maybe shorten with PrepConst 'extendetLED'?
4451  uint16_t numBytes;
4456  int8_t pin;
4458  uint8_t brightness;
4460  uint8_t *pixels;
4462  uint8_t rOffset;
4464  uint8_t gOffset;
4466  uint8_t bOffset;
4468  uint8_t wOffset;
4470  uint32_t endTime; //used for diff calc
4471  #ifdef __AVR__ //not needed (rem?)
4472  volatile uint8_t *port;// Output PORT register
4475  uint8_t pinMask; // Output PORT bitmask
4476  #endif
4477 
4478  };
4479 
4481 
4482 
4483  NeoPixel::NeoPixel(uint16_t n, uint8_t p, uint16_t t) :
4484  begun(false), brightness(0), pixels(NULL), endTime(0) {
4485  updateType(t);
4486  updateLength(n);
4487  setPin(p);
4488  }
4489 
4490  inline bool NeoPixel::canShow(void) { return (micros() - endTime) >= 300L; }
4491 
4492  NeoPixel::NeoPixel() :
4493  is800KHz(true),
4494  begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0), pixels(NULL),
4495  rOffset(1), gOffset(0), bOffset(2), wOffset(1), endTime(0)
4496  {}
4497 
4499  if(pixels) free(pixels);
4500  if(pin >= 0) pinMode(pin, INPUT);
4501  }
4502 
4503  void NeoPixel::begin(void) {
4504  if(pin >= 0) {
4505  pinMode(pin, OUTPUT);
4506  digitalWrite(pin, LOW);
4507  }
4508  begun = true;
4509 
4510  }
4511 
4512  void NeoPixel::updateLength(uint16_t n) {
4513  if(pixels) free(pixels);
4514  numBytes = n * ((wOffset == rOffset) ? 3 : 4);
4515  if((pixels = (uint8_t *)malloc(numBytes))) {
4516  memset(pixels, 0, numBytes);
4517  numLEDs = n;
4518  } else {
4519  numLEDs = numBytes = 0;
4520  }
4521  }
4522 
4523  void NeoPixel::updateType(uint16_t t) {
4524  boolean oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
4525 
4526  wOffset = (t >> 6) & 0b11;
4527  rOffset = (t >> 4) & 0b11;
4528  gOffset = (t >> 2) & 0b11;
4529  bOffset = t & 0b11;
4530  is800KHz = (t < 256); // 400 KHz flag is 1<<8
4531 
4532  if(pixels) {
4533  boolean newThreeBytesPerPixel = (wOffset == rOffset);
4534  if(newThreeBytesPerPixel != oldThreeBytesPerPixel) updateLength(numLEDs);
4535  }
4536  }
4537 
4538  #if defined(ESP8266)
4539  // ESP8266 show() is external to enforce ICACHE_RAM_ATTR execution
4540  extern "C" void ICACHE_RAM_ATTR espShow(
4541  uint8_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
4542  #elif defined(ESP32)
4543  extern "C" void espShow(
4544  uint8_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
4545  #endif
4546 
4547  void NeoPixel::show(void) {
4548  if(!pixels) return;
4549  while(!canShow()); //maybe timeout ?
4550  noInterrupts(); // Need 100% focus on instruction timing
4551 
4552  #ifdef __AVR__
4553  volatile uint16_t
4554  i = numBytes;
4555  volatile uint8_t
4556  *ptr = pixels,
4557  b = *ptr++,
4558  hi,
4559  lo;
4560 
4561  #if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL)
4562 
4563  if(is800KHz) {
4564  volatile uint8_t n1, n2 = 0;
4565 
4566  #if defined(PORTD)
4567  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
4568  if(port == &PORTD) {
4569  #endif
4570 
4571  hi = PORTD | pinMask;
4572  lo = PORTD & ~pinMask;
4573  n1 = lo;
4574  if(b & 0x80) n1 = hi;
4575 
4576  asm volatile(
4577  "headD:" "\n\t" // Clk Pseudocode
4578  // Bit 7:
4579  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4580  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4581  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4582  "rjmp .+0" "\n\t" // 2 nop nop
4583  "sbrc %[byte] , 6" "\n\t" // 1-2 if(b & 0x40)
4584  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4585  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4586  "rjmp .+0" "\n\t" // 2 nop nop
4587  // Bit 6:
4588  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4589  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4590  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4591  "rjmp .+0" "\n\t" // 2 nop nop
4592  "sbrc %[byte] , 5" "\n\t" // 1-2 if(b & 0x20)
4593  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4594  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4595  "rjmp .+0" "\n\t" // 2 nop nop
4596  // Bit 5:
4597  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4598  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4599  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4600  "rjmp .+0" "\n\t" // 2 nop nop
4601  "sbrc %[byte] , 4" "\n\t" // 1-2 if(b & 0x10)
4602  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4603  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4604  "rjmp .+0" "\n\t" // 2 nop nop
4605  // Bit 4:
4606  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4607  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4608  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4609  "rjmp .+0" "\n\t" // 2 nop nop
4610  "sbrc %[byte] , 3" "\n\t" // 1-2 if(b & 0x08)
4611  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4612  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4613  "rjmp .+0" "\n\t" // 2 nop nop
4614  // Bit 3:
4615  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4616  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4617  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4618  "rjmp .+0" "\n\t" // 2 nop nop
4619  "sbrc %[byte] , 2" "\n\t" // 1-2 if(b & 0x04)
4620  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4621  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4622  "rjmp .+0" "\n\t" // 2 nop nop
4623  // Bit 2:
4624  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4625  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4626  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4627  "rjmp .+0" "\n\t" // 2 nop nop
4628  "sbrc %[byte] , 1" "\n\t" // 1-2 if(b & 0x02)
4629  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4630  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4631  "rjmp .+0" "\n\t" // 2 nop nop
4632  // Bit 1:
4633  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4634  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4635  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4636  "rjmp .+0" "\n\t" // 2 nop nop
4637  "sbrc %[byte] , 0" "\n\t" // 1-2 if(b & 0x01)
4638  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4639  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4640  "sbiw %[count], 1" "\n\t" // 2 i-- (don't act on Z flag yet)
4641  // Bit 0:
4642  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4643  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4644  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4645  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++
4646  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 0x80)
4647  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4648  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4649  "brne headD" "\n" // 2 while(i) (Z flag set above)
4650  : [byte] "+r" (b),
4651  [n1] "+r" (n1),
4652  [n2] "+r" (n2),
4653  [count] "+w" (i)
4654  : [port] "I" (_SFR_IO_ADDR(PORTD)),
4655  [ptr] "e" (ptr),
4656  [hi] "r" (hi),
4657  [lo] "r" (lo));
4658 
4659  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
4660  } else
4661  #endif
4662  #endif
4663  #if defined(PORTB)
4664  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
4665  if(port == &PORTB) {
4666  #endif // defined(PORTD/C/F)
4667  hi = PORTB | pinMask;
4668  lo = PORTB & ~pinMask;
4669  n1 = lo;
4670  if(b & 0x80) n1 = hi;
4671 
4672  asm volatile(
4673  "headB:" "\n\t"
4674  "out %[port] , %[hi]" "\n\t"
4675  "mov %[n2] , %[lo]" "\n\t"
4676  "out %[port] , %[n1]" "\n\t"
4677  "rjmp .+0" "\n\t"
4678  "sbrc %[byte] , 6" "\n\t"
4679  "mov %[n2] , %[hi]" "\n\t"
4680  "out %[port] , %[lo]" "\n\t"
4681  "rjmp .+0" "\n\t"
4682  "out %[port] , %[hi]" "\n\t"
4683  "mov %[n1] , %[lo]" "\n\t"
4684  "out %[port] , %[n2]" "\n\t"
4685  "rjmp .+0" "\n\t"
4686  "sbrc %[byte] , 5" "\n\t"
4687  "mov %[n1] , %[hi]" "\n\t"
4688  "out %[port] , %[lo]" "\n\t"
4689  "rjmp .+0" "\n\t"
4690  "out %[port] , %[hi]" "\n\t"
4691  "mov %[n2] , %[lo]" "\n\t"
4692  "out %[port] , %[n1]" "\n\t"
4693  "rjmp .+0" "\n\t"
4694  "sbrc %[byte] , 4" "\n\t"
4695  "mov %[n2] , %[hi]" "\n\t"
4696  "out %[port] , %[lo]" "\n\t"
4697  "rjmp .+0" "\n\t"
4698  "out %[port] , %[hi]" "\n\t"
4699  "mov %[n1] , %[lo]" "\n\t"
4700  "out %[port] , %[n2]" "\n\t"
4701  "rjmp .+0" "\n\t"
4702  "sbrc %[byte] , 3" "\n\t"
4703  "mov %[n1] , %[hi]" "\n\t"
4704  "out %[port] , %[lo]" "\n\t"
4705  "rjmp .+0" "\n\t"
4706  "out %[port] , %[hi]" "\n\t"
4707  "mov %[n2] , %[lo]" "\n\t"
4708  "out %[port] , %[n1]" "\n\t"
4709  "rjmp .+0" "\n\t"
4710  "sbrc %[byte] , 2" "\n\t"
4711  "mov %[n2] , %[hi]" "\n\t"
4712  "out %[port] , %[lo]" "\n\t"
4713  "rjmp .+0" "\n\t"
4714  "out %[port] , %[hi]" "\n\t"
4715  "mov %[n1] , %[lo]" "\n\t"
4716  "out %[port] , %[n2]" "\n\t"
4717  "rjmp .+0" "\n\t"
4718  "sbrc %[byte] , 1" "\n\t"
4719  "mov %[n1] , %[hi]" "\n\t"
4720  "out %[port] , %[lo]" "\n\t"
4721  "rjmp .+0" "\n\t"
4722  "out %[port] , %[hi]" "\n\t"
4723  "mov %[n2] , %[lo]" "\n\t"
4724  "out %[port] , %[n1]" "\n\t"
4725  "rjmp .+0" "\n\t"
4726  "sbrc %[byte] , 0" "\n\t"
4727  "mov %[n2] , %[hi]" "\n\t"
4728  "out %[port] , %[lo]" "\n\t"
4729  "sbiw %[count], 1" "\n\t"
4730  "out %[port] , %[hi]" "\n\t"
4731  "mov %[n1] , %[lo]" "\n\t"
4732  "out %[port] , %[n2]" "\n\t"
4733  "ld %[byte] , %a[ptr]+" "\n\t"
4734  "sbrc %[byte] , 7" "\n\t"
4735  "mov %[n1] , %[hi]" "\n\t"
4736  "out %[port] , %[lo]" "\n\t"
4737  "brne headB" "\n"
4738  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
4739  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
4740  [lo] "r" (lo));
4741 
4742  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
4743  }
4744  #endif
4745  #if defined(PORTC) || defined(PORTF)
4746  else
4747  #endif
4748  #endif
4749 
4750  #if defined(PORTC)
4751  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
4752  if(port == &PORTC) {
4753  #endif
4754 
4755  hi = PORTC | pinMask;
4756  lo = PORTC & ~pinMask;
4757  n1 = lo;
4758  if(b & 0x80) n1 = hi;
4759 
4760  asm volatile(
4761  "headC:" "\n\t"
4762  "out %[port] , %[hi]" "\n\t"
4763  "mov %[n2] , %[lo]" "\n\t"
4764  "out %[port] , %[n1]" "\n\t"
4765  "rjmp .+0" "\n\t"
4766  "sbrc %[byte] , 6" "\n\t"
4767  "mov %[n2] , %[hi]" "\n\t"
4768  "out %[port] , %[lo]" "\n\t"
4769  "rjmp .+0" "\n\t"
4770  "out %[port] , %[hi]" "\n\t"
4771  "mov %[n1] , %[lo]" "\n\t"
4772  "out %[port] , %[n2]" "\n\t"
4773  "rjmp .+0" "\n\t"
4774  "sbrc %[byte] , 5" "\n\t"
4775  "mov %[n1] , %[hi]" "\n\t"
4776  "out %[port] , %[lo]" "\n\t"
4777  "rjmp .+0" "\n\t"
4778  "out %[port] , %[hi]" "\n\t"
4779  "mov %[n2] , %[lo]" "\n\t"
4780  "out %[port] , %[n1]" "\n\t"
4781  "rjmp .+0" "\n\t"
4782  "sbrc %[byte] , 4" "\n\t"
4783  "mov %[n2] , %[hi]" "\n\t"
4784  "out %[port] , %[lo]" "\n\t"
4785  "rjmp .+0" "\n\t"
4786  "out %[port] , %[hi]" "\n\t"
4787  "mov %[n1] , %[lo]" "\n\t"
4788  "out %[port] , %[n2]" "\n\t"
4789  "rjmp .+0" "\n\t"
4790  "sbrc %[byte] , 3" "\n\t"
4791  "mov %[n1] , %[hi]" "\n\t"
4792  "out %[port] , %[lo]" "\n\t"
4793  "rjmp .+0" "\n\t"
4794  "out %[port] , %[hi]" "\n\t"
4795  "mov %[n2] , %[lo]" "\n\t"
4796  "out %[port] , %[n1]" "\n\t"
4797  "rjmp .+0" "\n\t"
4798  "sbrc %[byte] , 2" "\n\t"
4799  "mov %[n2] , %[hi]" "\n\t"
4800  "out %[port] , %[lo]" "\n\t"
4801  "rjmp .+0" "\n\t"
4802  "out %[port] , %[hi]" "\n\t"
4803  "mov %[n1] , %[lo]" "\n\t"
4804  "out %[port] , %[n2]" "\n\t"
4805  "rjmp .+0" "\n\t"
4806  "sbrc %[byte] , 1" "\n\t"
4807  "mov %[n1] , %[hi]" "\n\t"
4808  "out %[port] , %[lo]" "\n\t"
4809  "rjmp .+0" "\n\t"
4810  "out %[port] , %[hi]" "\n\t"
4811  "mov %[n2] , %[lo]" "\n\t"
4812  "out %[port] , %[n1]" "\n\t"
4813  "rjmp .+0" "\n\t"
4814  "sbrc %[byte] , 0" "\n\t"
4815  "mov %[n2] , %[hi]" "\n\t"
4816  "out %[port] , %[lo]" "\n\t"
4817  "sbiw %[count], 1" "\n\t"
4818  "out %[port] , %[hi]" "\n\t"
4819  "mov %[n1] , %[lo]" "\n\t"
4820  "out %[port] , %[n2]" "\n\t"
4821  "ld %[byte] , %a[ptr]+" "\n\t"
4822  "sbrc %[byte] , 7" "\n\t"
4823  "mov %[n1] , %[hi]" "\n\t"
4824  "out %[port] , %[lo]" "\n\t"
4825  "brne headC" "\n"
4826  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
4827  : [port] "I" (_SFR_IO_ADDR(PORTC)), [ptr] "e" (ptr), [hi] "r" (hi),
4828  [lo] "r" (lo));
4829 
4830  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
4831  }
4832  #endif
4833  #if defined(PORTF)
4834  else
4835  #endif
4836  #endif
4837 
4838  #if defined(PORTF)
4839  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
4840  if(port == &PORTF) {
4841  #endif // defined(PORTD/B/C)
4842 
4843  hi = PORTF | pinMask;
4844  lo = PORTF & ~pinMask;
4845  n1 = lo;
4846  if(b & 0x80) n1 = hi;
4847 
4848  asm volatile(
4849  "headF:" "\n\t"
4850  "out %[port] , %[hi]" "\n\t"
4851  "mov %[n2] , %[lo]" "\n\t"
4852  "out %[port] , %[n1]" "\n\t"
4853  "rjmp .+0" "\n\t"
4854  "sbrc %[byte] , 6" "\n\t"
4855  "mov %[n2] , %[hi]" "\n\t"
4856  "out %[port] , %[lo]" "\n\t"
4857  "rjmp .+0" "\n\t"
4858  "out %[port] , %[hi]" "\n\t"
4859  "mov %[n1] , %[lo]" "\n\t"
4860  "out %[port] , %[n2]" "\n\t"
4861  "rjmp .+0" "\n\t"
4862  "sbrc %[byte] , 5" "\n\t"
4863  "mov %[n1] , %[hi]" "\n\t"
4864  "out %[port] , %[lo]" "\n\t"
4865  "rjmp .+0" "\n\t"
4866  "out %[port] , %[hi]" "\n\t"
4867  "mov %[n2] , %[lo]" "\n\t"
4868  "out %[port] , %[n1]" "\n\t"
4869  "rjmp .+0" "\n\t"
4870  "sbrc %[byte] , 4" "\n\t"
4871  "mov %[n2] , %[hi]" "\n\t"
4872  "out %[port] , %[lo]" "\n\t"
4873  "rjmp .+0" "\n\t"
4874  "out %[port] , %[hi]" "\n\t"
4875  "mov %[n1] , %[lo]" "\n\t"
4876  "out %[port] , %[n2]" "\n\t"
4877  "rjmp .+0" "\n\t"
4878  "sbrc %[byte] , 3" "\n\t"
4879  "mov %[n1] , %[hi]" "\n\t"
4880  "out %[port] , %[lo]" "\n\t"
4881  "rjmp .+0" "\n\t"
4882  "out %[port] , %[hi]" "\n\t"
4883  "mov %[n2] , %[lo]" "\n\t"
4884  "out %[port] , %[n1]" "\n\t"
4885  "rjmp .+0" "\n\t"
4886  "sbrc %[byte] , 2" "\n\t"
4887  "mov %[n2] , %[hi]" "\n\t"
4888  "out %[port] , %[lo]" "\n\t"
4889  "rjmp .+0" "\n\t"
4890  "out %[port] , %[hi]" "\n\t"
4891  "mov %[n1] , %[lo]" "\n\t"
4892  "out %[port] , %[n2]" "\n\t"
4893  "rjmp .+0" "\n\t"
4894  "sbrc %[byte] , 1" "\n\t"
4895  "mov %[n1] , %[hi]" "\n\t"
4896  "out %[port] , %[lo]" "\n\t"
4897  "rjmp .+0" "\n\t"
4898  "out %[port] , %[hi]" "\n\t"
4899  "mov %[n2] , %[lo]" "\n\t"
4900  "out %[port] , %[n1]" "\n\t"
4901  "rjmp .+0" "\n\t"
4902  "sbrc %[byte] , 0" "\n\t"
4903  "mov %[n2] , %[hi]" "\n\t"
4904  "out %[port] , %[lo]" "\n\t"
4905  "sbiw %[count], 1" "\n\t"
4906  "out %[port] , %[hi]" "\n\t"
4907  "mov %[n1] , %[lo]" "\n\t"
4908  "out %[port] , %[n2]" "\n\t"
4909  "ld %[byte] , %a[ptr]+" "\n\t"
4910  "sbrc %[byte] , 7" "\n\t"
4911  "mov %[n1] , %[hi]" "\n\t"
4912  "out %[port] , %[lo]" "\n\t"
4913  "brne headF" "\n"
4914  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
4915  : [port] "I" (_SFR_IO_ADDR(PORTF)), [ptr] "e" (ptr), [hi] "r" (hi),
4916  [lo] "r" (lo));
4917 
4918  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
4919  }
4920  #endif // defined(PORTD/B/C)
4921  #endif // defined(PORTF)
4922  } else {
4923 
4924  volatile uint8_t next, bit;
4925 
4926  hi = *port | pinMask;
4927  lo = *port & ~pinMask;
4928  next = lo;
4929  bit = 8;
4930 
4931  asm volatile(
4932  "head20:" "\n\t" // Clk Pseudocode (T = 0)
4933  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
4934  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
4935  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
4936  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 6)
4937  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
4938  "dec %[bit]" "\n\t" // 1 bit-- (T = 8)
4939  "breq nextbyte20" "\n\t" // 1-2 if(bit == 0)
4940  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
4941  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
4942  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
4943  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
4944  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
4945  "rjmp head20" "\n\t" // 2 -> head20 (next bit out)
4946  "nextbyte20:" "\n\t" // (T = 10)
4947  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
4948  "nop" "\n\t" // 1 nop (T = 13)
4949  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 14)
4950  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 16)
4951  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
4952  "brne head20" "\n" // 2 if(i != 0) -> (next byte)
4953  : [port] "+e" (port),
4954  [byte] "+r" (b),
4955  [bit] "+r" (bit),
4956  [next] "+r" (next),
4957  [count] "+w" (i)
4958  : [hi] "r" (hi),
4959  [lo] "r" (lo),
4960  [ptr] "e" (ptr));
4961  }
4962  #elif (F_CPU >= 11100000UL) && (F_CPU <= 14300000UL)
4963  if(is800KHz) {
4964  volatile uint8_t next;
4965 
4966  // PORTD OUTPUT ----------------------------------------------------
4967 
4968  #if defined(PORTD)
4969  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
4970  if(port == &PORTD) {
4971  #endif
4972 
4973  hi = PORTD | pinMask;
4974  lo = PORTD & ~pinMask;
4975  next = lo;
4976  if(b & 0x80) next = hi;
4977  asm volatile(
4978  "headD:" "\n\t" // (T = 0)
4979  "out %[port], %[hi]" "\n\t" // (T = 1)
4980  "rcall bitTimeD" "\n\t" // Bit 7 (T = 15)
4981  "out %[port], %[hi]" "\n\t"
4982  "rcall bitTimeD" "\n\t" // Bit 6
4983  "out %[port], %[hi]" "\n\t"
4984  "rcall bitTimeD" "\n\t" // Bit 5
4985  "out %[port], %[hi]" "\n\t"
4986  "rcall bitTimeD" "\n\t" // Bit 4
4987  "out %[port], %[hi]" "\n\t"
4988  "rcall bitTimeD" "\n\t" // Bit 3
4989  "out %[port], %[hi]" "\n\t"
4990  "rcall bitTimeD" "\n\t" // Bit 2
4991  "out %[port], %[hi]" "\n\t"
4992  "rcall bitTimeD" "\n\t" // Bit 1
4993  // Bit 0:
4994  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi (T = 1)
4995  "rjmp .+0" "\n\t" // 2 nop nop (T = 3)
4996  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 5)
4997  "out %[port] , %[next]" "\n\t" // 1 PORT = next (T = 6)
4998  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
4999  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 0x80) (T = 8)
5000  "mov %[next] , %[hi]" "\n\t" // 0-1 next = hi (T = 9)
5001  "nop" "\n\t" // 1 (T = 10)
5002  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo (T = 11)
5003  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 13)
5004  "brne headD" "\n\t" // 2 if(i != 0) -> (next byte)
5005  "rjmp doneD" "\n\t"
5006  "bitTimeD:" "\n\t" // nop nop nop (T = 4)
5007  "out %[port], %[next]" "\n\t" // 1 PORT = next (T = 5)
5008  "mov %[next], %[lo]" "\n\t" // 1 next = lo (T = 6)
5009  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 7)
5010  "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 0x80) (T = 8)
5011  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 9)
5012  "nop" "\n\t" // 1 (T = 10)
5013  "out %[port], %[lo]" "\n\t" // 1 PORT = lo (T = 11)
5014  "ret" "\n\t" // 4 nop nop nop nop (T = 15)
5015  "doneD:" "\n"
5016  : [byte] "+r" (b),
5017  [next] "+r" (next),
5018  [count] "+w" (i)
5019  : [port] "I" (_SFR_IO_ADDR(PORTD)),
5020  [ptr] "e" (ptr),
5021  [hi] "r" (hi),
5022  [lo] "r" (lo));
5023 
5024  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
5025  } else
5026  #endif
5027  #endif
5028 
5029  #if defined(PORTB)
5030  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
5031  if(port == &PORTB) {
5032  #endif
5033 
5034  hi = PORTB | pinMask;
5035  lo = PORTB & ~pinMask;
5036  next = lo;
5037  if(b & 0x80) next = hi;
5038 
5039  asm volatile(
5040  "headB:" "\n\t"
5041  "out %[port], %[hi]" "\n\t"
5042  "rcall bitTimeB" "\n\t"
5043  "out %[port], %[hi]" "\n\t"
5044  "rcall bitTimeB" "\n\t"
5045  "out %[port], %[hi]" "\n\t"
5046  "rcall bitTimeB" "\n\t"
5047  "out %[port], %[hi]" "\n\t"
5048  "rcall bitTimeB" "\n\t"
5049  "out %[port], %[hi]" "\n\t"
5050  "rcall bitTimeB" "\n\t"
5051  "out %[port], %[hi]" "\n\t"
5052  "rcall bitTimeB" "\n\t"
5053  "out %[port], %[hi]" "\n\t"
5054  "rcall bitTimeB" "\n\t"
5055  "out %[port] , %[hi]" "\n\t"
5056  "rjmp .+0" "\n\t"
5057  "ld %[byte] , %a[ptr]+" "\n\t"
5058  "out %[port] , %[next]" "\n\t"
5059  "mov %[next] , %[lo]" "\n\t"
5060  "sbrc %[byte] , 7" "\n\t"
5061  "mov %[next] , %[hi]" "\n\t"
5062  "nop" "\n\t"
5063  "out %[port] , %[lo]" "\n\t"
5064  "sbiw %[count], 1" "\n\t"
5065  "brne headB" "\n\t"
5066  "rjmp doneB" "\n\t"
5067  "bitTimeB:" "\n\t"
5068  "out %[port], %[next]" "\n\t"
5069  "mov %[next], %[lo]" "\n\t"
5070  "rol %[byte]" "\n\t"
5071  "sbrc %[byte], 7" "\n\t"
5072  "mov %[next], %[hi]" "\n\t"
5073  "nop" "\n\t"
5074  "out %[port], %[lo]" "\n\t"
5075  "ret" "\n\t"
5076  "doneB:" "\n"
5077  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
5078  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
5079  [lo] "r" (lo));
5080 
5081  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
5082  }
5083  #endif
5084  #if defined(PORTC) || defined(PORTF)
5085  else
5086  #endif
5087  #endif
5088 
5089  #if defined(PORTC)
5090  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
5091  if(port == &PORTC) {
5092  #endif
5093 
5094  hi = PORTC | pinMask;
5095  lo = PORTC & ~pinMask;
5096  next = lo;
5097  if(b & 0x80) next = hi;
5098 
5099  asm volatile(
5100  "headC:" "\n\t"
5101  "out %[port], %[hi]" "\n\t"
5102  "rcall bitTimeC" "\n\t"
5103  "out %[port], %[hi]" "\n\t"
5104  "rcall bitTimeC" "\n\t"
5105  "out %[port], %[hi]" "\n\t"
5106  "rcall bitTimeC" "\n\t"
5107  "out %[port], %[hi]" "\n\t"
5108  "rcall bitTimeC" "\n\t"
5109  "out %[port], %[hi]" "\n\t"
5110  "rcall bitTimeC" "\n\t"
5111  "out %[port], %[hi]" "\n\t"
5112  "rcall bitTimeC" "\n\t"
5113  "out %[port], %[hi]" "\n\t"
5114  "rcall bitTimeC" "\n\t"
5115  "out %[port] , %[hi]" "\n\t"
5116  "rjmp .+0" "\n\t"
5117  "ld %[byte] , %a[ptr]+" "\n\t"
5118  "out %[port] , %[next]" "\n\t"
5119  "mov %[next] , %[lo]" "\n\t"
5120  "sbrc %[byte] , 7" "\n\t"
5121  "mov %[next] , %[hi]" "\n\t"
5122  "nop" "\n\t"
5123  "out %[port] , %[lo]" "\n\t"
5124  "sbiw %[count], 1" "\n\t"
5125  "brne headC" "\n\t"
5126  "rjmp doneC" "\n\t"
5127  "bitTimeC:" "\n\t"
5128  "out %[port], %[next]" "\n\t"
5129  "mov %[next], %[lo]" "\n\t"
5130  "rol %[byte]" "\n\t"
5131  "sbrc %[byte], 7" "\n\t"
5132  "mov %[next], %[hi]" "\n\t"
5133  "nop" "\n\t"
5134  "out %[port], %[lo]" "\n\t"
5135  "ret" "\n\t"
5136  "doneC:" "\n"
5137  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
5138  : [port] "I" (_SFR_IO_ADDR(PORTC)), [ptr] "e" (ptr), [hi] "r" (hi),
5139  [lo] "r" (lo));
5140 
5141  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
5142  }
5143  #endif
5144  #if defined(PORTF)
5145  else
5146  #endif
5147  #endif
5148 
5149  #if defined(PORTF)
5150  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
5151  if(port == &PORTF) {
5152  #endif
5153 
5154  hi = PORTF | pinMask;
5155  lo = PORTF & ~pinMask;
5156  next = lo;
5157  if(b & 0x80) next = hi;
5158 
5159  asm volatile(
5160  "headF:" "\n\t"
5161  "out %[port], %[hi]" "\n\t"
5162  "rcall bitTimeC" "\n\t"
5163  "out %[port], %[hi]" "\n\t"
5164  "rcall bitTimeC" "\n\t"
5165  "out %[port], %[hi]" "\n\t"
5166  "rcall bitTimeC" "\n\t"
5167  "out %[port], %[hi]" "\n\t"
5168  "rcall bitTimeC" "\n\t"
5169  "out %[port], %[hi]" "\n\t"
5170  "rcall bitTimeC" "\n\t"
5171  "out %[port], %[hi]" "\n\t"
5172  "rcall bitTimeC" "\n\t"
5173  "out %[port], %[hi]" "\n\t"
5174  "rcall bitTimeC" "\n\t"
5175  "out %[port] , %[hi]" "\n\t"
5176  "rjmp .+0" "\n\t"
5177  "ld %[byte] , %a[ptr]+" "\n\t"
5178  "out %[port] , %[next]" "\n\t"
5179  "mov %[next] , %[lo]" "\n\t"
5180  "sbrc %[byte] , 7" "\n\t"
5181  "mov %[next] , %[hi]" "\n\t"
5182  "nop" "\n\t"
5183  "out %[port] , %[lo]" "\n\t"
5184  "sbiw %[count], 1" "\n\t"
5185  "brne headF" "\n\t"
5186  "rjmp doneC" "\n\t"
5187  "bitTimeC:" "\n\t"
5188  "out %[port], %[next]" "\n\t"
5189  "mov %[next], %[lo]" "\n\t"
5190  "rol %[byte]" "\n\t"
5191  "sbrc %[byte], 7" "\n\t"
5192  "mov %[next], %[hi]" "\n\t"
5193  "nop" "\n\t"
5194  "out %[port], %[lo]" "\n\t"
5195  "ret" "\n\t"
5196  "doneC:" "\n"
5197  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
5198  : [port] "I" (_SFR_IO_ADDR(PORTF)), [ptr] "e" (ptr), [hi] "r" (hi),
5199  [lo] "r" (lo));
5200 
5201  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
5202  }
5203  #endif
5204  #endif
5205  } else {
5206  volatile uint8_t next, bit;
5207 
5208  hi = *port | pinMask;
5209  lo = *port & ~pinMask;
5210  next = lo;
5211  bit = 8;
5212 
5213  asm volatile(
5214  "head30:" "\n\t" // Clk Pseudocode (T = 0)
5215  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
5216  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
5217  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
5218  "rjmp .+0" "\n\t" // 2 nop nop (T = 6)
5219  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 8)
5220  "rjmp .+0" "\n\t" // 2 nop nop (T = 10)
5221  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
5222  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
5223  "nop" "\n\t" // 1 nop (T = 15)
5224  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 17)
5225  "rjmp .+0" "\n\t" // 2 nop nop (T = 19)
5226  "dec %[bit]" "\n\t" // 1 bit-- (T = 20)
5227  "breq nextbyte30" "\n\t" // 1-2 if(bit == 0)
5228  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 22)
5229  "rjmp .+0" "\n\t" // 2 nop nop (T = 24)
5230  "rjmp .+0" "\n\t" // 2 nop nop (T = 26)
5231  "rjmp .+0" "\n\t" // 2 nop nop (T = 28)
5232  "rjmp head30" "\n\t" // 2 -> head30 (next bit out)
5233  "nextbyte30:" "\n\t" // (T = 22)
5234  "nop" "\n\t" // 1 nop (T = 23)
5235  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 24)
5236  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 26)
5237  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 28)
5238  "brne head30" "\n" // 1-2 if(i != 0) -> (next byte)
5239  : [port] "+e" (port),
5240  [byte] "+r" (b),
5241  [bit] "+r" (bit),
5242  [next] "+r" (next),
5243  [count] "+w" (i)
5244  : [hi] "r" (hi),
5245  [lo] "r" (lo),
5246  [ptr] "e" (ptr));
5247  }
5248  #elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L)
5249  if(is800KHz) {
5250  volatile uint8_t next, bit;
5251 
5252  hi = *port | pinMask;
5253  lo = *port & ~pinMask;
5254  next = lo;
5255  bit = 8;
5256 
5257  asm volatile(
5258  "head20:" "\n\t" // Clk Pseudocode (T = 0)
5259  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
5260  "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 128)
5261  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
5262  "dec %[bit]" "\n\t" // 1 bit-- (T = 5)
5263  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 7)
5264  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 8)
5265  "breq nextbyte20" "\n\t" // 1-2 if(bit == 0) (from dec above)
5266  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
5267  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
5268  "nop" "\n\t" // 1 nop (T = 13)
5269  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15)
5270  "nop" "\n\t" // 1 nop (T = 16)
5271  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
5272  "rjmp head20" "\n\t" // 2 -> head20 (next bit out)
5273  "nextbyte20:" "\n\t" // (T = 10)
5274  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 11)
5275  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 13)
5276  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15)
5277  "nop" "\n\t" // 1 nop (T = 16)
5278  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
5279  "brne head20" "\n" // 2 if(i != 0) -> (next byte)
5280  : [port] "+e" (port),
5281  [byte] "+r" (b),
5282  [bit] "+r" (bit),
5283  [next] "+r" (next),
5284  [count] "+w" (i)
5285  : [ptr] "e" (ptr),
5286  [hi] "r" (hi),
5287  [lo] "r" (lo));
5288  } else {
5289 
5290  volatile uint8_t next, bit;
5291 
5292  hi = *port | pinMask;
5293  lo = *port & ~pinMask;
5294  next = lo;
5295  bit = 8;
5296 
5297  asm volatile(
5298  "head40:" "\n\t" // Clk Pseudocode (T = 0)
5299  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
5300  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
5301  "mov %[next] , %[hi]" "\n\t" // 0-1 next = hi (T = 4)
5302  "rjmp .+0" "\n\t" // 2 nop nop (T = 6)
5303  "rjmp .+0" "\n\t" // 2 nop nop (T = 8)
5304  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 10)
5305  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
5306  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
5307  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
5308  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
5309  "rjmp .+0" "\n\t" // 2 nop nop (T = 20)
5310  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 22)
5311  "nop" "\n\t" // 1 nop (T = 23)
5312  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 24)
5313  "dec %[bit]" "\n\t" // 1 bit-- (T = 25)
5314  "breq nextbyte40" "\n\t" // 1-2 if(bit == 0)
5315  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 27)
5316  "nop" "\n\t" // 1 nop (T = 28)
5317  "rjmp .+0" "\n\t" // 2 nop nop (T = 30)
5318  "rjmp .+0" "\n\t" // 2 nop nop (T = 32)
5319  "rjmp .+0" "\n\t" // 2 nop nop (T = 34)
5320  "rjmp .+0" "\n\t" // 2 nop nop (T = 36)
5321  "rjmp .+0" "\n\t" // 2 nop nop (T = 38)
5322  "rjmp head40" "\n\t" // 2 -> head40 (next bit out)
5323  "nextbyte40:" "\n\t" // (T = 27)
5324  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 28)
5325  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 30)
5326  "rjmp .+0" "\n\t" // 2 nop nop (T = 32)
5327  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 34)
5328  "rjmp .+0" "\n\t" // 2 nop nop (T = 36)
5329  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 38)
5330  "brne head40" "\n" // 1-2 if(i != 0) -> (next byte)
5331  : [port] "+e" (port),
5332  [byte] "+r" (b),
5333  [bit] "+r" (bit),
5334  [next] "+r" (next),
5335  [count] "+w" (i)
5336  : [ptr] "e" (ptr),
5337  [hi] "r" (hi),
5338  [lo] "r" (lo));
5339  }
5340  #else
5341  #error "CPU SPEED NOT SUPPORTED"
5342  #endif
5343  #elif defined(__arm__)
5344 
5345 
5346  #if defined(TEENSYDUINO) && defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6
5347  #define CYCLES_800_T0H (F_CPU / 4000000)
5348  #define CYCLES_800_T1H (F_CPU / 1250000)
5349  #define CYCLES_800 (F_CPU / 800000)
5350  #define CYCLES_400_T0H (F_CPU / 2000000)
5351  #define CYCLES_400_T1H (F_CPU / 833333)
5352  #define CYCLES_400 (F_CPU / 400000)
5353 
5354  uint8_t *p = pixels,
5355  *end = p + numBytes, pix, mask;
5356  volatile uint8_t *set = portSetRegister(pin),
5357  *clr = portClearRegister(pin);
5358  uint32_t cyc;
5359 
5360  ARM_DEMCR |= ARM_DEMCR_TRCENA;
5361  ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
5362 
5363  if(is800KHz) {
5364  cyc = ARM_DWT_CYCCNT + CYCLES_800;
5365  while(p < end) {
5366  pix = *p++;
5367  for(mask = 0x80; mask; mask >>= 1) {
5368  while(ARM_DWT_CYCCNT - cyc < CYCLES_800);
5369  cyc = ARM_DWT_CYCCNT;
5370  *set = 1;
5371  if(pix & mask) {
5372  while(ARM_DWT_CYCCNT - cyc < CYCLES_800_T1H);
5373  } else {
5374  while(ARM_DWT_CYCCNT - cyc < CYCLES_800_T0H);
5375  }
5376  *clr = 1;
5377  }
5378  }
5379  while(ARM_DWT_CYCCNT - cyc < CYCLES_800);
5380  } else {
5381  cyc = ARM_DWT_CYCCNT + CYCLES_400;
5382  while(p < end) {
5383  pix = *p++;
5384  for(mask = 0x80; mask; mask >>= 1) {
5385  while(ARM_DWT_CYCCNT - cyc < CYCLES_400);
5386  cyc = ARM_DWT_CYCCNT;
5387  *set = 1;
5388  if(pix & mask) {
5389  while(ARM_DWT_CYCCNT - cyc < CYCLES_400_T1H);
5390  } else {
5391  while(ARM_DWT_CYCCNT - cyc < CYCLES_400_T0H);
5392  }
5393  *clr = 1;
5394  }
5395  }
5396  while(ARM_DWT_CYCCNT - cyc < CYCLES_400);
5397  }
5398  #else
5399  #error "Sorry, only 48 MHz is supported, please set Tools > CPU Speed to 48 MHz"
5400  #endif
5401  #elif defined(ESP8266) || defined(ESP32)
5402 
5403  espShow(pin, pixels, numBytes, is800KHz);
5404 
5405  #elif defined(__ARDUINO_ARC__)
5406 
5407  // Arduino 101 -----------------------------------------------------------
5408 
5409  #define NOPx7 { __builtin_arc_nop(); \
5410  __builtin_arc_nop(); __builtin_arc_nop(); \
5411  __builtin_arc_nop(); __builtin_arc_nop(); \
5412  __builtin_arc_nop(); __builtin_arc_nop(); }
5413 
5414  PinDescription *pindesc = &g_APinDescription[pin];
5415  register uint32_t loop = 8 * numBytes; // one loop to handle all bytes and all bits
5416  register uint8_t *p = pixels;
5417  register uint32_t currByte = (uint32_t) (*p);
5418  register uint32_t currBit = 0x80 & currByte;
5419  register uint32_t bitCounter = 0;
5420  register uint32_t first = 1;
5421 
5422  if (pindesc->ulGPIOType == SS_GPIO) {
5423  register uint32_t reg = pindesc->ulGPIOBase + SS_GPIO_SWPORTA_DR;
5424  uint32_t reg_val = __builtin_arc_lr((volatile uint32_t)reg);
5425  register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
5426  register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
5427 
5428  loop += 1;
5429  while(loop--) {
5430  if(!first) {
5431  currByte <<= 1;
5432  bitCounter++;
5433  }
5434 
5435  // 1 is >550ns high and >450ns low; 0 is 200..500ns high and >450ns low
5436  __builtin_arc_sr(first ? reg_bit_low : reg_bit_high, (volatile uint32_t)reg);
5437  if(currBit) { // ~400ns HIGH (740ns overall)
5438  NOPx7
5439  NOPx7
5440  }
5441  // ~340ns HIGH
5442  NOPx7
5443  __builtin_arc_nop();
5444 
5445  // 820ns LOW; per spec, max allowed low here is 5000ns */
5446  __builtin_arc_sr(reg_bit_low, (volatile uint32_t)reg);
5447  NOPx7
5448  NOPx7
5449 
5450  if(bitCounter >= 8) {
5451  bitCounter = 0;
5452  currByte = (uint32_t) (*++p);
5453  }
5454 
5455  currBit = 0x80 & currByte;
5456  first = 0;
5457  }
5458  } else if(pindesc->ulGPIOType == SOC_GPIO) {
5459  register uint32_t reg = pindesc->ulGPIOBase + SOC_GPIO_SWPORTA_DR;
5460  uint32_t reg_val = MMIO_REG_VAL(reg);
5461  register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
5462  register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
5463 
5464  loop += 1; // include first, special iteration
5465  while(loop--) {
5466  if(!first) {
5467  currByte <<= 1;
5468  bitCounter++;
5469  }
5470  MMIO_REG_VAL(reg) = first ? reg_bit_low : reg_bit_high;
5471  if(currBit) { // ~430ns HIGH (740ns overall)
5472  NOPx7
5473  NOPx7
5474  __builtin_arc_nop();
5475  }
5476  // ~310ns HIGH
5477  NOPx7
5478 
5479  // 850ns LOW; per spec, max allowed low here is 5000ns */
5480  MMIO_REG_VAL(reg) = reg_bit_low;
5481  NOPx7
5482  NOPx7
5483 
5484  if(bitCounter >= 8) {
5485  bitCounter = 0;
5486  currByte = (uint32_t) (*++p);
5487  }
5488 
5489  currBit = 0x80 & currByte;
5490  first = 0;
5491  }
5492  }
5493 
5494  #else
5495  #error Architecture not supported
5496  #endif
5497 
5498  #ifndef NRF52
5499  interrupts();
5500  #endif
5501 
5502  endTime = micros();
5503  }
5504 
5505  void NeoPixel::setPin(uint8_t p) {
5506  if(begun && (pin >= 0)) pinMode(pin, INPUT);
5507  pin = p;
5508  if(begun) {
5509  pinMode(p, OUTPUT);
5510  digitalWrite(p, LOW);
5511  }
5512  #ifdef __AVR__
5513  port = portOutputRegister(digitalPinToPort(p));
5514  pinMask = digitalPinToBitMask(p);
5515  #endif
5516  }
5517 
5519  uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
5520 
5521  if(n < numLEDs) {
5522  if(brightness) { // See notes in setBrightness()
5523  r = (r * brightness) >> 8;
5524  g = (g * brightness) >> 8;
5525  b = (b * brightness) >> 8;
5526  }
5527  uint8_t *p;
5528  if(wOffset == rOffset) {
5529  p = &pixels[n * 3];
5530  } else {
5531  p = &pixels[n * 4];
5532  p[wOffset] = 0;
5533  }
5534  p[rOffset] = r;
5535  p[gOffset] = g;
5536  p[bOffset] = b;
5537  }
5538  }
5539 
5541  uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
5542 
5543  if(n < numLEDs) {
5544  if(brightness) {
5545  r = (r * brightness) >> 8;
5546  g = (g * brightness) >> 8;
5547  b = (b * brightness) >> 8;
5548  w = (w * brightness) >> 8;
5549  }
5550  uint8_t *p;
5551  if(wOffset == rOffset) {
5552  p = &pixels[n * 3];
5553  } else {
5554  p = &pixels[n * 4];
5555  p[wOffset] = w;
5556  }
5557  p[rOffset] = r;
5558  p[gOffset] = g;
5559  p[bOffset] = b;
5560  }
5561  }
5562 
5563  void NeoPixel::setPixelColor(uint16_t n, uint32_t c) {
5564  if(n < numLEDs) {
5565  uint8_t *p,
5566  r = (uint8_t)(c >> 16),
5567  g = (uint8_t)(c >> 8),
5568  b = (uint8_t)c;
5569  if(brightness) {
5570  r = (r * brightness) >> 8;
5571  g = (g * brightness) >> 8;
5572  b = (b * brightness) >> 8;
5573  }
5574  if(wOffset == rOffset) {
5575  p = &pixels[n * 3];
5576  } else {
5577  p = &pixels[n * 4];
5578  uint8_t w = (uint8_t)(c >> 24);
5579  p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
5580  }
5581  p[rOffset] = r;
5582  p[gOffset] = g;
5583  p[bOffset] = b;
5584  }
5585  }
5586 
5587  uint32_t NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b) {
5588  return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
5589  }
5590 
5591  uint32_t NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
5592  return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
5593  }
5594 
5595  uint32_t NeoPixel::getPixelColor(uint16_t n) const {
5596  if(n >= numLEDs) return 0;
5597 
5598  uint8_t *p;
5599 
5600  if(wOffset == rOffset) {
5601  p = &pixels[n * 3];
5602  if(brightness) {
5603 
5604  return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
5605  (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
5606  ( (uint32_t)(p[bOffset] << 8) / brightness );
5607  } else {
5608  return ((uint32_t)p[rOffset] << 16) |
5609  ((uint32_t)p[gOffset] << 8) |
5610  (uint32_t)p[bOffset];
5611  }
5612  } else {
5613  p = &pixels[n * 4];
5614  if(brightness) {
5615  return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) |
5616  (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
5617  (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
5618  ( (uint32_t)(p[bOffset] << 8) / brightness );
5619  } else {
5620  return ((uint32_t)p[wOffset] << 24) |
5621  ((uint32_t)p[rOffset] << 16) |
5622  ((uint32_t)p[gOffset] << 8) |
5623  (uint32_t)p[bOffset];
5624  }
5625  }
5626  }
5627 
5628 
5629  uint8_t *NeoPixel::getPixels(void) const {
5630  return pixels;
5631  }
5632 
5633  uint16_t NeoPixel::numPixels(void) const {
5634  return numLEDs;
5635  }
5636 
5637  void NeoPixel::setBrightness(uint8_t b) {
5638 
5639  uint8_t newBrightness = b + 1;
5640  if(newBrightness != brightness) {
5641  uint8_t c,
5642  *ptr = pixels,
5643  oldBrightness = brightness - 1;
5644  uint16_t scale;
5645  if(oldBrightness == 0) scale = 0; // Avoid /0
5646  else if(b == 255) scale = 65535 / oldBrightness;
5647  else scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
5648  for(uint16_t i=0; i<numBytes; i++) {
5649  c = *ptr;
5650  *ptr++ = (c * scale) >> 8;
5651  }
5652  brightness = newBrightness;
5653  }
5654  }
5655 
5656  uint8_t NeoPixel::getBrightness(void) const {
5657  return brightness - 1;
5658  }
5659 
5660  void NeoPixel::clear() {
5661  memset(pixels, 0, numBytes);
5662  }
5663 
5664  static const uint8_t PROGMEM _sineTable[256] = {
5665  128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,
5666  176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,
5667  218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,
5668  245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,
5669  255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,
5670  245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,
5671  218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,
5672  176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,
5673  128,124,121,118,115,112,109,106,103,100, 97, 93, 90, 88, 85, 82,
5674  79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
5675  37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
5676  10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0,
5677  0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
5678  10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
5679  37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
5680  79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124};
5681 
5682  static const uint8_t PROGMEM _gammaTable[256] = {
5683  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5684  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
5685  1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
5686  3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
5687  7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12,
5688  13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
5689  20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
5690  30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
5691  42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
5692  58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
5693  76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
5694  97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
5695  122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
5696  150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
5697  182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
5698  218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255};
5699 
5700  uint8_t NeoPixel::sine8(uint8_t x) const {
5701  return pgm_read_byte(&_sineTable[x]); // 0-255 in, 0-255 out
5702  }
5703 
5704  uint8_t NeoPixel::gamma8(uint8_t x) const {
5705  return pgm_read_byte(&_gammaTable[x]); // 0-255 in, 0-255 out
5706  }
5707 
5709  #endif
5710  #endif
5711 
5942 #if EBOARD_COPY_AND_PASTE > 0x0
5943 
5945  extern int eVirtual_main();
5947 
5949  void setup(void);
5950 
5952  void setup(void) {
5953  //setup of RX and TX should be handled manually - in everyCase ^^
5956  #if EBOARD_DEBUG_MODE > 0x0
5957  Serial.begin(EBOARD_DEBUG_SPEED);
5958  #endif
5959  //this will initialize the interrupt handling!
5960  cli();
5961  TCCR1A = 0; TCCR1B = 0; //clear registers;
5962  OCR1A = EBOARD_PWM_SPE * 15624;
5963  TCCR1B |= (1 << WGM12); TCCR1B |= (1 << CS10); TCCR1B |= (1 << CS12);
5964  TIMSK1 |= (1 << OCIE1A);
5965  sei();
5966  #if EBOARD_BLUETOOTH > 0x0
5967  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
5970  Serial1.begin(38400);
5971  #else
5972  _serial.begin(38400);
5973  #endif
5975  #endif
5976  #if EBOARD_I2C > 0x0
5977  Wire.begin();
5978  #endif
5979  #if EBOARD_SHIFT_REGISTER > 0x0
5980  pinMode(PIN_SHIFT_CLK,OUTPUT);
5981  pinMode(PIN_SHIFT_DAT,OUTPUT);
5982  pinMode(PIN_SHIFT_LAT,OUTPUT);
5983  shiftAll(); //set all to 0
5984  #endif
5985  #if EBOARD_USE_SPI > 0x0 && (EBOARD_NANO == 0)
5986  _servoHandler.begin(); //Setup SPI
5987  #endif
5988 
5989  #if EBOARD_DEBUG_MODE > 0x0
5990  Serial.print(eVirtual_main());
5991  Serial.println(" -- Exit Code. \n Program has finished. Reset to start again");
5992  #else
5993  eVirtual_main();
5994  #endif
5995  if (STOP) {} //prevent unused error
5996  delay(200);
5997  cli(); //disable timers after running the program :D
5998  writePWM(0);analogWrite(PIN_MOTOR_SPE,0);
5999  }
6002  void loop(void);
6004  void loop(void){
6005  //shall be empty
6006  }
6008 
6009 #endif
6010 
6011 #else
6012  #error This library is build for arduino-devices and should be used only in the Arduino IDE or with a similar linking process
6013 #endif
6014 #pragma GCC diagnostic pop
6015 #pragma pack(pop)
6016 
6017 #endif
uint16_t _rx_delay_intrabit
the rx startbit delay
Definition: eBoard.h:1597
uint8_t * pixels
stores the pixels
Definition: eBoard.h:4460
void onRequest(void(*function)(void))
this will set the user_onRequest method
optVAL_t _pwmValue
Definition: eBoard.h:2399
volatile uint8_t * port
the used port register
Definition: eBoard.h:4473
virtual size_t write(uint8_t data)
this will write a single unsigned 8-bit value to address
bool checkPin(optVAL_t idx, optVAL_t mode=0x1)
[COPY&PASTE] [CHECK_PINS] Check if a pin is set to a specific mode
void recv(void)
private receive routine called each time interrupt handler gets triggered
SoccerBoard(void)
The constructor.
void setTX(uint8_t transmitPin)
sets a specific pin to be &#39;the chosen one&#39; as a txPin
int8_t pin
stores the pin -1 if the pin wasn&#39;t set
Definition: eBoard.h:4456
uint8_t gOffset
stores the green color offset
Definition: eBoard.h:4464
void begin(long speed)
the start function to setup delay_values etc.
void shiftSingle(optVAL_t idx, bool val)
[SHIFT] Changes a single output Pin
AX12Servo * connected[2]
stores the pointers to the registerd AX12Servo
Definition: eBoard.h:3247
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
uint8_t _transmitBitMask
the pin mask to address the tx pin
Definition: eBoard.h:1590
[COPY&PASTE] This is the SoccerBoard ghost struct :D
Definition: eBoard.h:2730
static void(* user_onReceive)(int numBytes)
twi slave [Rx]receive-event user def handler
Definition: eBoard.h:881
void writeVal(const T &val)
[BLUETOOTH] writes Data to bluetooth
byte sendWait(const byte what)
sends data.
#define PIN_SHIFT_LAT
Definition: eBoard.h:1538
void setPosLimit(optVAL_t posLimit)
Sets the position limits for the servos.
static volatile uint8_t _receive_buffer_head
current location in rxBuffer
Definition: eBoard.h:1612
[COPY&PASTE] This is the AX12Servo ghost struct :D
Definition: eBoard.h:3049
static void detachInterrupt(void)
disables the interrupt feature
void write(void)
this will write values stored in B and C
static uint8_t rxBufferIndex
this defines the rxBuffer Index - current position in rxBuffer array
Definition: eBoard.h:860
bool canShow(void)
this will determine if the next show is available [last show finished]
void storePosition(int pos, int speed=0x3FF)
This saves the Servo Position.
int actSpe
stores the actual &#39;would use speed&#39; of the AX12Servo
Definition: eBoard.h:3160
optVAL_t getPosition(void)
This "kind of" returns the Servo-Position.
virtual size_t write(uint8_t byte)
writes a specific value to the tx register
void setID(optVAL_t newID)
change the AX-12 Servo this object should speak to
#define PIN_MAX
Definition: eBoard.h:475
uint8_t getBrightness(void) const
returns the current set brightness
[SPI] This is used to avoid path resolving issues and defines the common known Arduino SPI interface ...
Definition: eBoard.h:1274
uint16_t numLEDs
stores the amount of LEDs
Definition: eBoard.h:4449
I2CInOut(SoccerBoard &, optVAL_t, optVAL_t, optVAL_t, optVAL_t)
The constructor.
void setVelocity(optVAL_t velocity)
Sets the default speed of servos.
void button(int)
šŸ”§ I prevent errors!
#define EBOARD_DEBUG_SPEED
Definition: eBoard.h:1410
bool isListening(void)
checks if this object is the listening object
~NeoPixel(void)
the destructor [calling free on pixel and freeing input pin]
optVAL_t countSetBits(optVAL_t x)
[COPY&PASTE] [CHECK_PWM] counts high-bits in an int/byte (determined by IGNORE_SIZE) ...
byte pY
posY
Definition: eBoard.h:4042
#define LCD_COMMAND_DISPLAY_OFF
Definition: eBoard.h:3797
TwoWire Wire
this is the well-known Arduino Wire Interface, just a little bit &#39;modified&#39; ;P
Definition: eBoard.h:1216
#define PIN_BLUETOOTH_RX
Definition: eBoard.h:1491
[SPI] This is used to communicate with the smart servo shield &#160;&#160;&#160;&#160;&#160;&#160;&#160; Don&#39;t use manually ...
Definition: eBoard.h:2525
static uint8_t txBufferIndex
this defines the txBuffer Index - current position in txBuffer array
Definition: eBoard.h:869
static void onRequestService(void)
twi slave [Tx]transmitting-event handler
void loop(void)
[COPY&PASTE] As we have an Arduino we need a setup function ;)
bool is800kHz
determines the speed the communcation is working on
Definition: eBoard.h:4445
uint16_t _rx_delay_stopbit
the rx stopbit dely
Definition: eBoard.h:1599
char channel(optVAL_t)
will return the next char received by the module. A 64 byte Serial buffer is included! ...
uint8_t bOffset
stores the blue color offset
Definition: eBoard.h:4466
This is used to avoid path resolving issues and defines the common known Arduino Wire-Interface &#160;&#160;&#160;...
Definition: eBoard.h:855
int peek(void)
reads the actual pointed rxBuffer element without dropping it
void led(int idx, bool state)
[MEGA] Control the OnBoard LED
uint8_t rx_pin_read(void)
simple routine to read the rxPin by registers
optVAL_t _OpwmValue
Definition: eBoard.h:2399
bool begun
true if NeoPixel::begin has been called
Definition: eBoard.h:4447
static uint8_t transmitting
&#39;boolean&#39; value. Set to 1 if transmitting => in master write mode
Definition: eBoard.h:874
RB14Scan(void)
The constructor.
void s2Cmd(optVAL_t o, optVAL_t t)
this function will execute two cmd sends without starting and without ending the transmission ...
void ledOff(int idx)
[MEGA] Deactivate the OnBoard LED
optVAL_t readPin(optVAL_t idx, bool dig=true)
read a digital state from an INPUTpin
uint8_t gamma8(uint8_t x) const
acces to the gamma-correction-8-bit table ;D
void ledMeter(int)
[MEGA] Activate the OnBoard LED
#define EBOARD_PWM_SPE
Definition: eBoard.h:1432
void writePin(optVAL_t idx, bool val)
write a boolean state to an output pin
void powerOn(optVAL_t id)
Set the state of a certain D-pin to HIGH.
#define LCD_COMMAND_MODE
Definition: eBoard.h:3793
long store_bits
[SHIFT] Manipulate me to set Pins via bitSet operations
Definition: eBoard.h:2367
void changeModes(optVAL_t, optVAL_t, optVAL_t)
šŸ”§ I prevent errors!
static void end(void)
this will end the SPI connection
int8_t getPin(void)
this will return the set data pin
void reset(void)
Resets the Soccerboard if EBOARD_USE_RESET is set to true.
bool _cI
called_guard
Definition: eBoard.h:4044
bool listen(void)
sets the SoftwareSerial object to be the listening one gaining control over the buffers etc...
bool reset(void)
clears the screen
bool isMoving(void)
Use this if you wan&#39;t to have a nice way of writing false.
#define PIN_SHIFT_DAT
Definition: eBoard.h:1532
void Reset(optVAL_t ID)
resets a servo
#define LCD_DATA_MODE
Definition: eBoard.h:3795
void sleep(uint16_t t)
Say goodnight!
#define _SS_MAX_RX_BUFF
Definition: eBoard.h:1555
void setTorque(uint16_t)
šŸ”§ I prevent errors!
void changeMode(bool newMode=true)
enable or disable the display
void ledOn(void)
Noone needs the AX-12 Servo LED^^.
#define PIN_MOTOR_DIR
Definition: eBoard.h:1512
static uint8_t rxBufferLength
this defines the length of rxBuffer
Definition: eBoard.h:862
#define LCD_COMMAND_DISPLAY_ON
Definition: eBoard.h:3799
static uint8_t txAddress
this defines the txAddress the transmitting Dta
Definition: eBoard.h:865
int storedPos
stores the position the Servo should go to DynamixelBoard::action()
Definition: eBoard.h:3144
void SetServoLimit(optVAL_t ID, optVAL_t upperLimit)
(probably) set the posLimit for only one servo (will be overwritten by write() => writePos()) ...
bool init(void)
initializes the Display called by:
void tx_pin_write(uint8_t pin_state)
writes a bool value on the txPin by registers
static uint8_t txBuffer[]
this defines the txBuffer used to enable delayed read
Definition: eBoard.h:867
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
sets the rgb color of a specific pixel
int upperLimit_temp
stores the posLimit value send with write()
Definition: eBoard.h:2618
#define LCD_PAGE_ADDRESSING
Definition: eBoard.h:3807
int optVAL_t
Definition: eBoard.h:1369
void changeAddress(optVAL_t)
šŸ”§ I prevent errors!
int eVirtual_main()
[COPY&PASTE] Assures the existence of the "qfix-code-main-method"
Definition: lcd_debug.cpp:27
this namespace contains all the Don&#39;t use manually classes ;)
SoftwareSerial _serial(0x13, 0x12)
this is the recomenned-to-use _serial object for bluetooth communcation :D
static void attachInterrupt(void)
enables the interrupt feature
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic=false)
the constructor for the SoftwareSerial object
virtual void flush(void)
resets the position in buffer and the buffer itself if the object is listening
#define SPI_MODE_MASK
Definition: eBoard.h:1255
static char _receive_buffer[64]
the buffer for rxBuffer
Definition: eBoard.h:1608
#define LCD_COMMAND_CHARGE_PUMP_SETTING
Definition: eBoard.h:3812
uint64_t pin_out
Definition: eBoard.h:2240
#define PIN_BLUETOOTH_TX
Definition: eBoard.h:1502
static void begin(void)
this will setup everything for SPI connection
optVAL_t id
stores the id of the AX12Servo obejct
Definition: eBoard.h:3155
void msleep(uint16_t t)
Say goodnight!
static bool STOP
Definition: eBoard.h:1361
void shiftAll(void)
[SHIFT] Changes bits according to store_bits
byte pX
the addressing mode (page/horizontal)
Definition: eBoard.h:4040
DynamixelBoard(SoccerBoard &)
The constructor.
ServoCds55 _servoHandler
this is the "to_use" instance of ServoCds55
Definition: eBoard.h:2702
void updateLength(uint16_t n)
this changes the length of the connected LED stripe
#define PIN_BLUETOOTH_STATE
Definition: eBoard.h:1480
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.
#define PIN_SHIFT_CLK
Definition: eBoard.h:1526
void write(optVAL_t ID, optVAL_t Pos)
Moves a Servo to a certain position.
void setPin(optVAL_t idx, optVAL_t mode=0x1)
[COPY&PASTE] set a pin to a certain mode => checkPin() will return true then
uint16_t numBytes
stores the byte size [pixels] used internally
Definition: eBoard.h:4451
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b)
returns a color value that can be used with NeoPixel::setPixelColor()
void setPin(uint8_t p)
sets pin for communication
virtual int read(void)
this will read a single byte from rxBuffer and increment the Index
#define EBOARD_SPI_SERVO_MAX
Definition: eBoard.h:1416
#define SPI_CLOCK_MASK
Definition: eBoard.h:1257
void clear(void)
this will reset all set pixels [won&#39;t call NeoPixel::show()]
bool setCursor(byte posX=0x0, byte posY=0x0)
set the position of the cursor
uint8_t * getPixels(void) const
this will give you access to the pixels
~SoftwareSerial(void)
the destructor of the SoftwareSerial object
void WritePos(optVAL_t ID, optVAL_t Pos)
Moves a Servo to a certain position.
LCD(SoccerBoard &soccerBoard, optVAL_t id=0x3C)
The constructor.
#define LCD_COMMAND_WHITE_BACKGROUND
Definition: eBoard.h:3803
void waitForButton(int)
šŸ”§ I prevent errors!
uint64_t pin_in
Definition: eBoard.h:2248
void motorsOff(void)
As requested this is the shortcut to disable the main motor.
int raw(optVAL_t)
this will check for connection status [will return true if pin not connected]
bool overflow(void)
returns the current overflow flag and disables it
static void setDataMode(uint8_t mode)
this will set the Data transfer mode
void s1Cmd(optVAL_t o)
this function will execute one cmd send without starting and without ending the transmission ...
#define LCD_HEIGHT
Definition: eBoard.h:3822
void updateType(uint16_t t)
this changes the type of communication between arduino and LED stripe
virtual int available(void)
checks if there is data to read available
NeoPixel(void)
the empty constructor
[COPY&PASTE] [BLUETOOTH] This is the RB14Scan ghost struct :D
Definition: eBoard.h:3308
uint8_t requestFrom(uint8_t address, uint8_t quantity)
this will read a specific quantity of bytes from a specific address
void changeBackground(bool newBackground=false)
changes the background of the display
static void onReceiveService(uint8_t *inBytes, int numBytes)
twi slave [Rx]receive-event handler
void begin()
begin the TwoWire communcation without any data set
optVAL_t ID
ID of the Display.
Definition: eBoard.h:4032
void rotate(optVAL_t, optVAL_t)
makes nothing
void pingI2C(optVAL_t ret[], optVAL_t ret_len)
Sends a byte to a certain I²C-Device.
void motor(uint8_t id, int16_t val)
As requested this is the ultimate shortcut ;)
uint8_t sine8(uint8_t x) const
acces to the sine-8-bit table ;D
bool digital(optVAL_t id)
Reads a digital value from a pin.
static void handle_interrupt(void)
used to handle interrupts on active listening object
int storedSpe
stores the Speed of the Servo DynamixelBoard::action()
Definition: eBoard.h:3150
[COPY&PASTE] This is the DynamixelBoard ghost struct :D
Definition: eBoard.h:3220
char readVal(char oF='.')
[BLUETOOTH] reads a single value from bluetooth if available!
#define SPI_CLOCK_DIV8
Definition: eBoard.h:1241
void checkIdx(optVAL_t idx)
[DEBUG_MODE] used to check if a pin index is in bounds
bool checkOverflow(void)
[BLUETOOTH] checks if theres a lack of Data!
TwoWire()
The constructor of the TwoWire class.
volatile uint8_t * _transmitPortRegister
the register the reveice pin is located on
Definition: eBoard.h:1592
static void setClockDivider(uint8_t rate)
this will change the clock devider the
void write(const char *const val)
this will write a constant string to the output
void beginTransmission(uint8_t address)
this will start a new transmission to a specific address => master mode
void power(optVAL_t id, bool state)
Set the state of a certain D-pin.
void s1Dat(optVAL_t o)
this function will execute one dat send without starting and without ending the transmission ...
#define PIN_MOTOR_SPE
Definition: eBoard.h:1519
uint32_t endTime
stores the last call time of show for NeoPixel::canShow()
Definition: eBoard.h:4470
void changeId(optVAL_t)
šŸ”§ I prevent errors!
uint8_t wOffset
stores the white color offset
Definition: eBoard.h:4468
uint16_t _tx_delay
the (generic) tx delay
Definition: eBoard.h:1601
DynamixelBoard * _conBoard
Definition: eBoard.h:3063
virtual int peek(void)
this will read a single byte from rxBuffer without increment the Index
void setBrightness(uint8_t val)
changes the brightness for all further acceses via NeoPixel::setPixelColor()
void setSpeed(optVAL_t)
šŸ”§ I prevent errors!
void lightOn(void)
enable the backlight
[COPY&PASTE] This is the I2CInOut ghost struct :D
Definition: eBoard.h:2979
void lightOff(void)
disable the backlight
void setRX(uint8_t receivePin)
sets a specific pin to be &#39;the chosen one&#39; as a rxPin
optVAL_t velocity_temp
stores the velocity value send with writePos()
Definition: eBoard.h:2622
bool clear(void)
clears the LCD
#define BUFFER_LENGTH
Definition: eBoard.h:837
SPIClass SPI
Definition: eBoard.h:1349
void onReceive(void(*function)(int))
this will set the user_onReceive method
uint8_t brightness
stores the brightness
Definition: eBoard.h:4458
uint8_t pinMask
the used pinMask
Definition: eBoard.h:4475
void __assert(const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp)
[DEBUG_MODE] custom assert message
void ledsOff(void)
[MEGA] Deactivate the OnBoard LED
#define SPI_2XCLOCK_MASK
Definition: eBoard.h:1259
static uint8_t txBufferLength
this defines the length of txBuffer
Definition: eBoard.h:871
static byte transfer(byte _data)
this will send a single bite via the SPI connection
void setPositionMode(void)
set the AX-12 Servo to positionMode
static void setBitOrder(uint8_t bitOrder)
this will set the BitOrder
void setup(void)
this is a guard
void end(void)
ends communcation on the rx pin
void action(void)
will force every AX12Servo to drive to AX12Servo::storedPos with AX12Servo::storedSpeed ...
static SoftwareSerial * active_object
the active SoftwareSerial object to operate on
Definition: eBoard.h:1614
bool changeBrightness(byte val=0x64)
changes the brightness of the display
void read(void)
šŸ”§ I prevent errors!
optVAL_t analog(optVAL_t id)
Reads an analog value from a pin.
void ledOn(int idx)
[MEGA] Activate the OnBoard LED
AX12Servo(void)
The constructor.
void ledOn(optVAL_t)
šŸ”§ I prevent errors!
bool changeID(optVAL_t newID=0x3C)
changes the address of the LCD display talked to
void setPosition(int pos, int speed=0x3FF)
This moves the Servo to the new position.
uint16_t _inverse_logic
determining if all pin reads etc whould be inverted (e.g. no pullup on rx);
Definition: eBoard.h:1606
DynamixelBoard dBoard(board)
the dBoard object
uint16_t _rx_delay_centering
the rx center delay
Definition: eBoard.h:1595
static volatile uint8_t _receive_buffer_tail
size of rxBuffer
Definition: eBoard.h:1610
uint8_t rOffset
stores the red color offset
Definition: eBoard.h:4462
uint8_t endTransmission(void)
this will end the transmission and send the STOP-sequence
bool isConnected(void)
[BLUETOOTH] this will check if the HC-05 is paired
void print(const char *data)
prints a string to the display
void setSpeedMode(void)
set the AX-12 Servo NOT to speedMode
void SetMotormode(optVAL_t ID, optVAL_t velocity)
(probably) set the velocity of only one Servo
virtual int available(void)
this will return the amount of rxBuffer left
uint8_t _receivePin
the id of the receive pin
Definition: eBoard.h:1584
void drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY)
draws a bitmap representet as an array of bytes
#define LCD_COMMAND_CHARGE_PUMP_ENABLE
Definition: eBoard.h:3814
#define LCD_WIDTH
Definition: eBoard.h:3818
void ledOff(void)
Noone needs the AX-12 Servo LED^^.
void powerOff(optVAL_t id)
Set the state of a certain D-pin to LOW.
uint16_t _buffer_overflow
determining if an _buffer_overflow occured
Definition: eBoard.h:1604
static void(* user_onRequest)(void)
twi slave [Tx]transmitting-event user def handler
Definition: eBoard.h:876
uint8_t _receiveBitMask
the pin mask to directly read from register (Rx)
Definition: eBoard.h:1586
virtual int read(void)
reads the actual pointed rxBuffer top element
optVAL_t sendI2C(optVAL_t deviceID, byte *buf, byte buf_len)
Sends a buffer of bytes to a certain I²C-Device.
PROGMEM const byte basicFont[][8]
Definition: eBoard.h:3432
optVAL_t cs
stores the ControlPin id
Definition: eBoard.h:2624
static uint8_t rxBuffer[]
this defines the rxBuffer used to enable delayed read
Definition: eBoard.h:858
volatile uint8_t * _receivePortRegister
the register the reveice pin is located on
Definition: eBoard.h:1588
void SetID(optVAL_t ID, optVAL_t newID)
change the ID of a special Servo
void begin(void)
this has to be called to start the communcation (you should call NeoPixel::setPin() before) ...
[NEO] this allows you to access Adafruit LED-stripes
Definition: eBoard.h:4312
virtual void flush(void)
as this isn&#39;t implemented in the offical Wire library, this does nothing xD
uint32_t getPixelColor(uint16_t n) const
returns the color of a specific pixel
void changeMotorID(optVAL_t)
šŸ”§ I prevent errors!
void show(void)
this will reveal the setPixels [via NeoPixel::setPixelColor() etc...]
uint16_t numPixels(void) const
returns the size of the LED stripe
void ledOff(optVAL_t)
šŸ”§ I prevent errors!
static void tunedDelay(uint16_t delay)
apply a specific delay to achieve higher precision
#define EBOARD_NEO_800KHZ
Definition: eBoard.h:4280
ServoCds55(optVAL_t CS=53)
The constructor.
void begin()
begin the communication and setup SPI
[I2C] [LCD] This is used to add support for OLED displays connected to the &#39;SoccerBoard&#39; ...
Definition: eBoard.h:3864
#define LCD_COMMAND_BLACK_BACKGROUND
Definition: eBoard.h:3801
void changeMotorID(optVAL_t newID)
change the AX-12 Servo this object should speak to
#define EBOARD_NEO_RGB
Definition: eBoard.h:4215
This is used to avoid path resolving issues and defines the common known Arduino SoftwareSerial inter...
Definition: eBoard.h:1581