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 
394 //i am a guard... leave me alone :D
395 #ifndef EBOARD_HEADER_GUARD
396  #define EBOARD_HEADER_GUARD
397 
398  #ifdef DOC
399  #define ARDUINO 200
400 
403  #define EBOARD_I2C 0x1
404 
408  #define EBOARD_LCD 0x1
409 
412  #define EBOARD_SHIFT_REGISTER 0x1
413 
416  #define EBOARD_BLUETOOTH 0x1
417 
420  #define REPT_TASK
421 
424  #define __AVR_ATmega2560__
425 
428  #define __AVR_ATmega328P__
429 
432  #define EBOARD_NEO 0x1
433 
439  #define HIGHSPEED
440  #define __AVR__
442  #endif
443 
444  #include <avr/pgmspace.h>
449  namespace eagle_impl {}
450  using namespace eagle_impl;
451  #ifndef EBOARD_GUESSPATH
452 
455  #define EBOARD_GUESSPATH 0x1
456  #endif
457 
458  #if defined(ARDUINO) //general platform-check [No tab]
459 
463  #define main eVirtual_main //main has a different meaning^^
464 
465  #if ARDUINO >= 100 //this could be only Arduino.h but this snippet is portable :D
466  #include "Arduino.h"
467  #else
468  #include <wiring.h>
469  #endif
470 
471  #if not ( defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__))
472  #error "This library was build for ARDUINO UNO R3 Aand ARDUINO MEGA 2560!"
473  #endif
474 
475  #if defined(__AVR_ATmega2560__)
476 
479  #define PIN_MAX 0x32 //53 pins to address - 4 !!53 is SS
480  #else
481  #define PIN_MAX 0xA // 13 Pins to address - 4 !!10 is SS
482  #endif
483 
484  #include <avr/io.h>
485  #include <avr/interrupt.h>
486 
487  #if EBOARD_I2C > 0x0 && EBOARD_GUESSPATH > 0x0
488  #define twi_h
490 
491  #include <inttypes.h>
492 
493  //#define ATMEGA8
494 
495  #ifndef TWI_FREQ
496  #define TWI_FREQ 100000L
497  #endif
498 
499  #ifndef TWI_BUFFER_LENGTH
500  #define TWI_BUFFER_LENGTH 32
501  #endif
502 
503  #define TWI_READY 0
504  #define TWI_MRX 1
505  #define TWI_MTX 2
506  #define TWI_SRX 3
507  #define TWI_STX 4
508 
509  void twi_init(void);
510  void twi_setAddress(uint8_t);
511  uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t);
512  uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t);
513  uint8_t twi_transmit(const uint8_t*, uint8_t);
514  void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
515  void twi_attachSlaveTxEvent( void (*)(void) );
516  void twi_reply(uint8_t);
517  void twi_stop(void);
518  void twi_releaseBus(void);
519 
520  #include <math.h>
521  #include <stdlib.h>
522  #include <inttypes.h>
523  #include <avr/io.h>
524  #include <avr/interrupt.h>
525  #include <compat/twi.h>
526 
527  #ifndef cbi
528  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
529  #endif
530 
531  #ifndef sbi
532  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
533  #endif
534 
535  #include "pins_arduino.h"
536 
537  static volatile uint8_t twi_state;
538  static volatile uint8_t twi_slarw;
539  static volatile uint8_t twi_sendStop;
540  static volatile uint8_t twi_inRepStart;
541 
542  static void (*twi_onSlaveTransmit)(void);
543  static void (*twi_onSlaveReceive)(uint8_t*, int);
544 
545  static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];
546  static volatile uint8_t twi_masterBufferIndex;
547  static volatile uint8_t twi_masterBufferLength;
548 
549  static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];
550  static volatile uint8_t twi_txBufferIndex;
551  static volatile uint8_t twi_txBufferLength;
552 
553  static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];
554  static volatile uint8_t twi_rxBufferIndex;
555 
556  static volatile uint8_t twi_error;
557 
558  void twi_init(void) {
559  twi_state = TWI_READY;
560  twi_sendStop = true;
561  twi_inRepStart = false;
562 
563  digitalWrite(SDA, 1);
564  digitalWrite(SCL, 1);
565 
566  cbi(TWSR, TWPS0);
567  cbi(TWSR, TWPS1);
568  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
569 
570  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
571  }
572 
573  void twi_setAddress(uint8_t address) {
574  TWAR = address << 1;
575  }
576 
577  uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) {
578  uint8_t i;
579 
580  if(TWI_BUFFER_LENGTH < length){
581  return 0;
582  }
583 
584  while(TWI_READY != twi_state){
585  continue;
586  }
587  twi_state = TWI_MRX;
588  twi_sendStop = sendStop;
589 
590  twi_error = 0xFF;
591 
592  twi_masterBufferIndex = 0;
593  twi_masterBufferLength = length-1;
594  twi_slarw = TW_READ;
595  twi_slarw |= address << 1;
596 
597  if (true == twi_inRepStart) {
598  twi_inRepStart = false;
599  TWDR = twi_slarw;
600  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
601  }
602  else
603  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
604 
605  while(TWI_MRX == twi_state){
606  continue;
607  }
608 
609  if (twi_masterBufferIndex < length)
610  length = twi_masterBufferIndex;
611 
612  for(i = 0; i < length; ++i){
613  data[i] = twi_masterBuffer[i];
614  }
615 
616  return length;
617  }
618 
619  uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
620  {
621  uint8_t i;
622 
623  if(TWI_BUFFER_LENGTH < length){
624  return 1;
625  }
626 
627  while(TWI_READY != twi_state){
628  continue;
629  }
630  twi_state = TWI_MTX;
631  twi_sendStop = sendStop;
632  twi_error = 0xFF;
633 
634  twi_masterBufferIndex = 0;
635  twi_masterBufferLength = length;
636 
637  for(i = 0; i < length; ++i){
638  twi_masterBuffer[i] = data[i];
639  }
640 
641  twi_slarw = TW_WRITE;
642  twi_slarw |= address << 1;
643 
644  if (true == twi_inRepStart) {
645  twi_inRepStart = false;
646  TWDR = twi_slarw;
647  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
648  }
649  else
650  TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
651 
652  while(wait && (TWI_MTX == twi_state)){
653  continue;
654  }
655 
656  if (twi_error == 0xFF)
657  return 0;
658  else if (twi_error == TW_MT_SLA_NACK)
659  return 2;
660  else if (twi_error == TW_MT_DATA_NACK)
661  return 3;
662  else
663  return 4;
664  }
665 
666  uint8_t twi_transmit(const uint8_t* data, uint8_t length) {
667  uint8_t i;
668 
669  if(TWI_BUFFER_LENGTH < length){
670  return 1;
671  }
672 
673  if(TWI_STX != twi_state){
674  return 2;
675  }
676 
677  twi_txBufferLength = length;
678  for(i = 0; i < length; ++i){
679  twi_txBuffer[i] = data[i];
680  }
681 
682  return 0;
683  }
684 
685  void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) {
686  twi_onSlaveReceive = function;
687  }
688 
689  void twi_attachSlaveTxEvent( void (*function)(void) ) {
690  twi_onSlaveTransmit = function;
691  }
692 
693  void twi_reply(uint8_t ack) {
694  if(ack){
695  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
696  }else{
697  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
698  }
699  }
700 
701 
702  void twi_stop(void) {
703  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
704 
705  while(TWCR & _BV(TWSTO)){
706  continue;
707  }
708 
709  twi_state = TWI_READY;
710  }
711 
712  void twi_releaseBus(void){
713  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
714  twi_state = TWI_READY;
715  }
716 
717  ISR(TWI_vect) {
718  switch(TW_STATUS){
719  case TW_START:
720  case TW_REP_START:
721  TWDR = twi_slarw;
722  twi_reply(1);
723  break;
724 
725  case TW_MT_SLA_ACK:
726  case TW_MT_DATA_ACK:
727  if(twi_masterBufferIndex < twi_masterBufferLength){
728  TWDR = twi_masterBuffer[twi_masterBufferIndex++];
729  twi_reply(1);
730  }else{
731  if (twi_sendStop)
732  twi_stop();
733  else {
734  twi_inRepStart = true;
735  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
736  twi_state = TWI_READY;
737  }
738  }
739  break;
740  case TW_MT_SLA_NACK:
741  twi_error = TW_MT_SLA_NACK;
742  twi_stop();
743  break;
744  case TW_MT_DATA_NACK:
745  twi_error = TW_MT_DATA_NACK;
746  twi_stop();
747  break;
748  case TW_MT_ARB_LOST:
749  twi_error = TW_MT_ARB_LOST;
750  twi_releaseBus();
751  break;
752 
753  case TW_MR_DATA_ACK:
754  twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
755  case TW_MR_SLA_ACK:
756  if(twi_masterBufferIndex < twi_masterBufferLength){
757  twi_reply(1);
758  }else{
759  twi_reply(0);
760  }
761  break;
762  case TW_MR_DATA_NACK:
763  twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
764  if (twi_sendStop)
765  twi_stop();
766  else {
767  twi_inRepStart = true;
768  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;
769  twi_state = TWI_READY;
770  }
771  break;
772  case TW_MR_SLA_NACK:
773  twi_stop();
774  break;
775  case TW_SR_SLA_ACK:
776  case TW_SR_GCALL_ACK:
777  case TW_SR_ARB_LOST_SLA_ACK:
778  case TW_SR_ARB_LOST_GCALL_ACK:
779  twi_state = TWI_SRX;
780  twi_rxBufferIndex = 0;
781  twi_reply(1);
782  break;
783  case TW_SR_DATA_ACK:
784  case TW_SR_GCALL_DATA_ACK:
785  if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
786  twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
787  twi_reply(1);
788  }else{
789  twi_reply(0);
790  }
791  break;
792  case TW_SR_STOP:
793  if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
794  twi_rxBuffer[twi_rxBufferIndex] = '\0';
795  }
796  twi_stop();
797  twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
798  twi_rxBufferIndex = 0;
799  twi_releaseBus();
800  break;
801  case TW_SR_DATA_NACK:
802  case TW_SR_GCALL_DATA_NACK:
803  twi_reply(0);
804  break;
805  case TW_ST_SLA_ACK:
806  case TW_ST_ARB_LOST_SLA_ACK:
807  twi_state = TWI_STX;
808  twi_txBufferIndex = 0;
809  twi_txBufferLength = 0;
810  twi_onSlaveTransmit();
811  if(0 == twi_txBufferLength){
812  twi_txBufferLength = 1;
813  twi_txBuffer[0] = 0x00;
814  }
815  case TW_ST_DATA_ACK:
816  TWDR = twi_txBuffer[twi_txBufferIndex++];
817  if(twi_txBufferIndex < twi_txBufferLength){
818  twi_reply(1);
819  }else{
820  twi_reply(0);
821  }
822  break;
823  case TW_ST_DATA_NACK:
824  case TW_ST_LAST_DATA:
825  twi_reply(1);
826  twi_state = TWI_READY;
827  break;
828 
829  case TW_NO_INFO:
830  break;
831  case TW_BUS_ERROR:
832  twi_error = TW_BUS_ERROR;
833  twi_stop();
834  break;
835  }
836  }
838  #include <inttypes.h>
839  #include "Stream.h"
840 
841  #define BUFFER_LENGTH 32
842  namespace eagle_impl {
859  class TwoWire : public Stream {
860  private:
862  static uint8_t rxBuffer[];
864  static uint8_t rxBufferIndex;
866  static uint8_t rxBufferLength;
867 
869  static uint8_t txAddress;
871  static uint8_t txBuffer[];
873  static uint8_t txBufferIndex;
875  static uint8_t txBufferLength;
876 
878  static uint8_t transmitting;
880  static void (*user_onRequest)(void);
885  static void (*user_onReceive)(int numBytes);
887  static void onRequestService(void);
893  static void onReceiveService(uint8_t* inBytes, int numBytes);
894 
895  public:
897  TwoWire();
899  void begin();
904  void begin(uint8_t address);
910  inline void begin(int address);
915  void beginTransmission(uint8_t address);
921  inline void beginTransmission(int address);
932  inline uint8_t endTransmission(void);
943  uint8_t endTransmission(uint8_t sendStop);
951  inline uint8_t requestFrom(uint8_t address, uint8_t quantity);
959  uint8_t requestFrom(uint8_t address , uint8_t quantity, uint8_t sendStop);
967  inline uint8_t requestFrom(int address, int quantity);
976  inline uint8_t requestFrom(int address, int quantity, int sendStop);
985  virtual size_t write(uint8_t data);
993  virtual size_t write(const uint8_t *data, size_t quantity);
998  virtual int available(void);
1004  virtual int read(void);
1010  virtual int peek(void);
1012  virtual void flush(void);
1019  void onReceive( void (*function)(int) );
1026  void onRequest( void (*function)(void) );
1027 
1028  /* Removed due to: not needed
1029  inline size_t write(unsigned long n) { return write((uint8_t)n); }
1030  inline size_t write(long n) { return write((uint8_t)n); }
1031  inline size_t write(unsigned int n) { return write((uint8_t)n); }
1032  inline size_t write(int n) { return write((uint8_t)n); }
1033  */
1034  using Print::write;
1035  };
1036  }
1037  extern "C" {
1038  #include <stdlib.h>
1039  #include <string.h>
1040  #include <inttypes.h>
1041  //#include "twi.h"
1042  }
1043 
1046  uint8_t TwoWire::rxBufferIndex = 0;
1047  uint8_t TwoWire::rxBufferLength = 0;
1048 
1049  uint8_t TwoWire::txAddress = 0;
1051  uint8_t TwoWire::txBufferIndex = 0;
1052  uint8_t TwoWire::txBufferLength = 0;
1053 
1054  uint8_t TwoWire::transmitting = 0;
1055  void (*TwoWire::user_onRequest)(void);
1056  void (*TwoWire::user_onReceive)(int);
1057 
1058  TwoWire::TwoWire() {}
1059 
1060  void TwoWire::begin(void) {
1061  rxBufferIndex = 0;
1062  rxBufferLength = 0;
1063 
1064  txBufferIndex = 0;
1065  txBufferLength = 0;
1066 
1067  twi_init();
1068  }
1069 
1070  void TwoWire::begin(uint8_t address) {
1071  twi_setAddress(address);
1072  twi_attachSlaveTxEvent(onRequestService);
1073  twi_attachSlaveRxEvent(onReceiveService);
1074  begin();
1075  }
1076 
1077  void TwoWire::begin(int address) {
1078  begin((uint8_t)address);
1079  }
1080 
1081  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
1082  if(quantity > BUFFER_LENGTH){
1083  quantity = BUFFER_LENGTH;
1084  }
1085  uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
1086  rxBufferIndex = 0;
1087  rxBufferLength = read;
1088 
1089  return read;
1090  }
1091 
1092  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
1093  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
1094  }
1095 
1096  uint8_t TwoWire::requestFrom(int address, int quantity) {
1097  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
1098  }
1099 
1100  uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
1101  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
1102  }
1103 
1104  void TwoWire::beginTransmission(uint8_t address) {
1105  transmitting = 1;
1106  txAddress = address;
1107  txBufferIndex = 0;
1108  txBufferLength = 0;
1109  }
1110 
1111  void TwoWire::beginTransmission(int address) {
1112  beginTransmission((uint8_t)address);
1113  }
1114 
1115  uint8_t TwoWire::endTransmission(uint8_t sendStop) {
1116  int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
1117  txBufferIndex = 0;
1118  txBufferLength = 0;
1119  transmitting = 0;
1120  return ret;
1121  }
1122 
1123  uint8_t TwoWire::endTransmission(void){
1124  return endTransmission(true);
1125  }
1126 
1127  size_t TwoWire::write(uint8_t data) {
1128  if(transmitting) {
1129  if(txBufferLength >= BUFFER_LENGTH) {
1130  setWriteError();
1131  return 0;
1132  }
1133  txBuffer[txBufferIndex] = data;
1134  ++txBufferIndex;
1136  }else{
1137  twi_transmit(&data, 1);
1138  }
1139  return 1;
1140  }
1141 
1142  size_t TwoWire::write(const uint8_t *data, size_t quantity) {
1143  if(transmitting){
1144  for(size_t i = 0; i < quantity; ++i) {
1145  write(data[i]);
1146  }
1147  }else{
1148  twi_transmit(data, quantity);
1149  }
1150  return quantity;
1151  }
1152 
1153  int TwoWire::available(void) {
1154  return rxBufferLength - rxBufferIndex;
1155  }
1156 
1157  int TwoWire::read(void) {
1158  int value = -1;
1159 
1161  value = rxBuffer[rxBufferIndex];
1162  ++rxBufferIndex;
1163  }
1164 
1165  return value;
1166  }
1167 
1168  int TwoWire::peek(void) {
1169  int value = -1;
1170 
1172  value = rxBuffer[rxBufferIndex];
1173  }
1174 
1175  return value;
1176  }
1177 
1178  void TwoWire::flush(void) {
1179  // XXX: to be implemented.
1180  }
1181 
1182  void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) {
1183  if(!user_onReceive){
1184  return;
1185  }
1186 
1188  return;
1189  }
1190 
1191  for(uint8_t i = 0; i < numBytes; ++i) {
1192  rxBuffer[i] = inBytes[i];
1193  }
1194  rxBufferIndex = 0;
1195  rxBufferLength = numBytes;
1196  user_onReceive(numBytes);
1197  }
1198 
1199  void TwoWire::onRequestService(void) {
1200  if(!user_onRequest) {
1201  return;
1202  }
1203 
1204  txBufferIndex = 0;
1205  txBufferLength = 0;
1206  user_onRequest();
1207  }
1208 
1209  void TwoWire::onReceive( void (*function)(int) ) {
1210  user_onReceive = function;
1211  }
1212 
1213  void TwoWire::onRequest( void (*function)(void) ) {
1214  user_onRequest = function;
1215  }
1216 
1218 
1220  TwoWire Wire = TwoWire();
1221 
1222  #endif
1223 
1226  #ifndef EBOARD_USE_SPI
1227  #define EBOARD_USE_SPI 0x1
1228  #endif
1229  #if EBOARD_USE_SPI > 0x0
1230  #define _SPI_H_INCLUDED
1232 
1233  #include <stdio.h>
1235  #define SPI_CLOCK_DIV4 0x00
1236  #define SPI_CLOCK_DIV16 0x01
1238  #define SPI_CLOCK_DIV64 0x02
1240  #define SPI_CLOCK_DIV128 0x03
1242  #define SPI_CLOCK_DIV2 0x04
1244  #define SPI_CLOCK_DIV8 0x05
1246  #define SPI_CLOCK_DIV32 0x06
1248 
1250  #define SPI_MODE0 0x00
1251  #define SPI_MODE1 0x04
1253  #define SPI_MODE2 0x08
1255  #define SPI_MODE3 0x0C
1257 
1259  #define SPI_MODE_MASK 0x0C
1260  #define SPI_CLOCK_MASK 0x03
1262  #define SPI_2XCLOCK_MASK 0x01
1264  namespace eagle_impl {
1278  struct SPIClass {
1284  inline static byte transfer(byte _data);
1288  inline static void attachInterrupt(void);
1292  inline static void detachInterrupt(void); // Default
1296  static void begin(void); // Default
1300  inline static void end(void);
1305  inline static void setBitOrder(uint8_t bitOrder);
1310  inline static void setDataMode(uint8_t mode);
1315  inline static void setClockDivider(uint8_t rate);
1316  };
1317  }
1319  byte SPIClass::transfer(byte _data) {
1320  SPDR = _data;
1321  while (!(SPSR & _BV(SPIF)));
1322  return SPDR;
1323  }
1324 
1325  void SPIClass::attachInterrupt() { SPCR |= _BV(SPIE);}
1326 
1327  void SPIClass::detachInterrupt() { SPCR &= ~_BV(SPIE);}
1328 
1329  void SPIClass::begin() {
1330  digitalWrite(SS, HIGH);
1331  pinMode(SS, OUTPUT); //doesn't block common use as_ OUTPUT!
1332  SPCR |= _BV(MSTR);
1333  SPCR |= _BV(SPE);
1334  pinMode(SCK, OUTPUT);
1335  pinMode(MOSI, OUTPUT);
1336  }
1337 
1338  void SPIClass::end() {SPCR &= ~_BV(SPE);}
1339 
1340  void SPIClass::setBitOrder(uint8_t bitOrder) {
1341  if(bitOrder == LSBFIRST) SPCR |= _BV(DORD);
1342  else SPCR &= ~(_BV(DORD));
1343  }
1344 
1345  void SPIClass::setDataMode(uint8_t mode) { SPCR = (SPCR & ~SPI_MODE_MASK) | mode; }
1346 
1347  void SPIClass::setClockDivider(uint8_t rate) {
1348  SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
1349  SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
1350  }
1352 
1353  SPIClass SPI;
1354 
1355  #endif
1356  #if (EBOARD_I2C > 0x0) && (EBOARD_LCD > 0x0)
1357  #include <avr/pgmspace.h>
1358  #endif
1359 
1365  static bool STOP = false;
1366 
1370  #ifdef IGNORE_SIZE
1371  typedef byte optVAL_t;
1372  #else
1373  typedef int optVAL_t;
1374  #endif
1375 
1379  #ifndef EBOARD_DEBUG_MODE
1380  #define EBOARD_DEBUG_MODE 0x1
1381  #endif
1382 
1386  #ifndef EBOARD_NANO
1387  #define EBOARD_NANO 0x0
1388  #endif
1389 
1392  #ifndef EBOARD_CHECK_PINS
1393  #define EBOARD_CHECK_PINS 0x1
1394  #endif
1395 
1396  #ifndef EBOARD_SHIFT_REGISTER
1397 
1400  #define EBOARD_SHIFT_REGISTER 0x0
1401  #endif
1402 
1406  #ifndef EBOARD_CHECK_PINS_PWM
1407  #define EBOARD_CHECK_PINS_PWM 0x1
1408  #endif
1409 
1413  #ifndef EBOARD_DEBUG_SPEED
1414  #define EBOARD_DEBUG_SPEED 9600
1415  #endif
1416 
1419  #ifndef EBOARD_SPI_SERVO_MAX
1420  #define EBOARD_SPI_SERVO_MAX 2
1421  #endif
1422 
1425  #ifndef EBOARD_USE_UTILITY
1426  #define EBOARD_USE_UTILITY 0x1
1427  #endif
1428 
1431  #define EBOARD_COPY_AND_PASTE 0x1
1432 
1435  #ifndef EBOARD_PWM_SPE
1436  #define EBOARD_PWM_SPE 1
1437  #endif
1438 
1439  #ifndef EBOARD_I2C
1440 
1443  #define EBOARD_I2C 0x0 //disabled by default
1444  #endif
1445 
1446  #ifndef EBOARD_BLUETOOTH
1447 
1450  #define EBOARD_BLUETOOTH 0x0
1451  #endif
1452 
1455  #ifndef EBOARD_CLAMP
1456  #define EBOARD_CLAMP 0x1
1457  #endif
1458 
1459 
1460  #ifndef EBOARD_NEO
1461 
1464  #define EBOARD_NEO 0x0
1465  #endif
1466 
1467 
1471  #ifndef EBOARD_USE_RESET
1472  #define EBOARD_USE_RESET 0x1
1473  #endif
1474 
1475  #if EBOARD_USE_RESET > 0x0
1476  #include <avr/wdt.h>
1477  #endif
1478 
1482  #ifndef PIN_BLUETOOTH_STATE
1483  #if defined(__AVR_ATmega2560__)
1484  #define PIN_BLUETOOTH_STATE 0x13 // 19
1485  #else
1486  #define PIN_BLUETOOTH_STATE 0x2
1487  #endif
1488  #endif
1489 
1493  #ifndef PIN_BLUETOOTH_RX
1494  #if defined(__AVR_ATmega2560__)
1495  #define PIN_BLUETOOTH_RX 0x13 // 19
1496  #else
1497  #define PIN_BLUETOOTH_RX 0x2
1498  #endif
1499  #endif
1500 
1504  #ifndef PIN_BLUETOOTH_TX
1505  #if defined(__AVR_ATmega2560__)
1506  #define PIN_BLUETOOTH_TX 0x12 // 18
1507  #else
1508  #define PIN_BLUETOOTH_TX 0x3
1509  #endif
1510  #endif
1511 
1515  #ifndef PIN_MOTOR_DIR
1516  #define PIN_MOTOR_DIR 0x4
1517  #endif
1518 
1522  #ifndef PIN_MOTOR_SPE
1523  #define PIN_MOTOR_SPE 0x5
1524  #endif
1525 
1529  #ifndef PIN_SHIFT_CLK
1530  #define PIN_SHIFT_CLK 0x6
1531  #endif
1532 
1535  #ifndef PIN_SHIFT_DAT
1536  #define PIN_SHIFT_DAT 0x7
1537  #endif
1538 
1541  #ifndef PIN_SHIFT_LAT
1542  #define PIN_SHIFT_LAT 0x8
1543  #endif
1544 
1545 
1546  //done by arduino
1547  //if this has an effect... something went wrong :D
1548  #ifndef HIGH
1549  #define HIGH 1
1550  #endif
1551  #ifndef LOW
1552  #define LOW 0
1553  #endif
1554 
1555  #if (EBOARD_BLUETOOTH > 0x0) && defined(__AVR_ATmega328P__)
1556  #if EBOARD_GUESSPATH > 0x0
1557  //#ifdef __linux__
1558  // #include "/usr/share/arduino/libraries/SoftwareSerial/SoftwareSerial.h"
1559  //#else
1560  // #include "C:\Program Files (x86)\Arduino\libraries\SoftwareSerial\SoftwareSerial.h"
1561  //#endif
1562  //#include "/usr/share/arduino/libraries/SoftwareSerial/SoftwareSerial.cpp"
1563 
1564  //again to resolve including errors we'll include the SoftwareSerial cpp file
1565 
1566  #define _SS_MAX_RX_BUFF 64 // RX buffer size
1567  #ifndef GCC_VERSION
1568  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
1569  #endif
1570  namespace eagle_impl {
1592  class SoftwareSerial : public Stream {
1593  private:
1595  uint8_t _receivePin;
1597  uint8_t _receiveBitMask;
1599  volatile uint8_t *_receivePortRegister;
1601  uint8_t _transmitBitMask;
1603  volatile uint8_t *_transmitPortRegister;
1604 
1606  uint16_t _rx_delay_centering;
1608  uint16_t _rx_delay_intrabit;
1610  uint16_t _rx_delay_stopbit;
1612  uint16_t _tx_delay;
1613 
1615  uint16_t _buffer_overflow:1;
1617  uint16_t _inverse_logic:1;
1619  static char _receive_buffer[_SS_MAX_RX_BUFF];
1621  static volatile uint8_t _receive_buffer_tail;
1623  static volatile uint8_t _receive_buffer_head;
1625  static SoftwareSerial *active_object;
1626 
1628  void recv(void);
1633  inline uint8_t rx_pin_read(void);
1638  inline void tx_pin_write(uint8_t pin_state);
1643  void setTX(uint8_t transmitPin);
1648  void setRX(uint8_t receivePin);
1653  static inline void tunedDelay(uint16_t delay);
1654 
1655  public:
1656  // public methods
1663  SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
1669  ~SoftwareSerial(void);
1685  void begin(long speed);
1690  bool listen(void);
1692  inline void end(void);
1697  inline bool isListening(void);
1702  inline bool overflow(void);
1707  int peek(void);
1714  virtual size_t write(uint8_t byte);
1719  virtual int read(void);
1724  virtual int available(void);
1728  virtual void flush(void);
1729  //used to save codespace
1730  using Print::write;
1732  static inline void handle_interrupt(void);
1733  };
1734  }
1736 
1737  bool SoftwareSerial::isListening(void) {
1738  return this == active_object;
1739  }
1740 
1741  bool SoftwareSerial::overflow(void) {
1742  bool ret = _buffer_overflow;
1743  _buffer_overflow = false;
1744  return ret;
1745  }
1746  /* was a workaround for arduino 0012 but not needed
1747  #undef int
1748  #undef char
1749  #undef long
1750  #undef byte
1751  #undef float
1752  #undef abs
1753  #undef round
1754  */
1755  #if EBOARD_DEBUG_MODE > 0x0
1756  #define _DEBUG 0
1757  #define _DEBUG_PIN1 11
1758  #define _DEBUG_PIN2 13
1759  #endif
1760  typedef struct _DELAY_TABLE {
1761  long baud;
1762  unsigned short rx_delay_centering;
1763  unsigned short rx_delay_intrabit;
1764  unsigned short rx_delay_stopbit;
1765  unsigned short tx_delay;
1766  } DELAY_TABLE;
1767 
1768  #if F_CPU == 16000000
1769 
1770  static const DELAY_TABLE PROGMEM table[] = {
1771  // baud rxcenter rxintra rxstop tx
1772  { 115200, 1, 17, 17, 12, },
1773  { 57600, 10, 37, 37, 33, },
1774  { 38400, 25, 57, 57, 54, },
1775  { 31250, 31, 70, 70, 68, },
1776  { 28800, 34, 77, 77, 74, },
1777  { 19200, 54, 117, 117, 114, },
1778  { 14400, 74, 156, 156, 153, },
1779  { 9600, 114, 236, 236, 233, },
1780  { 4800, 233, 474, 474, 471, },
1781  { 2400, 471, 950, 950, 947, },
1782  { 1200, 947, 1902, 1902, 1899, },
1783  { 600, 1902, 3804, 3804, 3800, },
1784  { 300, 3804, 7617, 7617, 7614, },
1785  };
1786 
1787  const int XMIT_START_ADJUSTMENT = 5;
1788 
1789  #elif F_CPU == 8000000
1790 
1791  static const DELAY_TABLE table[] PROGMEM = {
1792  // baud rxcenter rxintra rxstop tx
1793  { 115200, 1, 5, 5, 3, },
1794  { 57600, 1, 15, 15, 13, },
1795  { 38400, 2, 25, 26, 23, },
1796  { 31250, 7, 32, 33, 29, },
1797  { 28800, 11, 35, 35, 32, },
1798  { 19200, 20, 55, 55, 52, },
1799  { 14400, 30, 75, 75, 72, },
1800  { 9600, 50, 114, 114, 112, },
1801  { 4800, 110, 233, 233, 230, },
1802  { 2400, 229, 472, 472, 469, },
1803  { 1200, 467, 948, 948, 945, },
1804  { 600, 948, 1895, 1895, 1890, },
1805  { 300, 1895, 3805, 3805, 3802, },
1806  };
1807 
1808  const int XMIT_START_ADJUSTMENT = 4;
1809 
1810  #elif F_CPU == 20000000
1811 
1812  static const DELAY_TABLE PROGMEM table[] = {
1813  // baud rxcenter rxintra rxstop tx
1814  { 115200, 3, 21, 21, 18, },
1815  { 57600, 20, 43, 43, 41, },
1816  { 38400, 37, 73, 73, 70, },
1817  { 31250, 45, 89, 89, 88, },
1818  { 28800, 46, 98, 98, 95, },
1819  { 19200, 71, 148, 148, 145, },
1820  { 14400, 96, 197, 197, 194, },
1821  { 9600, 146, 297, 297, 294, },
1822  { 4800, 296, 595, 595, 592, },
1823  { 2400, 592, 1189, 1189, 1186, },
1824  { 1200, 1187, 2379, 2379, 2376, },
1825  { 600, 2379, 4759, 4759, 4755, },
1826  { 300, 4759, 9523, 9523, 9520, },
1827  };
1828 
1829  const int XMIT_START_ADJUSTMENT = 6;
1830 
1831  #else
1832  #error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
1833  #endif
1834 
1837  volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
1838  volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
1839  #if EBOARD_DEBUG_MODE > 0x0
1840  inline void DebugPulse(uint8_t pin, uint8_t count) {
1841  #if _DEBUG
1842  volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
1843 
1844  uint8_t val = *pport;
1845  while (count--)
1846  {
1847  *pport = val | digitalPinToBitMask(pin);
1848  *pport = val;
1849  }
1850  #endif
1851  }
1852  #endif
1853  inline void SoftwareSerial::tunedDelay(uint16_t delay) {
1854  uint8_t tmp=0;
1855 
1856  asm volatile("sbiw %0, 0x01 \n\t"
1857  "ldi %1, 0xFF \n\t"
1858  "cpi %A0, 0xFF \n\t"
1859  "cpc %B0, %1 \n\t"
1860  "brne .-10 \n\t"
1861  : "+r" (delay), "+a" (tmp)
1862  : "0" (delay)
1863  );
1864  }
1865 
1866  bool SoftwareSerial::listen() {
1867  if (active_object != this)
1868  {
1869  _buffer_overflow = false;
1870  uint8_t oldSREG = SREG;
1871  cli();
1873  active_object = this;
1874  SREG = oldSREG;
1875  return true;
1876  }
1877 
1878  return false;
1879  }
1880 
1881  void SoftwareSerial::recv() {
1882 
1883  #if GCC_VERSION < 40302
1884  asm volatile(
1885  "push r18 \n\t"
1886  "push r19 \n\t"
1887  "push r20 \n\t"
1888  "push r21 \n\t"
1889  "push r22 \n\t"
1890  "push r23 \n\t"
1891  "push r26 \n\t"
1892  "push r27 \n\t"
1893  ::);
1894  #endif
1895 
1896  uint8_t d = 0;
1897 
1898  if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) {
1899  // Wait approximately 1/2 of a bit width to "center" the sample
1901  #if EBOARD_DEBUG_MODE > 0x0
1902  DebugPulse(_DEBUG_PIN2, 1);
1903  #endif
1904  // Read each of the 8 bits
1905  for (uint8_t i=0x1; i; i <<= 1)
1906  {
1908  #if EBOARD_DEBUG_MODE > 0x0
1909  DebugPulse(_DEBUG_PIN2, 1);
1910  #endif
1911  uint8_t noti = ~i;
1912  if (rx_pin_read())
1913  d |= i;
1914  else
1915  d &= noti;
1916  }
1917 
1918  // skip the stop bit
1920  #if EBOARD_DEBUG_MODE > 0x0
1921  DebugPulse(_DEBUG_PIN2, 1);
1922  #endif
1923  if (_inverse_logic)
1924  d = ~d;
1925 
1927  _receive_buffer[_receive_buffer_tail] = d; // save new byte
1929  }
1930  else {
1931  #if EBOARD_DEBUG_MODE > 0x0
1932  #if _DEBUG // for scope: pulse pin as overflow indictator
1933  DebugPulse(_DEBUG_PIN1, 1);
1934  #endif
1935  #endif
1936  _buffer_overflow = true;
1937  }
1938  }
1939 
1940  #if GCC_VERSION < 40302
1941  asm volatile(
1942  "pop r27 \n\t"
1943  "pop r26 \n\t"
1944  "pop r23 \n\t"
1945  "pop r22 \n\t"
1946  "pop r21 \n\t"
1947  "pop r20 \n\t"
1948  "pop r19 \n\t"
1949  "pop r18 \n\t"
1950  ::);
1951  #endif
1952  }
1953 
1954  void SoftwareSerial::tx_pin_write(uint8_t pin_state) {
1955  if (pin_state == LOW)
1957  else
1959  }
1960 
1961  uint8_t SoftwareSerial::rx_pin_read() {
1963  }
1964 
1965  inline void SoftwareSerial::handle_interrupt() {
1966  if (active_object) {
1967  active_object->recv();
1968  }
1969  }
1970 
1971  #if defined(PCINT0_vect)
1972  ISR(PCINT0_vect) {
1974  }
1975  #endif
1976 
1977  #if defined(PCINT1_vect)
1978  ISR(PCINT1_vect) {
1980  }
1981  #endif
1982 
1983  #if defined(PCINT2_vect)
1984  ISR(PCINT2_vect) {
1986  }
1987  #endif
1988 
1989  #if defined(PCINT3_vect)
1990  ISR(PCINT3_vect) {
1992  }
1993  #endif
1994 
1995  SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
1996  _rx_delay_centering(0),
1997  _rx_delay_intrabit(0),
1998  _rx_delay_stopbit(0),
1999  _tx_delay(0),
2000  _buffer_overflow(false),
2001  _inverse_logic(inverse_logic) {
2002  setTX(transmitPin);
2003  setRX(receivePin);
2004  }
2005 
2006  SoftwareSerial::~SoftwareSerial() {
2007  end();
2008  }
2009 
2010  void SoftwareSerial::setTX(uint8_t tx) {
2011  pinMode(tx, OUTPUT);
2012  digitalWrite(tx, HIGH);
2013  _transmitBitMask = digitalPinToBitMask(tx);
2014  uint8_t port = digitalPinToPort(tx);
2015  _transmitPortRegister = portOutputRegister(port);
2016  }
2017 
2018  void SoftwareSerial::setRX(uint8_t rx) {
2019  pinMode(rx, INPUT);
2020  if (!_inverse_logic)
2021  digitalWrite(rx, HIGH);
2022  _receivePin = rx;
2023  _receiveBitMask = digitalPinToBitMask(rx);
2024  uint8_t port = digitalPinToPort(rx);
2025  _receivePortRegister = portInputRegister(port);
2026  }
2027 
2028  void SoftwareSerial::begin(long speed) {
2030 
2031  for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
2032  long baud = pgm_read_dword(&table[i].baud);
2033  if (baud == speed) {
2034  _rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
2035  _rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
2036  _rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
2037  _tx_delay = pgm_read_word(&table[i].tx_delay);
2038  break;
2039  }
2040  }
2041 
2042  if (_rx_delay_stopbit) {
2043  if (digitalPinToPCICR(_receivePin)) {
2044  *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
2045  *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
2046  }
2048  }
2049 
2050  #if _DEBUG
2051  pinMode(_DEBUG_PIN1, OUTPUT);
2052  pinMode(_DEBUG_PIN2, OUTPUT);
2053  #endif
2054 
2055  listen();
2056  }
2057 
2058  void SoftwareSerial::end() {
2059  if (digitalPinToPCMSK(_receivePin))
2060  *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
2061  }
2062 
2063 
2064  int SoftwareSerial::read() {
2065  if (!isListening())
2066  return -1;
2067 
2069  return -1;
2070 
2071  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
2073  return d;
2074  }
2075 
2077  if (!isListening())
2078  return 0;
2079 
2081  }
2082 
2083  size_t SoftwareSerial::write(uint8_t b) {
2084  if (_tx_delay == 0) {
2085  setWriteError();
2086  return 0;
2087  }
2088 
2089  uint8_t oldSREG = SREG;
2090  cli();
2091 
2092  tx_pin_write(_inverse_logic ? HIGH : LOW);
2093  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
2094 
2095  if (_inverse_logic) {
2096  for (byte mask = 0x01; mask; mask <<= 1) {
2097  if (b & mask)
2098  tx_pin_write(LOW);
2099  else
2100  tx_pin_write(HIGH);
2101 
2103  }
2104 
2105  tx_pin_write(LOW);
2106  }
2107  else {
2108  for (byte mask = 0x01; mask; mask <<= 1) {
2109  if (b & mask)
2110  tx_pin_write(HIGH);
2111  else
2112  tx_pin_write(LOW);
2114  }
2115 
2116  tx_pin_write(HIGH);
2117  }
2118 
2119  SREG = oldSREG;
2121 
2122  return 1;
2123  }
2124 
2125  void SoftwareSerial::flush() {
2126  if (!isListening())
2127  return;
2128 
2129  uint8_t oldSREG = SREG;
2130  cli();
2132  SREG = oldSREG;
2133  }
2134 
2135  int SoftwareSerial::peek() {
2136  if (!isListening())
2137  return -1;
2138 
2140  return -1;
2141 
2143  }
2145  #endif
2146 
2152  #endif
2153 
2154  #if EBOARD_DEBUG_MODE > 0x0
2155 
2158  #define __ASSERT_USE_STDERR
2159  #include <assert.h>
2177  void __assert (const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp);
2179  void __assert (const char *__func, const char *__file, optVAL_t __lineno, const char *__sexp){
2180  Serial.print("Error with: "); Serial.print(__func);
2181  Serial.print(" in "); Serial.print(__file);
2182  Serial.print(" @"); Serial.println(__lineno, DEC);
2183  Serial.print(" >>");
2184  Serial.println(__sexp);
2185  if(strcmp(__func,"checkIdx")==0){
2186  Serial.println(" This happens if an out of bounds exception");
2187  Serial.println(" has occured. Following pins shouldn't be used:");
2188  Serial.print(" D");Serial.print(PIN_BLUETOOTH_RX);Serial.print("&");
2189  Serial.print("D");Serial.print(PIN_BLUETOOTH_TX);
2190  Serial.println(" : Used for Bluetooth communication");
2191  Serial.print(" D");Serial.print(PIN_MOTOR_DIR);Serial.print("&");
2192  Serial.print("D");Serial.print(PIN_MOTOR_SPE);
2193  Serial.println(" : Used for main motor control");
2194  #if EBOARD_USE_SPI > 0x0
2195  Serial.print(" D10-13");
2196  Serial.println(": Used for smart-servo-shield");
2197  #endif
2198  } else if (strcmp(__func,"readPin")==0){
2199  Serial.println("You've tried to access an analogPin that isn't present on the board you're currently working on!");
2200  }
2201  Serial.flush();
2202  abort(); // halt after outputting information
2203  }
2205  #endif
2206 
2213  inline void checkIdx(optVAL_t idx);
2215  inline void checkIdx(optVAL_t idx){
2216  #if EBOARD_DEBUG_MODE > 0x0
2217  assert(idx>=0x0 && idx < PIN_MAX); //changed pins? change me! (didn't want to use macros)
2218  assert(idx!=PIN_BLUETOOTH_RX&&idx!=PIN_BLUETOOTH_TX);
2219  #endif
2220  }
2222 
2223  #if EBOARD_COPY_AND_PASTE > 0x0
2224  #if EBOARD_CHECK_PINS_PWM > 0x0
2225 
2234  optVAL_t count; //dont't want to overuse global space^^
2235  for (count = 0; x; count++)
2236  x &= x - 1;
2237  return count;
2238  }
2240  #endif
2241 
2242  #if EBOARD_CHECK_PINS > 0x0
2243 
2248  #if defined(__AVR_ATmega328P__) && not defined(__AVR_ATmega2560__)
2249  uint16_t pin_out = 0x0;
2250  #elif defined(__AVR_ATmega2560__)
2251  uint64_t pin_out = 0x0;
2252  #endif
2253 
2256  #if defined(__AVR_ATmega328P__) && not defined(__AVR_ATmega2560__)
2257  uint16_t pin_in = 0x0;
2258  #elif defined(__AVR_ATmega2560__)
2259  uint64_t pin_in = 0x0;
2260  #endif
2261 
2271  inline bool checkPin(optVAL_t idx, optVAL_t mode = OUTPUT);
2273  inline bool checkPin(optVAL_t idx, optVAL_t mode){
2274  checkIdx(idx);
2275  return (mode == OUTPUT)? ((pin_out & (1<<idx))>0x0):((pin_in & (1<<idx))>0x0);
2276  }
2278  #endif
2279 
2285  void setPin(optVAL_t idx, optVAL_t mode = OUTPUT);
2287  void setPin(optVAL_t idx, optVAL_t mode){
2288  #if EBOARD_CHECK_PINS > 0x0
2289  checkIdx(idx);
2290  if(mode==OUTPUT) { //possible to read from OUTPUT digital ... we won't do it
2291  pin_out |= (1<<idx);
2292  pin_in &= ~(1<<idx);
2293  }
2294  else {
2295  pin_in |= (1<<idx);
2296  pin_out &= ~(1<<idx);
2297  }
2298  #endif
2299  pinMode(idx, mode);
2300  }
2302  #endif
2303 
2304  #if EBOARD_BLUETOOTH > 0x0
2305 
2313  inline char readVal(char oF = '.');
2321  inline bool checkOverflow(void);
2326  template <typename T>
2327  inline void writeVal(const T& val);
2328 
2340  inline bool isConnected(void);
2342  inline bool checkOverflow(void) {
2343  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
2344  return false; //there is no hardware provided control for hardwareserial overflow
2345  #else
2346  return (_serial.overflow());
2347  #endif
2348  }
2349  inline char readVal(char oF) {
2350  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
2351  return ((Serial1.available())?(Serial1.read()):(oF));
2352  #else
2353  return ((_serial.available())?(_serial.read()):(oF));
2354  #endif
2355  }
2356  template<typename T>
2357  inline void writeVal(const T& val){
2358  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
2359  Serial1.write(val);
2360  #else
2361  _serial.write(val);
2362  #endif
2363  }
2364  inline bool isConnected(void) {
2365  #if PIN_BLUETOOTH_RX != PIN_BLUETOOTH_STATE
2366  return digitalRead(PIN_BLUETOOTH_STATE);
2367  #else
2368  return true;
2369  #endif
2370  }
2372  #endif
2373 
2374  #if EBOARD_SHIFT_REGISTER > 0x0
2375 
2378  long store_bits = 0L;
2387  inline void shiftSingle(optVAL_t idx, bool val);
2391  void shiftAll(void);
2393  inline void shiftSingle(optVAL_t idx, bool val) {
2394  bitWrite(store_bits,idx,val);
2395  shiftAll();
2396  }
2397 
2398  void shiftAll(void){
2399  digitalWrite(PIN_SHIFT_LAT,LOW);
2400  for(optVAL_t c = 0; (c<32 && !STOP); c++){
2401  digitalWrite(PIN_SHIFT_CLK,LOW);
2402  shiftOut(PIN_SHIFT_DAT,PIN_SHIFT_CLK,MSBFIRST,bitRead(store_bits,c));
2403  }
2404  digitalWrite(PIN_SHIFT_LAT,LOW);
2405  }
2407  #endif
2408 
2410  optVAL_t _pwmValue = 0x0, _OpwmValue = 0x0;
2411 
2419  inline void writePWM (optVAL_t val);
2421  inline void writePWM(optVAL_t val){
2422  val = min(val,0xFF); val = max(0x0,val);
2423  _pwmValue = val;
2424  }
2425 
2426  #ifdef REPT_TASK
2427  extern void rept_task(void);
2428  #endif
2429 
2430  ISR(TIMER1_COMPA_vect) {
2431  if (_pwmValue!=_OpwmValue){
2432  analogWrite(PIN_MOTOR_SPE,_pwmValue);
2434  }
2435  #ifdef REPT_TASK
2436  rept_task();
2437  #endif
2438  }
2439 
2441 
2450  inline void writePin(optVAL_t idx,bool val);
2452  inline void writePin(optVAL_t idx,bool val){
2453  #if EBOARD_SHIFT_REGISTER > 0x0
2454  if(idx>0x63) {
2455  idx -= 0x64;
2456  shiftSingle(idx,val);
2457  return;
2458  }
2459  #endif
2460  #if EBOARD_CHECK_PINS > 0x0
2461  checkIdx(idx);
2462  if(!checkPin(idx))
2463  #endif
2464  #if EBOARD_COPY_AND_PASTE > 0x0
2465  setPin(idx);
2466  #else
2467  pinMode(idx,OUTPUT);
2468  #endif
2469  digitalWrite(idx,val);
2470  }
2472 
2482  inline optVAL_t readPin(optVAL_t idx,bool dig = true);
2484  inline optVAL_t readPin(optVAL_t idx,bool dig){
2485  #if EBOARD_CHECK_PINS > 0x0
2486  if(dig) checkIdx(idx);
2487  #if defined (__AVR_ATmega2560__)
2488  else if (idx<0||idx>0xF){ //use I2C? change => Wire
2489  #else
2490  else if (idx<0||idx>0x7){ //use I2C? change => Wire
2491  #endif
2492  #if EBOARD_DEBUG_MODE > 0x0
2493  assert(false);
2494  #endif
2495  return 0;
2496  }
2497  if(dig && !checkPin(idx,INPUT))
2498  #endif
2499  #if EBOARD_COPY_AND_PASTE > 0x0
2500  setPin(idx,INPUT);
2501  #else
2502  pinMode(idx,INPUT);
2503  #endif
2504  return((dig)? digitalRead(idx) : analogRead(idx));
2505  }
2507 
2508  #if EBOARD_USE_SPI > 0x0 && (EBOARD_NANO == 0x0)
2509  namespace eagle_impl {
2536  struct ServoCds55 {
2544  #if defined(__AVR_ATmega2560__)
2545  ServoCds55(optVAL_t CS=53);
2546  #else
2547  ServoCds55(optVAL_t CS=10);
2548  #endif
2549  void begin();
2559  void WritePos(optVAL_t ID,optVAL_t Pos);
2566  inline void write(optVAL_t ID,optVAL_t Pos);
2572  void setVelocity(optVAL_t velocity);
2580  void setPosLimit(optVAL_t posLimit);
2584  void rotate(optVAL_t,optVAL_t);
2593  void SetServoLimit(optVAL_t ID,optVAL_t upperLimit);
2602  void SetMotormode(optVAL_t ID, optVAL_t velocity);
2611  void SetID(optVAL_t ID, optVAL_t newID);
2617  void Reset(optVAL_t ID);
2626  byte sendWait(const byte what);
2627 
2629  int upperLimit_temp;
2630 
2631  private:
2635  optVAL_t cs;
2636  // @brief prevents arduino from endless recallocating memory
2637  byte tmp;
2638  };
2639  }
2641  ServoCds55::ServoCds55 (optVAL_t CS):cs(CS) {
2642  this->velocity_temp = 0x96;
2643  this->upperLimit_temp = 0x12C; //keep default range of +-300
2644  }
2645 
2646  void ServoCds55::begin() {
2647  pinMode(this->cs,OUTPUT);
2648  digitalWrite(this->cs,HIGH);
2649  SPI.begin ();
2651  }
2652 
2653  byte ServoCds55::sendWait(const byte what) {
2654  this->tmp = SPI.transfer (what);
2655  delayMicroseconds (20);
2656  return this->tmp;
2657  }
2658 
2659  inline void ServoCds55::setVelocity(optVAL_t velocity){this->velocity_temp = velocity;}
2660  inline void ServoCds55::setPosLimit(optVAL_t posLimit){this->upperLimit_temp = posLimit;}
2661 
2662  inline void ServoCds55::write(optVAL_t ID,optVAL_t Pos){
2663  WritePos(ID,Pos);
2664  }
2665 
2666  void ServoCds55::rotate(optVAL_t ID,optVAL_t velocity){}
2667 
2668  void ServoCds55::WritePos(optVAL_t ID,optVAL_t Pos){
2669  digitalWrite(this->cs, LOW);
2670  sendWait('p'); sendWait(ID); sendWait((Pos>>0x8 & 0xff));
2671  sendWait((Pos & 0xff)); sendWait((this->velocity_temp>>0x8 & 0xff)); sendWait((this->velocity_temp & 0xff));
2672  sendWait('\t'); sendWait('\r'); sendWait('\n');
2673  digitalWrite(this->cs, HIGH);
2674  delay(8);
2675  }
2676 
2677  void ServoCds55::SetServoLimit(optVAL_t ID,optVAL_t upperLimit_tempT){
2678  digitalWrite(this->cs, LOW);
2679  sendWait('s'); sendWait(ID); sendWait((upperLimit_tempT>>0x8 & 0xff));
2680  sendWait((upperLimit_tempT & 0xff)); sendWait('\t'); sendWait('\r');
2681  sendWait('\n');
2682  digitalWrite(this->cs, HIGH);
2683  delay(8);
2684  }
2685 
2686  void ServoCds55::SetMotormode(optVAL_t ID, optVAL_t velocity){
2687  digitalWrite(this->cs, LOW);
2688  sendWait('m'); sendWait(ID); sendWait((velocity>>0x8 & 0xff));
2689  sendWait((velocity & 0xff)); sendWait('\t'); sendWait('\r');
2690  sendWait('\n');
2691  digitalWrite(this->cs, HIGH);
2692  delay(8);
2693  }
2694 
2695  void ServoCds55::SetID(optVAL_t ID, optVAL_t newID){
2696  digitalWrite(this->cs, LOW);
2697  sendWait('i'); sendWait(ID); sendWait(newID);
2698  sendWait('\t'); sendWait('\r'); sendWait('\n');
2699  digitalWrite(this->cs, HIGH);
2700  delay(8);
2701  }
2702 
2703  void ServoCds55::Reset(optVAL_t ID){
2704  digitalWrite(this->cs, LOW);
2705  sendWait('r'); sendWait(ID); sendWait('\t');
2706  sendWait('\r'); sendWait('\n');
2707  digitalWrite(this->cs, HIGH);
2708  delay(8);
2709  }
2711 
2714  #endif
2715 
2716  #if EBOARD_COPY_AND_PASTE > 0x0 && EBOARD_NANO == 0
2717 
2742  struct SoccerBoard {
2747  inline SoccerBoard(void);
2748  //inline ~SoccerBoard(void) {}
2749  #if EBOARD_USE_UTILITY > 0x0 or defined(__AVR_ATmega2560__) //won't shrink space... just speed things up
2750 
2758  inline void led(int idx,bool state);
2766  inline void ledOn(int idx);
2774  inline void ledOff(int idx);
2780  inline void ledsOff(void);
2786  inline void ledMeter(int);
2787 
2788  #endif
2789  #if EBOARD_USE_UTILITY > 0x0
2790  inline void /*bool*/ button(int);
2793  inline void waitForButton(int);
2794  #endif
2795 
2805  inline void motor(uint8_t id,int16_t val);
2807  inline void motorsOff(void);
2808  //ARDUINO UNO PINOUT
2809  //D0,D1 => Bluetooth connection
2810  //D4,D5 => MotorControl (D5: 980Hz)
2811  //D10,D13 => SPI
2812 
2822  inline void power(optVAL_t id, bool state);
2832  inline void powerOn(optVAL_t id);
2842  inline void powerOff(optVAL_t id);
2848  inline void sleep(uint16_t t);
2854  inline void msleep(uint16_t t);
2862  inline bool digital (optVAL_t id);
2870  inline optVAL_t analog (optVAL_t id);
2872  inline void reset(void); /* use crash-reset? =>*/ /* wdt_enable(WDTO_15MS); while(1) {} */
2873  };
2875  SoccerBoard::SoccerBoard(void) {}
2876 
2877  #if defined(__AVR_ATmega2560__)
2878  inline void SoccerBoard::led(int idx, bool state) {writePin(13,state);}
2879  void SoccerBoard::ledOn(int) {writePin(13,HIGH);}
2880  void SoccerBoard::ledOff(int) {writePin(13,LOW);}
2881  void SoccerBoard::ledsOff(void) {writePin(13,LOW);}
2882  void SoccerBoard::ledMeter(int) {writePin(13,HIGH);}
2883  #elif EBOARD_USE_UTILITY > 0x0
2884  void SoccerBoard::led(int, bool) {}
2885  void SoccerBoard::ledOn(int) {}
2886  void SoccerBoard::ledOff(int) {}
2887  void SoccerBoard::ledsOff(void) {}
2888  void SoccerBoard::ledMeter(int) {}
2889  #endif
2890 
2891  #if EBOARD_USE_UTILITY > 0x0
2892  void SoccerBoard::button(int) {}
2893  void SoccerBoard::waitForButton(int) {}
2894  #endif
2895 
2896  void SoccerBoard::motor(uint8_t id,int16_t val) {
2897  if(id==0&&(val>-256 && val < 256)) {setPin(PIN_MOTOR_DIR,val<0); writePWM(abs(val));}
2898  else if(id>0&&id<3&&(val>-0 && val < 1024)) {_servoHandler.write((id-1),(val *600/1023 - 300));}
2899  }
2900  void SoccerBoard::motorsOff(void) {writePWM(0);}
2901 
2902  void SoccerBoard::reset(void) {
2903  #if EBOARD_USE_RESET > 0x0
2904  wdt_enable(WDTO_15MS);
2905  while(true) {}
2906  #endif
2907  }
2908 
2909  void SoccerBoard::power(optVAL_t id, bool state) {writePin(id,state);}
2910  void SoccerBoard::powerOn(optVAL_t id) {this->power(id,1);}
2911  void SoccerBoard::powerOff(optVAL_t id) {this->power(id,0);}
2912  void SoccerBoard::sleep(uint16_t t) {delay(1000*t);}
2913  void SoccerBoard::msleep(uint16_t t) {delay(t);}
2914  bool SoccerBoard::digital (optVAL_t id) {return readPin(id);}
2915  optVAL_t SoccerBoard::analog (optVAL_t id) {return readPin(id,0);}
2916 
2917  //@endcond
2918  //To avoid not_found issues
2920  #define DIGITAL_IN 0x0
2921  #define DIGITAL_IN_INV 0x1
2923  #define DIGITAL_IN_PULLUP 0x2
2925  #define DIGITAL_IN_PULLUP_INV 0x3
2927  #define DIGITAL_OUT 0x4
2929  #define DIGITAL_OUT_INV 0x5
2931  #define DIGITAL_OUT_LOW 0x6
2933  #define DIGITAL_OUT_HIGH 0x7
2935  #define ANALOG_IN_8_BIT 0x8
2937  #define ANALOG_IN_10_BIT 0x9
2939  #define ANALOG_IN_MEAN_8_BIT 0xA
2941  #define ANALOG_IN_MEAN_10_BIT 0xB
2943  #define COUNTER_8_BIT 0xC
2945  #define COUNTER_16_BIT 0xD
2947  #define COUNTER_RISE_8_BIT 0xE
2949  #define COUNTER_RISE_16_BIT 0xF
2951  #define PWM_SLOW 0x8
2953  #define PWM_FAST 0x9
2955  #define FREQ_LOW 0xA
2957  #define FREQ_HIGH 0xB
2959  #define COUNTER_B_DIR 0xC
2961  #define COUNTER_B_DIR_PULLUP 0xD
2963  #define COUNTER_MEAN_8_BIT 0xE
2965  #define COUNTER_MEAN_16_BIT 0xF
2967 
2993  struct I2CInOut{
3000  #if EBOARD_USE_UTILITY > 0x0
3001  inline void read(void);
3004  inline void changeAddress(optVAL_t);
3006  inline void changeModes(optVAL_t,optVAL_t,optVAL_t);
3007  #endif
3008 
3012  inline void write(void);
3013 
3015  optVAL_t A; //if you've used uint16_t values you'll have to replace it here
3016  //we only have B - DiOut and C - AO [OUT]
3018  optVAL_t B;
3020  optVAL_t C;
3021  };
3024  this->A=0x0;this->B=0x0;this->C=0x0;
3025  }
3026  #if EBOARD_USE_UTILITY > 0x0
3027  void I2CInOut::read(void) {}
3030  #endif
3031  void I2CInOut::write(void){
3032  setPin(PIN_MOTOR_DIR,((this->B)!=0x0));
3033  writePWM(this->C);
3034  }
3036 
3038  struct DynamixelBoard;
3040 
3064  struct AX12Servo {
3069  AX12Servo(void);
3076  AX12Servo(DynamixelBoard &dBoard, optVAL_t servoID); //if borders => setPosLimit
3077 
3078  DynamixelBoard *_conBoard;
3079 
3080  #if EBOARD_USE_UTILITY > 0x0
3081 
3088  inline void setID(optVAL_t newID);
3097  inline void changeMotorID(optVAL_t newID); //this should change the hardwareaddress...
3103  inline void setPositionMode(void);
3109  inline void setSpeedMode(void);
3115  inline void setSpeed(optVAL_t);
3117  inline void ledOff(void);
3119  inline void ledOn(void);
3121  inline void setTorque(uint16_t);
3122  #endif
3123 
3131  void setPosition(int pos, int speed=0x3FF);
3139  inline void storePosition(int pos, int speed = 0x3FF);
3145  inline optVAL_t getPosition(void);
3153  inline bool isMoving(void);
3159  int storedPos;
3165  int storedSpe;
3166 
3167  //bool posMode; //we don't care wich mode we are in ^^
3168 
3170  optVAL_t id;
3171  private:
3173  int actPos;
3175  int actSpe;
3176 
3177  }; //shield //set limits auto register for begin
3178 
3180  AX12Servo::AX12Servo(void) {}
3181  #if EBOARD_USE_UTILITY > 0x0
3182  void AX12Servo::setID(optVAL_t newID) {this->id = newID;_servoHandler.SetServoLimit(this->id,_servoHandler.upperLimit_temp);}
3183  void AX12Servo::changeMotorID(optVAL_t newID) {this->id = newID;} //this should change the hardwareaddress...
3184  //IF needed: _servoHandler.setID(this->id, newID);
3185  void AX12Servo::setPositionMode(void) {}
3186  void AX12Servo::setSpeedMode(void) {}
3187  void AX12Servo::setSpeed(optVAL_t) {} //i won't use the rotate functions...
3188  void AX12Servo::ledOff(void) {} //noone needs the AX12-Servo LED
3189  void AX12Servo::ledOn(void) {} //really.... noone ^^
3190  void AX12Servo::setTorque(uint16_t) {} //which damn register? xD
3191  #endif
3192 
3193  void AX12Servo::setPosition(int pos, int speed) {
3194  #if EBOARD_CLAMP > 0x0
3195  if(pos>1023 || speed > 1023) return;
3196  this->actPos=pos; this->storedPos=pos; this->storedSpe = speed;
3197  speed = speed*600/1023 - 300;
3198  pos = pos *600/1023 - 300;
3199 
3200  #else
3201  if(pos>300 || speed > 300) return;
3202  this->actPos=pos; this->storedPos=pos; this->storedSpe = speed;
3203  #endif
3204  if(speed != actSpe){ _servoHandler.setVelocity(speed); this->actSpe=speed;}
3205  _servoHandler.write(this->id,pos);
3206  }
3208  return this->actPos; //when moving... false value;
3209  }
3210  bool AX12Servo::isMoving(void) {return false;} //we don't know^^
3212 
3236  struct DynamixelBoard {
3240  inline DynamixelBoard(SoccerBoard&);
3241  //inline ~DynamixelBoard(void) {}
3242  #if EBOARD_USE_UTILITY > 0x0
3243  inline void changeId(optVAL_t);
3246  inline void changeMotorID(optVAL_t);
3248  inline void ledOn(optVAL_t);
3250  inline void ledOff(optVAL_t);
3251  #endif
3252  inline void action(void);
3254 
3256  friend struct AX12Servo;
3257  protected:
3263  AX12Servo* connected[EBOARD_SPI_SERVO_MAX];
3264  };
3267  for(optVAL_t i = 0; i < EBOARD_SPI_SERVO_MAX; i++ ) {this->connected[i] = NULL;} //wanna use nullptr... wanna have c++11^^
3268  }
3269  //inline ~DynamixelBoard(void) {}
3270  #if EBOARD_USE_UTILITY > 0x0
3275  #endif
3276  void DynamixelBoard::action(void) {
3277  for(optVAL_t i = 0; (i < EBOARD_SPI_SERVO_MAX && !STOP); i++ ){
3278  if(this->connected[i] != NULL)
3279  (*connected[i]).setPosition((*connected[i]).storedPos,(*connected[i]).storedSpe);
3280  }
3281  }
3282 
3283 
3284  void AX12Servo::storePosition(int pos, int speed){
3285  if(this->id < EBOARD_SPI_SERVO_MAX) _conBoard->connected[this->id] = this;
3286  this->storedPos=pos;this->storedSpe=speed;
3287  }
3288  AX12Servo::AX12Servo(DynamixelBoard &dBoard, optVAL_t servoID): _conBoard( &dBoard),id(servoID-1), actSpe(0x96) {
3289  //#if EBOARD_DEBUG_MODE > 0x0
3290  // assert(servoID<EBOARD_SPI_SERVO_MAX);
3291  //#endif
3292  }
3294  #endif
3295  #if EBOARD_BLUETOOTH > 0x0
3296 
3327  struct RB14Scan {
3331  inline RB14Scan(void);
3334  inline int raw(optVAL_t);
3337  inline char channel(optVAL_t);
3343  inline void write(const char* const val);
3344  };
3345 
3347  inline RB14Scan::RB14Scan(void) {}
3348  inline int RB14Scan::raw(optVAL_t) {return isConnected();}
3349  inline char RB14Scan::channel(optVAL_t) {return ((isConnected())?(readVal()):(-1));}
3350  inline void RB14Scan::write(const char* const val) {writeVal(val);}
3352 
3360  #endif
3361 #if EBOARD_I2C > 0x0
3362 
3377  inline optVAL_t sendI2C(optVAL_t deviceID,byte *buf, byte buf_len);
3378 
3393  inline optVAL_t sendI2C(optVAL_t deviceID, byte buf);
3394 
3403  inline void pingI2C(optVAL_t ret[], optVAL_t ret_len);
3405  inline void pingI2C(optVAL_t ret[], optVAL_t ret_len){
3406  optVAL_t count = 0;
3407  for (byte i = 1; (i < 255 && !STOP); i++) /*ignore special*/ {
3408  if(i==200)continue; //internal
3409  Wire.beginTransmission (i);
3410  if (Wire.endTransmission () == 0) {
3411  if(count < ret_len) ret[count] = i;
3412  count++;
3413  delay (1);
3414  }
3415  }
3416  }
3417  inline optVAL_t sendI2C(optVAL_t deviceID,byte *buf, byte buf_len) {
3418  Wire.beginTransmission(deviceID);
3419  Wire.write(buf,buf_len);
3420  return Wire.endTransmission();
3421  }
3422 
3423  inline optVAL_t sendI2C(optVAL_t deviceID, byte buf){
3424  Wire.beginTransmission(deviceID);
3425  Wire.write(buf);
3426  return Wire.endTransmission();
3427  }
3429 
3440  inline void readI2C(optVAL_t deviceID, optVAL_t ret[], optVAL_t ret_len,bool blocking=true);
3442  inline void readI2C(optVAL_t deviceID,optVAL_t ret[] , optVAL_t ret_len,bool blocking) {
3443  for(optVAL_t rect = 0x0; (Wire.available() || (((blocking && (rect < ret_len))) && (!STOP))); rect++)
3444  ret[rect] = Wire.read();
3445  }
3447 
3448  //Beginof LCD configuration
3449  #if EBOARD_LCD > 0x0
3450 
3451  PROGMEM const byte basicFont[][8] = {
3452  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
3453  {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
3454  {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
3455  {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
3456  {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
3457  {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
3458  {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
3459  {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
3460  {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
3461  {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
3462  {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
3463  {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
3464  {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
3465  {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
3466  {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
3467  {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
3468  {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
3469  {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
3470  {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
3471  {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
3472  {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
3473  {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
3474  {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
3475  {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
3476  {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
3477  {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
3478  {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
3479  {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
3480  {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
3481  {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
3482  {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
3483  {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
3484  {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
3485  {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
3486  {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
3487  {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
3488  {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
3489  {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
3490  {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
3491  {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
3492  {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
3493  {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
3494  {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
3495  {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
3496  {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
3497  {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
3498  {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
3499  {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
3500  {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
3501  {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
3502  {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
3503  {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
3504  {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
3505  {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
3506  {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
3507  {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
3508  {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
3509  {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
3510  {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
3511  {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
3512  {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
3513  {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
3514  {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
3515  {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
3516  {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
3517  {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
3518  {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
3519  {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
3520  {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
3521  {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
3522  {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
3523  {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
3524  {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
3525  {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
3526  {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
3527  {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
3528  {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
3529  {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
3530  {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
3531  {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
3532  {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
3533  {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
3534  {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
3535  {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
3536  {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
3537  {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
3538  {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
3539  {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
3540  {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
3541  {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
3542  {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
3543  {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
3544  {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
3545  {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
3546  {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
3547  {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
3548  };
3549  /*
3550  * @note if you don't mind the space this is the extended font set!
3551  *
3552  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x00
3553  {0x7E,0x81,0x95,0xB1,0xB1,0x95,0x81,0x7E}, // 0x01
3554  {0x7E,0xFF,0xEB,0xCF,0xCF,0xEB,0xFF,0x7E}, // 0x02
3555  {0x0E,0x1F,0x3F,0x7E,0x3F,0x1F,0x0E,0x00}, // 0x03
3556  {0x08,0x1C,0x3E,0x7F,0x3E,0x1C,0x08,0x00}, // 0x04
3557  {0x38,0x3A,0x9F,0xFF,0x9F,0x3A,0x38,0x00}, // 0x05
3558  {0x10,0x38,0xBC,0xFF,0xBC,0x38,0x10,0x00}, // 0x06
3559  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x07
3560  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x08
3561  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x09
3562  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0A
3563  {0x70,0xF8,0x88,0x88,0xFD,0x7F,0x07,0x0F}, // 0x0B
3564  {0x00,0x4E,0x5F,0xF1,0xF1,0x5F,0x4E,0x00}, // 0x0C
3565  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0D
3566  {0xC0,0xFF,0x7F,0x05,0x05,0x65,0x7F,0x3F}, // 0x0E
3567  {0x99,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x99}, // 0x0F
3568  {0x7F,0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00}, // 0x10
3569  {0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x7F,0x00}, // 0x11
3570  {0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00}, // 0x12
3571  {0x00,0x5F,0x5F,0x00,0x00,0x5F,0x5F,0x00}, // 0x13
3572  {0x06,0x0F,0x09,0x7F,0x7F,0x01,0x7F,0x7F}, // 0x14
3573  {0xDA,0xBF,0xA5,0xA5,0xFD,0x59,0x03,0x02}, // 0x15
3574  {0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00}, // 0x16
3575  {0x80,0x94,0xB6,0xFF,0xFF,0xB6,0x94,0x80}, // 0x17
3576  {0x00,0x04,0x06,0x7F,0x7F,0x06,0x04,0x00}, // 0x18
3577  {0x00,0x10,0x30,0x7F,0x7F,0x30,0x10,0x00}, // 0x19
3578  {0x08,0x08,0x08,0x2A,0x3E,0x1C,0x08,0x00}, // 0x1A
3579  {0x08,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x00}, // 0x1B
3580  {0x3C,0x3C,0x20,0x20,0x20,0x20,0x20,0x00}, // 0x1C
3581  {0x08,0x1C,0x3E,0x08,0x08,0x3E,0x1C,0x08}, // 0x1D
3582  {0x30,0x38,0x3C,0x3E,0x3E,0x3C,0x38,0x30}, // 0x1E
3583  {0x06,0x0E,0x1E,0x3E,0x3E,0x1E,0x0E,0x06}, // 0x1F
3584  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x20
3585  {0x00,0x06,0x5F,0x5F,0x06,0x00,0x00,0x00}, // 0x21
3586  {0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00}, // 0x22
3587  {0x14,0x7F,0x7F,0x14,0x7F,0x7F,0x14,0x00}, // 0x23
3588  {0x24,0x2E,0x6B,0x6B,0x3A,0x12,0x00,0x00}, // 0x24
3589  {0x46,0x66,0x30,0x18,0x0C,0x66,0x62,0x00}, // 0x25
3590  {0x30,0x7A,0x4F,0x5D,0x37,0x7A,0x48,0x00}, // 0x26
3591  {0x04,0x07,0x03,0x00,0x00,0x00,0x00,0x00}, // 0x27
3592  {0x00,0x1C,0x3E,0x63,0x41,0x00,0x00,0x00}, // 0x28
3593  {0x00,0x41,0x63,0x3E,0x1C,0x00,0x00,0x00}, // 0x29
3594  {0x08,0x2A,0x3E,0x1C,0x1C,0x3E,0x2A,0x08}, // 0x2A
3595  {0x08,0x08,0x3E,0x3E,0x08,0x08,0x00,0x00}, // 0x2B
3596  {0x00,0xA0,0xE0,0x60,0x00,0x00,0x00,0x00}, // 0x2C
3597  {0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00}, // 0x2D
3598  {0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00}, // 0x2E
3599  {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // 0x2F
3600  {0x3E,0x7F,0x59,0x4D,0x7F,0x3E,0x00,0x00}, // 0x30
3601  {0x42,0x42,0x7F,0x7F,0x40,0x40,0x00,0x00}, // 0x31
3602  {0x62,0x73,0x59,0x49,0x6F,0x66,0x00,0x00}, // 0x32
3603  {0x22,0x63,0x49,0x49,0x7F,0x36,0x00,0x00}, // 0x33
3604  {0x18,0x1C,0x16,0x13,0x7F,0x7F,0x10,0x00}, // 0x34
3605  {0x27,0x67,0x45,0x45,0x7D,0x39,0x00,0x00}, // 0x35
3606  {0x3C,0x7E,0x4B,0x49,0x79,0x30,0x00,0x00}, // 0x36
3607  {0x03,0x63,0x71,0x19,0x0F,0x07,0x00,0x00}, // 0x37
3608  {0x36,0x7F,0x49,0x49,0x7F,0x36,0x00,0x00}, // 0x38
3609  {0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00,0x00}, // 0x39
3610  {0x00,0x00,0x6C,0x6C,0x00,0x00,0x00,0x00}, // 0x3A
3611  {0x00,0xA0,0xEC,0x6C,0x00,0x00,0x00,0x00}, // 0x3B
3612  {0x08,0x1C,0x36,0x63,0x41,0x00,0x00,0x00}, // 0x3C
3613  {0x14,0x14,0x14,0x14,0x14,0x14,0x00,0x00}, // 0x3D
3614  {0x00,0x41,0x63,0x36,0x1C,0x08,0x00,0x00}, // 0x3E
3615  {0x02,0x03,0x51,0x59,0x0F,0x06,0x00,0x00}, // 0x3F
3616  {0x3E,0x7F,0x41,0x5D,0x5D,0x1F,0x1E,0x00}, // 0x40
3617  {0x7C,0x7E,0x13,0x13,0x7E,0x7C,0x00,0x00}, // 0x41
3618  {0x41,0x7F,0x7F,0x49,0x49,0x7F,0x36,0x00}, // 0x42
3619  {0x1C,0x3E,0x63,0x41,0x41,0x63,0x22,0x00}, // 0x43
3620  {0x41,0x7F,0x7F,0x41,0x63,0x7F,0x1C,0x00}, // 0x44
3621  {0x41,0x7F,0x7F,0x49,0x5D,0x41,0x63,0x00}, // 0x45
3622  {0x41,0x7F,0x7F,0x49,0x1D,0x01,0x03,0x00}, // 0x46
3623  {0x1C,0x3E,0x63,0x41,0x51,0x73,0x72,0x00}, // 0x47
3624  {0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00,0x00}, // 0x48
3625  {0x00,0x41,0x7F,0x7F,0x41,0x00,0x00,0x00}, // 0x49
3626  {0x30,0x70,0x40,0x41,0x7F,0x3F,0x01,0x00}, // 0x4A
3627  {0x41,0x7F,0x7F,0x08,0x1C,0x77,0x63,0x00}, // 0x4B
3628  {0x41,0x7F,0x7F,0x41,0x40,0x60,0x70,0x00}, // 0x4C
3629  {0x7F,0x7F,0x06,0x0C,0x06,0x7F,0x7F,0x00}, // 0x4D
3630  {0x7F,0x7F,0x06,0x0C,0x18,0x7F,0x7F,0x00}, // 0x4E
3631  {0x1C,0x3E,0x63,0x41,0x63,0x3E,0x1C,0x00}, // 0x4F
3632  {0x41,0x7F,0x7F,0x49,0x09,0x0F,0x06,0x00}, // 0x50
3633  {0x1E,0x3F,0x21,0x71,0x7F,0x5E,0x00,0x00}, // 0x51
3634  {0x41,0x7F,0x7F,0x19,0x39,0x6F,0x46,0x00}, // 0x52
3635  {0x26,0x67,0x4D,0x59,0x7B,0x32,0x00,0x00}, // 0x53
3636  {0x03,0x41,0x7F,0x7F,0x41,0x03,0x00,0x00}, // 0x54
3637  {0x7F,0x7F,0x40,0x40,0x7F,0x7F,0x00,0x00}, // 0x55
3638  {0x1F,0x3F,0x60,0x60,0x3F,0x1F,0x00,0x00}, // 0x56
3639  {0x7F,0x7F,0x30,0x18,0x30,0x7F,0x7F,0x00}, // 0x57
3640  {0x63,0x77,0x1C,0x08,0x1C,0x77,0x63,0x00}, // 0x58
3641  {0x07,0x4F,0x78,0x78,0x4F,0x07,0x00,0x00}, // 0x59
3642  {0x67,0x73,0x59,0x4D,0x47,0x63,0x71,0x00}, // 0x5A
3643  {0x00,0x7F,0x7F,0x41,0x41,0x00,0x00,0x00}, // 0x5B
3644  {0x01,0x03,0x06,0x0C,0x18,0x30,0x60,0x00}, // 0x5C
3645  {0x00,0x41,0x41,0x7F,0x7F,0x00,0x00,0x00}, // 0x5D
3646  {0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00}, // 0x5E
3647  {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}, // 0x5F
3648  {0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00}, // 0x60
3649  {0x20,0x74,0x54,0x54,0x3C,0x78,0x40,0x00}, // 0x61
3650  {0x41,0x3F,0x7F,0x44,0x44,0x7C,0x38,0x00}, // 0x62
3651  {0x38,0x7C,0x44,0x44,0x6C,0x28,0x00,0x00}, // 0x63
3652  {0x30,0x78,0x48,0x49,0x3F,0x7F,0x40,0x00}, // 0x64
3653  {0x38,0x7C,0x54,0x54,0x5C,0x18,0x00,0x00}, // 0x65
3654  {0x48,0x7E,0x7F,0x49,0x03,0x02,0x00,0x00}, // 0x66
3655  {0x98,0xBC,0xA4,0xA4,0xF8,0x7C,0x04,0x00}, // 0x67
3656  {0x41,0x7F,0x7F,0x08,0x04,0x7C,0x78,0x00}, // 0x68
3657  {0x00,0x44,0x7D,0x7D,0x40,0x00,0x00,0x00}, // 0x69
3658  {0x40,0xC4,0x84,0xFD,0x7D,0x00,0x00,0x00}, // 0x6A
3659  {0x41,0x7F,0x7F,0x10,0x38,0x6C,0x44,0x00}, // 0x6B
3660  {0x00,0x41,0x7F,0x7F,0x40,0x00,0x00,0x00}, // 0x6C
3661  {0x7C,0x7C,0x0C,0x18,0x0C,0x7C,0x78,0x00}, // 0x6D
3662  {0x7C,0x7C,0x04,0x04,0x7C,0x78,0x00,0x00}, // 0x6E
3663  {0x38,0x7C,0x44,0x44,0x7C,0x38,0x00,0x00}, // 0x6F
3664  {0x84,0xFC,0xF8,0xA4,0x24,0x3C,0x18,0x00}, // 0x70
3665  {0x18,0x3C,0x24,0xA4,0xF8,0xFC,0x84,0x00}, // 0x71
3666  {0x44,0x7C,0x78,0x44,0x1C,0x18,0x00,0x00}, // 0x72
3667  {0x48,0x5C,0x54,0x54,0x74,0x24,0x00,0x00}, // 0x73
3668  {0x00,0x04,0x3E,0x7F,0x44,0x24,0x00,0x00}, // 0x74
3669  {0x3C,0x7C,0x40,0x40,0x3C,0x7C,0x40,0x00}, // 0x75
3670  {0x1C,0x3C,0x60,0x60,0x3C,0x1C,0x00,0x00}, // 0x76
3671  {0x3C,0x7C,0x60,0x30,0x60,0x7C,0x3C,0x00}, // 0x77
3672  {0x44,0x6C,0x38,0x10,0x38,0x6C,0x44,0x00}, // 0x78
3673  {0x9C,0xBC,0xA0,0xA0,0xFC,0x7C,0x00,0x00}, // 0x79
3674  {0x4C,0x64,0x74,0x5C,0x4C,0x64,0x00,0x00}, // 0x7A
3675  {0x08,0x08,0x3E,0x77,0x41,0x41,0x00,0x00}, // 0x7B
3676  {0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00}, // 0x7C
3677  {0x41,0x41,0x77,0x3E,0x08,0x08,0x00,0x00}, // 0x7D
3678  {0x02,0x03,0x01,0x03,0x02,0x03,0x01,0x00}, // 0x7E
3679  {0x78,0x7C,0x46,0x43,0x46,0x7C,0x78,0x00}, // 0x7F
3680  {0x1E,0xBF,0xE1,0x61,0x33,0x12,0x00,0x00}, // 0x80
3681  {0x3A,0x7A,0x40,0x40,0x7A,0x7A,0x40,0x00}, // 0x81
3682  {0x38,0x7C,0x56,0x57,0x5D,0x18,0x00,0x00}, // 0x82
3683  {0x02,0x23,0x75,0x55,0x55,0x7D,0x7B,0x42}, // 0x83
3684  {0x21,0x75,0x54,0x54,0x7D,0x79,0x40,0x00}, // 0x84
3685  {0x20,0x75,0x57,0x56,0x7C,0x78,0x40,0x00}, // 0x85
3686  {0x00,0x22,0x77,0x55,0x55,0x7F,0x7A,0x40}, // 0x86
3687  {0x1C,0xBE,0xE2,0x62,0x36,0x14,0x00,0x00}, // 0x87
3688  {0x02,0x3B,0x7D,0x55,0x55,0x5D,0x1B,0x02}, // 0x88
3689  {0x39,0x7D,0x54,0x54,0x5D,0x19,0x00,0x00}, // 0x89
3690  {0x38,0x7D,0x57,0x56,0x5C,0x18,0x00,0x00}, // 0x8A
3691  {0x01,0x45,0x7C,0x7C,0x41,0x01,0x00,0x00}, // 0x8B
3692  {0x02,0x03,0x45,0x7D,0x7D,0x43,0x02,0x00}, // 0x8C
3693  {0x00,0x45,0x7F,0x7E,0x40,0x00,0x00,0x00}, // 0x8D
3694  {0x79,0x7D,0x26,0x26,0x7D,0x79,0x00,0x00}, // 0x8E
3695  {0x70,0x7A,0x2D,0x2D,0x7A,0x70,0x00,0x00}, // 0x8F
3696  {0x44,0x7C,0x7E,0x57,0x55,0x44,0x00,0x00}, // 0x90
3697  {0x20,0x74,0x54,0x54,0x7C,0x7C,0x54,0x54}, // 0x91
3698  {0x7C,0x7E,0x0B,0x09,0x7F,0x7F,0x49,0x00}, // 0x92
3699  {0x32,0x7B,0x49,0x49,0x7B,0x32,0x00,0x00}, // 0x93
3700  {0x32,0x7A,0x48,0x48,0x7A,0x32,0x00,0x00}, // 0x94
3701  {0x30,0x79,0x4B,0x4A,0x78,0x30,0x00,0x00}, // 0x95
3702  {0x3A,0x7B,0x41,0x41,0x7B,0x7A,0x40,0x00}, // 0x96
3703  {0x38,0x79,0x43,0x42,0x78,0x78,0x40,0x00}, // 0x97
3704  {0xBA,0xBA,0xA0,0xA0,0xFA,0x7A,0x00,0x00}, // 0x98
3705  {0x39,0x7D,0x44,0x44,0x44,0x7D,0x39,0x00}, // 0x99
3706  {0x3D,0x7D,0x40,0x40,0x7D,0x3D,0x00,0x00}, // 0x9A
3707  {0x38,0x7C,0x64,0x54,0x4C,0x7C,0x38,0x00}, // 0x9B
3708  {0x68,0x7E,0x7F,0x49,0x43,0x66,0x20,0x00}, // 0x9C
3709  {0x5C,0x3E,0x73,0x49,0x67,0x3E,0x1D,0x00}, // 0x9D
3710  {0x44,0x6C,0x38,0x38,0x6C,0x44,0x00,0x00}, // 0x9E
3711  {0x40,0xC8,0x88,0xFE,0x7F,0x09,0x0B,0x02}, // 0x9F
3712  {0x20,0x74,0x56,0x57,0x7D,0x78,0x40,0x00}, // 0xA0
3713  {0x00,0x44,0x7E,0x7F,0x41,0x00,0x00,0x00}, // 0xA1
3714  {0x30,0x78,0x48,0x4A,0x7B,0x31,0x00,0x00}, // 0xA2
3715  {0x38,0x78,0x40,0x42,0x7B,0x79,0x40,0x00}, // 0xA3
3716  {0x7A,0x7B,0x09,0x0B,0x7A,0x73,0x01,0x00}, // 0xA4
3717  {0x7A,0x7B,0x19,0x33,0x7A,0x7B,0x01,0x00}, // 0xA5
3718  {0x00,0x26,0x2F,0x29,0x2F,0x2F,0x28,0x00}, // 0xA6
3719  {0x00,0x26,0x2F,0x29,0x29,0x2F,0x26,0x00}, // 0xA7
3720  {0x30,0x78,0x4D,0x45,0x60,0x20,0x00,0x00}, // 0xA8
3721  {0x1C,0x22,0x7D,0x4B,0x5B,0x65,0x22,0x1C}, // 0xA9
3722  {0x08,0x08,0x08,0x08,0x38,0x38,0x00,0x00}, // 0xAA
3723  {0x61,0x3F,0x1F,0xCC,0xEE,0xAB,0xB9,0x90}, // 0xAB
3724  {0x61,0x3F,0x1F,0x4C,0x66,0x73,0xD9,0xF8}, // 0xAC
3725  {0x00,0x00,0x60,0xFA,0xFA,0x60,0x00,0x00}, // 0xAD
3726  {0x08,0x1C,0x36,0x22,0x08,0x1C,0x36,0x22}, // 0xAE
3727  {0x22,0x36,0x1C,0x08,0x22,0x36,0x1C,0x08}, // 0xAF
3728  {0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00}, // 0xB0
3729  {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55}, // 0xB1
3730  {0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF}, // 0xB2
3731  {0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00}, // 0xB3
3732  {0x10,0x10,0x10,0xFF,0xFF,0x00,0x00,0x00}, // 0xB4
3733  {0x70,0x78,0x2C,0x2E,0x7B,0x71,0x00,0x00}, // 0xB5
3734  {0x72,0x79,0x2D,0x2D,0x79,0x72,0x00,0x00}, // 0xB6
3735  {0x71,0x7B,0x2E,0x2C,0x78,0x70,0x00,0x00}, // 0xB7
3736  {0x1C,0x22,0x5D,0x55,0x55,0x41,0x22,0x1C}, // 0xB8
3737  {0x14,0x14,0xF7,0xF7,0x00,0xFF,0xFF,0x00}, // 0xB9
3738  {0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00}, // 0xBA
3739  {0x14,0x14,0xF4,0xF4,0x04,0xFC,0xFC,0x00}, // 0xBB
3740  {0x14,0x14,0x17,0x17,0x10,0x1F,0x1F,0x00}, // 0xBC
3741  {0x18,0x3C,0x24,0xE7,0xE7,0x24,0x24,0x00}, // 0xBD
3742  {0x2B,0x2F,0xFC,0xFC,0x2F,0x2B,0x00,0x00}, // 0xBE
3743  {0x10,0x10,0x10,0xF0,0xF0,0x00,0x00,0x00}, // 0xBF
3744  {0x00,0x00,0x00,0x1F,0x1F,0x10,0x10,0x10}, // 0xC0
3745  {0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10}, // 0xC1
3746  {0x10,0x10,0x10,0xF0,0xF0,0x10,0x10,0x10}, // 0xC2
3747  {0x00,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10}, // 0xC3
3748  {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10}, // 0xC4
3749  {0x10,0x10,0x10,0xFF,0xFF,0x10,0x10,0x10}, // 0xC5
3750  {0x22,0x77,0x55,0x57,0x7E,0x7B,0x41,0x00}, // 0xC6
3751  {0x72,0x7B,0x2D,0x2F,0x7A,0x73,0x01,0x00}, // 0xC7
3752  {0x00,0x00,0x1F,0x1F,0x10,0x17,0x17,0x14}, // 0xC8
3753  {0x00,0x00,0xFC,0xFC,0x04,0xF4,0xF4,0x14}, // 0xC9
3754  {0x14,0x14,0x17,0x17,0x10,0x17,0x17,0x14}, // 0xCA
3755  {0x14,0x14,0xF4,0xF4,0x04,0xF4,0xF4,0x14}, // 0xCB
3756  {0x00,0x00,0xFF,0xFF,0x00,0xF7,0xF7,0x14}, // 0xCC
3757  {0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14}, // 0xCD
3758  {0x14,0x14,0xF7,0xF7,0x00,0xF7,0xF7,0x14}, // 0xCE
3759  {0x66,0x3C,0x3C,0x24,0x3C,0x3C,0x66,0x00}, // 0xCF
3760  {0x05,0x27,0x72,0x57,0x7D,0x38,0x00,0x00}, // 0xD0
3761  {0x49,0x7F,0x7F,0x49,0x63,0x7F,0x1C,0x00}, // 0xD1
3762  {0x46,0x7D,0x7D,0x55,0x55,0x46,0x00,0x00}, // 0xD2
3763  {0x45,0x7D,0x7C,0x54,0x55,0x45,0x00,0x00}, // 0xD3
3764  {0x44,0x7D,0x7F,0x56,0x54,0x44,0x00,0x00}, // 0xD4
3765  {0x0A,0x0E,0x08,0x00,0x00,0x00,0x00,0x00}, // 0xD5
3766  {0x00,0x44,0x7E,0x7F,0x45,0x00,0x00,0x00}, // 0xD6
3767  {0x02,0x45,0x7D,0x7D,0x45,0x02,0x00,0x00}, // 0xD7
3768  {0x01,0x45,0x7C,0x7C,0x45,0x01,0x00,0x00}, // 0xD8
3769  {0x10,0x10,0x10,0x1F,0x1F,0x00,0x00,0x00}, // 0xD9
3770  {0x00,0x00,0x00,0xF0,0xF0,0x10,0x10,0x10}, // 0xDA
3771  {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, // 0xDB
3772  {0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0}, // 0xDC
3773  {0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00}, // 0xDD
3774  {0x00,0x45,0x7F,0x7E,0x44,0x00,0x00,0x00}, // 0xDE
3775  {0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}, // 0xDF
3776  {0x38,0x7C,0x46,0x47,0x45,0x7C,0x38,0x00}, // 0xE0
3777  {0xFC,0xFE,0x2A,0x2A,0x3E,0x14,0x00,0x00}, // 0xE1
3778  {0x3A,0x7D,0x45,0x45,0x45,0x7D,0x3A,0x00}, // 0xE2
3779  {0x38,0x7C,0x45,0x47,0x46,0x7C,0x38,0x00}, // 0xE3
3780  {0x32,0x7B,0x49,0x4B,0x7A,0x33,0x01,0x00}, // 0xE4
3781  {0x3A,0x7F,0x45,0x47,0x46,0x7F,0x39,0x00}, // 0xE5
3782  {0x80,0xFE,0x7E,0x20,0x20,0x3E,0x1E,0x00}, // 0xE6
3783  {0x42,0x7E,0x7E,0x54,0x1C,0x08,0x00,0x00}, // 0xE7
3784  {0x41,0x7F,0x7F,0x55,0x14,0x1C,0x08,0x00}, // 0xE8
3785  {0x3C,0x7C,0x42,0x43,0x7D,0x3C,0x00,0x00}, // 0xE9
3786  {0x3A,0x79,0x41,0x41,0x79,0x3A,0x00,0x00}, // 0xEA
3787  {0x3C,0x7D,0x43,0x42,0x7C,0x3C,0x00,0x00}, // 0xEB
3788  {0xB8,0xB8,0xA2,0xA3,0xF9,0x78,0x00,0x00}, // 0xEC
3789  {0x0C,0x5C,0x72,0x73,0x5D,0x0C,0x00,0x00}, // 0xED
3790  {0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x00}, // 0xEE
3791  {0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x00}, // 0xEF
3792  {0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00}, // 0xF0
3793  {0x44,0x44,0x5F,0x5F,0x44,0x44,0x00,0x00}, // 0xF1
3794  {0x28,0x28,0x28,0x28,0x28,0x28,0x00,0x00}, // 0xF2
3795  {0x71,0x35,0x1F,0x4C,0x66,0x73,0xD9,0xF8}, // 0xF3
3796  {0x06,0x0F,0x09,0x7F,0x7F,0x01,0x7F,0x7F}, // 0xF4
3797  {0xDA,0xBF,0xA5,0xA5,0xFD,0x59,0x03,0x02}, // 0xF5
3798  {0x08,0x08,0x6B,0x6B,0x08,0x08,0x00,0x00}, // 0xF6
3799  {0x00,0x80,0xC0,0x40,0x00,0x00,0x00,0x00}, // 0xF7
3800  {0x00,0x06,0x0F,0x09,0x0F,0x06,0x00,0x00}, // 0xF8
3801  {0x02,0x02,0x00,0x00,0x02,0x02,0x00,0x00}, // 0xF9
3802  {0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00}, // 0xFA
3803  {0x00,0x12,0x13,0x1F,0x1F,0x10,0x10,0x00}, // 0xFB
3804  {0x00,0x11,0x15,0x15,0x1F,0x1F,0x0A,0x00}, // 0xFC
3805  {0x00,0x19,0x1D,0x15,0x17,0x12,0x00,0x00}, // 0xFD
3806  {0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00}, // 0xFE
3807  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0xFF
3808  */
3809 
3810  //Definition of OLED Constants
3812  #define LCD_COMMAND_MODE 0x80
3813  #define LCD_DATA_MODE 0x40
3815  #define LCD_COMMAND_DISPLAY_OFF 0xAE
3817  #define LCD_COMMAND_DISPLAY_ON 0xAF
3819  #define LCD_COMMAND_BLACK_BACKGROUND 0xA6
3821  #define LCD_COMMAND_WHITE_BACKGROUND 0xA7
3823  #define LCD_COMMAND_SET_BRIGHTNESS 0x81
3825  #define LCD_PAGE_ADDRESSING 0x02
3827  #define LCD_HORIZONTAL_ADDRESSING 0x00
3829  //The regulator
3831  #define LCD_COMMAND_CHARGE_PUMP_SETTING 0x8d
3832  #define LCD_COMMAND_CHARGE_PUMP_ENABLE 0x14
3834 
3835  #ifndef LCD_WIDTH
3836  #define LCD_WIDTH 128
3838  #endif
3839  #ifndef LCD_HEIGHT
3840  #define LCD_HEIGHT 64
3842  #endif
3843 
3886  struct LCD {
3887  #if EBOARD_NANO == 0
3888 
3896  LCD(SoccerBoard &soccerBoard, optVAL_t id=0x3C);
3897  #else
3898  LCD(optVAL_t id=0x3C);
3899  #endif
3900 
3914  inline bool changeID(optVAL_t newID = 0x3C);
3925  inline bool clear(void);
3931  inline void print(const char* data);
3937  inline void print(int data);
3945  inline void print(optVAL_t line, optVAL_t col, const char* data);
3953  inline void print(optVAL_t line, optVAL_t col, int data);
3962  inline void lightOn(void);
3971  inline void lightOff(void);
3982  inline bool reset(void);
3983 
3984  //added features
3997  inline bool init(void);
4007  inline void drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY);
4015  inline void changeMode(bool newMode = true);
4029  inline bool setCursor(byte posX = 0x0, byte posY = 0x0);
4042  inline bool changeBrightness (byte val = 0x64);
4052  inline void changeBackground(bool newBackground = false);
4054  optVAL_t ID;
4055  private:
4061  byte pX;
4064  byte pY;
4066  bool _cI;
4067 
4074  inline void s2Cmd(optVAL_t o, optVAL_t t);
4080  inline void s1Cmd(optVAL_t o);
4086  inline void s1Dat(optVAL_t o);
4087 
4088  };
4090  #if EBOARD_NANO == 0x0
4091  LCD::LCD(SoccerBoard &soccerBoard, optVAL_t id) {
4092  this->_cI = false;
4093  this->ID = id;
4094  //this->init();
4095  }
4096  #else
4097  LCD::LCD( optVAL_t id) {
4098  this->_cI = false;
4099  this->ID = id;
4100  //this->init();
4101  }
4102  #endif
4103  inline bool LCD::changeID(optVAL_t newID) {
4104  this->ID = newID;
4105  return this->init();
4106  }
4107  inline bool LCD::clear(void) {
4108  if(!this->_cI) this->init();
4109  for(byte i = 0; i < 8; i++){
4110  //maybe *8
4111  setCursor(0,i);
4112 
4113  for (byte j = 0; j < 128; j++) {
4114  this->s1Dat(0);
4115  }
4116  }
4117  return setCursor(0,0);
4118  }
4119  void LCD::print(optVAL_t line, optVAL_t col, const char *data) {
4120  if(!this->_cI) this->init();
4121  byte i = 0x0;
4122  if(col < ((LCD_WIDTH-1)/8.0) && line < ((LCD_HEIGHT-1)/8.0)) {
4123  setCursor(col,line);
4124  }
4125  while(data[i] && (pX*8) < LCD_WIDTH){
4126  //Serial.print(data[i]); Serial.print(" ");
4127  //Serial.print(i); Serial.print(" "); Serial.print(pX); Serial.print(" ");
4128  //Serial.println(this->pY);
4129  if(data[i] == '\n' || this->pX >= LCD_WIDTH) {
4130  setCursor(0,(pY+1));
4131  } else if (this->pY >= LCD_HEIGHT){
4132  setCursor(0,0);
4133  }
4134  if(data[i] < 32 || data[i] > 127){ i++; continue;}
4135  for (byte j = 0; j < 8; j++){
4136  this->s1Dat(pgm_read_byte(&basicFont[data[i]-32][j]));
4137  }
4138  i++;this->pX++;
4139  }
4140  }
4141  void LCD::print(optVAL_t line, optVAL_t col, int data){
4142  char buffer[11] = "";
4143  itoa(data,buffer,10);
4144  this->print(line,col,buffer);
4145  }
4146  inline void LCD::lightOn(void) {
4147  this->changeBrightness(255);
4148  }
4149  inline void LCD::lightOff(void) {
4150  this->changeBrightness(0);
4151  }
4152  inline bool LCD::reset(void) {
4153  return this->clear();
4154  }
4155  inline void LCD::print(int data) {this->print(255,255,data);}
4156  inline void LCD::print(const char* data) {this->print(255,255,data);}
4157  inline bool LCD::init() {
4158  #ifdef HIGHSPEED
4159  TWBR = 0xC;
4160  #endif
4161  this->_cI = true;
4163  this->changeMode(false);
4164  this->changeBackground(false);
4165  this->changeBrightness(255);
4166  this->s2Cmd(0x20,LCD_PAGE_ADDRESSING);
4167  this->changeMode(true);
4168 
4169  //this->print("eBoard \n written by \n EagleoutIce");
4170  return this->clear();
4171  }
4172 
4173  inline void LCD::drawBitmap(const unsigned char *bitmap, byte posX, byte posY, byte hiX, byte hiY){
4174  if(!this->_cI) this->init();
4175  setCursor(posX,posY);
4176  byte col = 0x0;
4177  for(int i = 0x0; i < (hiX * 8 * hiY); i++){
4178  this->s1Dat(pgm_read_byte(&bitmap[i]));
4179  if(++col == (hiX * 8)) {
4180  col = 0x0;
4181  setCursor(posX,++posY);
4182  }
4183  }
4184  }
4185  inline void LCD::changeMode(bool newMode) {
4186  if(!this->_cI) this->init();
4187  if(newMode) this->s1Cmd(LCD_COMMAND_DISPLAY_ON);
4188  else this->s1Cmd(LCD_COMMAND_DISPLAY_OFF);
4189  }
4190  inline bool LCD::setCursor(byte posX, byte posY) {
4191  if(!this->_cI) this->init();
4192  this->s2Cmd((0x00 + (8 *posX & 0x0F)),(0x10 + ((8 * posX >> 4) & 0x0F))); //lower and higher address
4193  Wire.beginTransmission(this->ID);
4194  Wire.write(LCD_COMMAND_MODE); Wire.write(0xB0 + posY); //page address
4195  this->pX = posX; this->pY = posY;
4196  return (Wire.endTransmission() == 0);
4197  }
4198 
4199  inline bool LCD::changeBrightness(byte val) {
4200  if(!this->_cI) this->init();
4201  this->s2Cmd(0x81,val); //brightness mode
4202  Wire.beginTransmission(this->ID);
4203  return (Wire.endTransmission() == 0);
4204  }
4205  inline void LCD::changeBackground(bool newBackground) {
4206  if(!this->_cI) this->init();
4207  if(newBackground) this->s1Cmd(LCD_COMMAND_WHITE_BACKGROUND);
4208  else this->s1Cmd(LCD_COMMAND_BLACK_BACKGROUND);
4209  }
4210 
4211  inline void LCD::s2Cmd(optVAL_t o, optVAL_t t){
4212  if(!this->_cI) this->init();
4213  this->s1Cmd(o); this->s1Cmd(t);
4214  }
4215 
4216  inline void LCD::s1Cmd(optVAL_t C) {
4217  if(!this->_cI) this->init();
4218  Wire.beginTransmission(this->ID);
4221  }
4222  inline void LCD::s1Dat(optVAL_t o){
4223  if(!this->_cI) this->init();
4224  Wire.beginTransmission(this->ID);
4227  }
4228 
4229  //@endcond
4230  #endif
4231 
4232  #if EBOARD_NEO > 0x0
4233  // Codesection based on official NeoPixel library
4234  // RGB NeoPixel permutations; white and red offsets are always same
4235  // Offset: W R G B
4237  #define EBOARD_NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2))
4238  #define EBOARD_NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1))
4240  #define EBOARD_NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2))
4242  #define EBOARD_NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1))
4244  #define EBOARD_NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0))
4246  #define EBOARD_NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0))
4248 
4249  // RGBW NeoPixel permutations; all 4 offsets are distinct
4250  // Offset: W R G B
4252  #define EBOARD_NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3))
4253  #define EBOARD_NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2))
4255  #define EBOARD_NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3))
4257  #define EBOARD_NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2))
4259  #define EBOARD_NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1))
4261  #define EBOARD_NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1))
4263  #define EBOARD_NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3))
4265  #define EBOARD_NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2))
4267  #define EBOARD_NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3))
4269  #define EBOARD_NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2))
4271  #define EBOARD_NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1))
4273  #define EBOARD_NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1))
4275  #define EBOARD_NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3))
4277  #define EBOARD_NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2))
4279  #define EBOARD_NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3))
4281  #define EBOARD_NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2))
4283  #define EBOARD_NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1))
4285  #define EBOARD_NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1))
4287  #define EBOARD_NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0))
4289  #define EBOARD_NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0))
4291  #define EBOARD_NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0))
4293  #define EBOARD_NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0))
4295  #define EBOARD_NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0))
4297  #define EBOARD_NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0))
4299 
4300 
4302  #define EBOARD_NEO_800KHZ 0x0000
4303  #define EBOARD_NEO_400KHZ 0x0100
4305 
4306  // uint16_t can be uint8_t in 800Khz mode ^^
4334  struct NeoPixel{
4342  NeoPixel(uint16_t n, uint8_t p = 6, uint16_t t = EBOARD_NEO_RGB + EBOARD_NEO_800KHZ);
4350  NeoPixel(void);
4352  ~NeoPixel(void);
4356  void begin(void);
4360  void show(void);
4365  void setPin(uint8_t p);
4373  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
4382  void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
4388  void setPixelColor(uint16_t n, uint32_t c);
4393  void setBrightness(uint8_t val);
4397  void clear(void);
4402  void updateLength(uint16_t n);
4407  void updateType(uint16_t t);
4412  inline uint8_t *getPixels(void) const;
4417  inline uint8_t getBrightness(void) const;
4423  uint8_t sine8(uint8_t x) const;
4429  uint8_t gamma8(uint8_t x) const;
4434  inline int8_t getPin(void);
4439  inline uint16_t numPixels(void) const;
4446  static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b);
4454  static inline uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w);
4459  uint32_t getPixelColor(uint16_t n) const;
4464  inline bool canShow(void);
4465  protected:
4467  bool is800kHz;
4469  bool begun;
4471  uint16_t numLEDs; //maybe shorten with PrepConst 'extendetLED'?
4473  uint16_t numBytes;
4478  int8_t pin;
4480  uint8_t brightness;
4482  uint8_t *pixels;
4484  uint8_t rOffset;
4486  uint8_t gOffset;
4488  uint8_t bOffset;
4490  uint8_t wOffset;
4492  uint32_t endTime; //used for diff calc
4493  #ifdef __AVR__ //not needed (rem?)
4494  volatile uint8_t *port;// Output PORT register
4497  uint8_t pinMask; // Output PORT bitmask
4498  #endif
4499 
4500  };
4501 
4503 
4504 
4505  NeoPixel::NeoPixel(uint16_t n, uint8_t p, uint16_t t) :
4506  begun(false), brightness(0), pixels(NULL), endTime(0) {
4507  updateType(t);
4508  updateLength(n);
4509  setPin(p);
4510  }
4511 
4512  inline bool NeoPixel::canShow(void) { return (micros() - endTime) >= 300L; }
4513 
4514  NeoPixel::NeoPixel() :
4515  is800KHz(true),
4516  begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0), pixels(NULL),
4517  rOffset(1), gOffset(0), bOffset(2), wOffset(1), endTime(0)
4518  {}
4519 
4521  if(pixels) free(pixels);
4522  if(pin >= 0) pinMode(pin, INPUT);
4523  }
4524 
4525  void NeoPixel::begin(void) {
4526  if(pin >= 0) {
4527  pinMode(pin, OUTPUT);
4528  digitalWrite(pin, LOW);
4529  }
4530  begun = true;
4531 
4532  }
4533 
4534  void NeoPixel::updateLength(uint16_t n) {
4535  if(pixels) free(pixels);
4536  numBytes = n * ((wOffset == rOffset) ? 3 : 4);
4537  if((pixels = (uint8_t *)malloc(numBytes))) {
4538  memset(pixels, 0, numBytes);
4539  numLEDs = n;
4540  } else {
4541  numLEDs = numBytes = 0;
4542  }
4543  }
4544 
4545  void NeoPixel::updateType(uint16_t t) {
4546  boolean oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
4547 
4548  wOffset = (t >> 6) & 0b11;
4549  rOffset = (t >> 4) & 0b11;
4550  gOffset = (t >> 2) & 0b11;
4551  bOffset = t & 0b11;
4552  is800KHz = (t < 256); // 400 KHz flag is 1<<8
4553 
4554  if(pixels) {
4555  boolean newThreeBytesPerPixel = (wOffset == rOffset);
4556  if(newThreeBytesPerPixel != oldThreeBytesPerPixel) updateLength(numLEDs);
4557  }
4558  }
4559 
4560  #if defined(ESP8266)
4561  // ESP8266 show() is external to enforce ICACHE_RAM_ATTR execution
4562  extern "C" void ICACHE_RAM_ATTR espShow(
4563  uint8_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
4564  #elif defined(ESP32)
4565  extern "C" void espShow(
4566  uint8_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
4567  #endif
4568 
4569  void NeoPixel::show(void) {
4570  if(!pixels) return;
4571  while(!canShow()); //maybe timeout ?
4572  noInterrupts(); // Need 100% focus on instruction timing
4573 
4574  #ifdef __AVR__
4575  volatile uint16_t
4576  i = numBytes;
4577  volatile uint8_t
4578  *ptr = pixels,
4579  b = *ptr++,
4580  hi,
4581  lo;
4582 
4583  #if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL)
4584 
4585  if(is800KHz) {
4586  volatile uint8_t n1, n2 = 0;
4587 
4588  #if defined(PORTD)
4589  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
4590  if(port == &PORTD) {
4591  #endif
4592 
4593  hi = PORTD | pinMask;
4594  lo = PORTD & ~pinMask;
4595  n1 = lo;
4596  if(b & 0x80) n1 = hi;
4597 
4598  asm volatile(
4599  "headD:" "\n\t" // Clk Pseudocode
4600  // Bit 7:
4601  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4602  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4603  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4604  "rjmp .+0" "\n\t" // 2 nop nop
4605  "sbrc %[byte] , 6" "\n\t" // 1-2 if(b & 0x40)
4606  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4607  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4608  "rjmp .+0" "\n\t" // 2 nop nop
4609  // Bit 6:
4610  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4611  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4612  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4613  "rjmp .+0" "\n\t" // 2 nop nop
4614  "sbrc %[byte] , 5" "\n\t" // 1-2 if(b & 0x20)
4615  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4616  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4617  "rjmp .+0" "\n\t" // 2 nop nop
4618  // Bit 5:
4619  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4620  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4621  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4622  "rjmp .+0" "\n\t" // 2 nop nop
4623  "sbrc %[byte] , 4" "\n\t" // 1-2 if(b & 0x10)
4624  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4625  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4626  "rjmp .+0" "\n\t" // 2 nop nop
4627  // Bit 4:
4628  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4629  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4630  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4631  "rjmp .+0" "\n\t" // 2 nop nop
4632  "sbrc %[byte] , 3" "\n\t" // 1-2 if(b & 0x08)
4633  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4634  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4635  "rjmp .+0" "\n\t" // 2 nop nop
4636  // Bit 3:
4637  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4638  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4639  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4640  "rjmp .+0" "\n\t" // 2 nop nop
4641  "sbrc %[byte] , 2" "\n\t" // 1-2 if(b & 0x04)
4642  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4643  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4644  "rjmp .+0" "\n\t" // 2 nop nop
4645  // Bit 2:
4646  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4647  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4648  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4649  "rjmp .+0" "\n\t" // 2 nop nop
4650  "sbrc %[byte] , 1" "\n\t" // 1-2 if(b & 0x02)
4651  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4652  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4653  "rjmp .+0" "\n\t" // 2 nop nop
4654  // Bit 1:
4655  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4656  "mov %[n2] , %[lo]" "\n\t" // 1 n2 = lo
4657  "out %[port] , %[n1]" "\n\t" // 1 PORT = n1
4658  "rjmp .+0" "\n\t" // 2 nop nop
4659  "sbrc %[byte] , 0" "\n\t" // 1-2 if(b & 0x01)
4660  "mov %[n2] , %[hi]" "\n\t" // 0-1 n2 = hi
4661  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4662  "sbiw %[count], 1" "\n\t" // 2 i-- (don't act on Z flag yet)
4663  // Bit 0:
4664  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi
4665  "mov %[n1] , %[lo]" "\n\t" // 1 n1 = lo
4666  "out %[port] , %[n2]" "\n\t" // 1 PORT = n2
4667  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++
4668  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 0x80)
4669  "mov %[n1] , %[hi]" "\n\t" // 0-1 n1 = hi
4670  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo
4671  "brne headD" "\n" // 2 while(i) (Z flag set above)
4672  : [byte] "+r" (b),
4673  [n1] "+r" (n1),
4674  [n2] "+r" (n2),
4675  [count] "+w" (i)
4676  : [port] "I" (_SFR_IO_ADDR(PORTD)),
4677  [ptr] "e" (ptr),
4678  [hi] "r" (hi),
4679  [lo] "r" (lo));
4680 
4681  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
4682  } else
4683  #endif
4684  #endif
4685  #if defined(PORTB)
4686  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
4687  if(port == &PORTB) {
4688  #endif // defined(PORTD/C/F)
4689  hi = PORTB | pinMask;
4690  lo = PORTB & ~pinMask;
4691  n1 = lo;
4692  if(b & 0x80) n1 = hi;
4693 
4694  asm volatile(
4695  "headB:" "\n\t"
4696  "out %[port] , %[hi]" "\n\t"
4697  "mov %[n2] , %[lo]" "\n\t"
4698  "out %[port] , %[n1]" "\n\t"
4699  "rjmp .+0" "\n\t"
4700  "sbrc %[byte] , 6" "\n\t"
4701  "mov %[n2] , %[hi]" "\n\t"
4702  "out %[port] , %[lo]" "\n\t"
4703  "rjmp .+0" "\n\t"
4704  "out %[port] , %[hi]" "\n\t"
4705  "mov %[n1] , %[lo]" "\n\t"
4706  "out %[port] , %[n2]" "\n\t"
4707  "rjmp .+0" "\n\t"
4708  "sbrc %[byte] , 5" "\n\t"
4709  "mov %[n1] , %[hi]" "\n\t"
4710  "out %[port] , %[lo]" "\n\t"
4711  "rjmp .+0" "\n\t"
4712  "out %[port] , %[hi]" "\n\t"
4713  "mov %[n2] , %[lo]" "\n\t"
4714  "out %[port] , %[n1]" "\n\t"
4715  "rjmp .+0" "\n\t"
4716  "sbrc %[byte] , 4" "\n\t"
4717  "mov %[n2] , %[hi]" "\n\t"
4718  "out %[port] , %[lo]" "\n\t"
4719  "rjmp .+0" "\n\t"
4720  "out %[port] , %[hi]" "\n\t"
4721  "mov %[n1] , %[lo]" "\n\t"
4722  "out %[port] , %[n2]" "\n\t"
4723  "rjmp .+0" "\n\t"
4724  "sbrc %[byte] , 3" "\n\t"
4725  "mov %[n1] , %[hi]" "\n\t"
4726  "out %[port] , %[lo]" "\n\t"
4727  "rjmp .+0" "\n\t"
4728  "out %[port] , %[hi]" "\n\t"
4729  "mov %[n2] , %[lo]" "\n\t"
4730  "out %[port] , %[n1]" "\n\t"
4731  "rjmp .+0" "\n\t"
4732  "sbrc %[byte] , 2" "\n\t"
4733  "mov %[n2] , %[hi]" "\n\t"
4734  "out %[port] , %[lo]" "\n\t"
4735  "rjmp .+0" "\n\t"
4736  "out %[port] , %[hi]" "\n\t"
4737  "mov %[n1] , %[lo]" "\n\t"
4738  "out %[port] , %[n2]" "\n\t"
4739  "rjmp .+0" "\n\t"
4740  "sbrc %[byte] , 1" "\n\t"
4741  "mov %[n1] , %[hi]" "\n\t"
4742  "out %[port] , %[lo]" "\n\t"
4743  "rjmp .+0" "\n\t"
4744  "out %[port] , %[hi]" "\n\t"
4745  "mov %[n2] , %[lo]" "\n\t"
4746  "out %[port] , %[n1]" "\n\t"
4747  "rjmp .+0" "\n\t"
4748  "sbrc %[byte] , 0" "\n\t"
4749  "mov %[n2] , %[hi]" "\n\t"
4750  "out %[port] , %[lo]" "\n\t"
4751  "sbiw %[count], 1" "\n\t"
4752  "out %[port] , %[hi]" "\n\t"
4753  "mov %[n1] , %[lo]" "\n\t"
4754  "out %[port] , %[n2]" "\n\t"
4755  "ld %[byte] , %a[ptr]+" "\n\t"
4756  "sbrc %[byte] , 7" "\n\t"
4757  "mov %[n1] , %[hi]" "\n\t"
4758  "out %[port] , %[lo]" "\n\t"
4759  "brne headB" "\n"
4760  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
4761  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
4762  [lo] "r" (lo));
4763 
4764  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
4765  }
4766  #endif
4767  #if defined(PORTC) || defined(PORTF)
4768  else
4769  #endif
4770  #endif
4771 
4772  #if defined(PORTC)
4773  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
4774  if(port == &PORTC) {
4775  #endif
4776 
4777  hi = PORTC | pinMask;
4778  lo = PORTC & ~pinMask;
4779  n1 = lo;
4780  if(b & 0x80) n1 = hi;
4781 
4782  asm volatile(
4783  "headC:" "\n\t"
4784  "out %[port] , %[hi]" "\n\t"
4785  "mov %[n2] , %[lo]" "\n\t"
4786  "out %[port] , %[n1]" "\n\t"
4787  "rjmp .+0" "\n\t"
4788  "sbrc %[byte] , 6" "\n\t"
4789  "mov %[n2] , %[hi]" "\n\t"
4790  "out %[port] , %[lo]" "\n\t"
4791  "rjmp .+0" "\n\t"
4792  "out %[port] , %[hi]" "\n\t"
4793  "mov %[n1] , %[lo]" "\n\t"
4794  "out %[port] , %[n2]" "\n\t"
4795  "rjmp .+0" "\n\t"
4796  "sbrc %[byte] , 5" "\n\t"
4797  "mov %[n1] , %[hi]" "\n\t"
4798  "out %[port] , %[lo]" "\n\t"
4799  "rjmp .+0" "\n\t"
4800  "out %[port] , %[hi]" "\n\t"
4801  "mov %[n2] , %[lo]" "\n\t"
4802  "out %[port] , %[n1]" "\n\t"
4803  "rjmp .+0" "\n\t"
4804  "sbrc %[byte] , 4" "\n\t"
4805  "mov %[n2] , %[hi]" "\n\t"
4806  "out %[port] , %[lo]" "\n\t"
4807  "rjmp .+0" "\n\t"
4808  "out %[port] , %[hi]" "\n\t"
4809  "mov %[n1] , %[lo]" "\n\t"
4810  "out %[port] , %[n2]" "\n\t"
4811  "rjmp .+0" "\n\t"
4812  "sbrc %[byte] , 3" "\n\t"
4813  "mov %[n1] , %[hi]" "\n\t"
4814  "out %[port] , %[lo]" "\n\t"
4815  "rjmp .+0" "\n\t"
4816  "out %[port] , %[hi]" "\n\t"
4817  "mov %[n2] , %[lo]" "\n\t"
4818  "out %[port] , %[n1]" "\n\t"
4819  "rjmp .+0" "\n\t"
4820  "sbrc %[byte] , 2" "\n\t"
4821  "mov %[n2] , %[hi]" "\n\t"
4822  "out %[port] , %[lo]" "\n\t"
4823  "rjmp .+0" "\n\t"
4824  "out %[port] , %[hi]" "\n\t"
4825  "mov %[n1] , %[lo]" "\n\t"
4826  "out %[port] , %[n2]" "\n\t"
4827  "rjmp .+0" "\n\t"
4828  "sbrc %[byte] , 1" "\n\t"
4829  "mov %[n1] , %[hi]" "\n\t"
4830  "out %[port] , %[lo]" "\n\t"
4831  "rjmp .+0" "\n\t"
4832  "out %[port] , %[hi]" "\n\t"
4833  "mov %[n2] , %[lo]" "\n\t"
4834  "out %[port] , %[n1]" "\n\t"
4835  "rjmp .+0" "\n\t"
4836  "sbrc %[byte] , 0" "\n\t"
4837  "mov %[n2] , %[hi]" "\n\t"
4838  "out %[port] , %[lo]" "\n\t"
4839  "sbiw %[count], 1" "\n\t"
4840  "out %[port] , %[hi]" "\n\t"
4841  "mov %[n1] , %[lo]" "\n\t"
4842  "out %[port] , %[n2]" "\n\t"
4843  "ld %[byte] , %a[ptr]+" "\n\t"
4844  "sbrc %[byte] , 7" "\n\t"
4845  "mov %[n1] , %[hi]" "\n\t"
4846  "out %[port] , %[lo]" "\n\t"
4847  "brne headC" "\n"
4848  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
4849  : [port] "I" (_SFR_IO_ADDR(PORTC)), [ptr] "e" (ptr), [hi] "r" (hi),
4850  [lo] "r" (lo));
4851 
4852  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
4853  }
4854  #endif
4855  #if defined(PORTF)
4856  else
4857  #endif
4858  #endif
4859 
4860  #if defined(PORTF)
4861  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
4862  if(port == &PORTF) {
4863  #endif // defined(PORTD/B/C)
4864 
4865  hi = PORTF | pinMask;
4866  lo = PORTF & ~pinMask;
4867  n1 = lo;
4868  if(b & 0x80) n1 = hi;
4869 
4870  asm volatile(
4871  "headF:" "\n\t"
4872  "out %[port] , %[hi]" "\n\t"
4873  "mov %[n2] , %[lo]" "\n\t"
4874  "out %[port] , %[n1]" "\n\t"
4875  "rjmp .+0" "\n\t"
4876  "sbrc %[byte] , 6" "\n\t"
4877  "mov %[n2] , %[hi]" "\n\t"
4878  "out %[port] , %[lo]" "\n\t"
4879  "rjmp .+0" "\n\t"
4880  "out %[port] , %[hi]" "\n\t"
4881  "mov %[n1] , %[lo]" "\n\t"
4882  "out %[port] , %[n2]" "\n\t"
4883  "rjmp .+0" "\n\t"
4884  "sbrc %[byte] , 5" "\n\t"
4885  "mov %[n1] , %[hi]" "\n\t"
4886  "out %[port] , %[lo]" "\n\t"
4887  "rjmp .+0" "\n\t"
4888  "out %[port] , %[hi]" "\n\t"
4889  "mov %[n2] , %[lo]" "\n\t"
4890  "out %[port] , %[n1]" "\n\t"
4891  "rjmp .+0" "\n\t"
4892  "sbrc %[byte] , 4" "\n\t"
4893  "mov %[n2] , %[hi]" "\n\t"
4894  "out %[port] , %[lo]" "\n\t"
4895  "rjmp .+0" "\n\t"
4896  "out %[port] , %[hi]" "\n\t"
4897  "mov %[n1] , %[lo]" "\n\t"
4898  "out %[port] , %[n2]" "\n\t"
4899  "rjmp .+0" "\n\t"
4900  "sbrc %[byte] , 3" "\n\t"
4901  "mov %[n1] , %[hi]" "\n\t"
4902  "out %[port] , %[lo]" "\n\t"
4903  "rjmp .+0" "\n\t"
4904  "out %[port] , %[hi]" "\n\t"
4905  "mov %[n2] , %[lo]" "\n\t"
4906  "out %[port] , %[n1]" "\n\t"
4907  "rjmp .+0" "\n\t"
4908  "sbrc %[byte] , 2" "\n\t"
4909  "mov %[n2] , %[hi]" "\n\t"
4910  "out %[port] , %[lo]" "\n\t"
4911  "rjmp .+0" "\n\t"
4912  "out %[port] , %[hi]" "\n\t"
4913  "mov %[n1] , %[lo]" "\n\t"
4914  "out %[port] , %[n2]" "\n\t"
4915  "rjmp .+0" "\n\t"
4916  "sbrc %[byte] , 1" "\n\t"
4917  "mov %[n1] , %[hi]" "\n\t"
4918  "out %[port] , %[lo]" "\n\t"
4919  "rjmp .+0" "\n\t"
4920  "out %[port] , %[hi]" "\n\t"
4921  "mov %[n2] , %[lo]" "\n\t"
4922  "out %[port] , %[n1]" "\n\t"
4923  "rjmp .+0" "\n\t"
4924  "sbrc %[byte] , 0" "\n\t"
4925  "mov %[n2] , %[hi]" "\n\t"
4926  "out %[port] , %[lo]" "\n\t"
4927  "sbiw %[count], 1" "\n\t"
4928  "out %[port] , %[hi]" "\n\t"
4929  "mov %[n1] , %[lo]" "\n\t"
4930  "out %[port] , %[n2]" "\n\t"
4931  "ld %[byte] , %a[ptr]+" "\n\t"
4932  "sbrc %[byte] , 7" "\n\t"
4933  "mov %[n1] , %[hi]" "\n\t"
4934  "out %[port] , %[lo]" "\n\t"
4935  "brne headF" "\n"
4936  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
4937  : [port] "I" (_SFR_IO_ADDR(PORTF)), [ptr] "e" (ptr), [hi] "r" (hi),
4938  [lo] "r" (lo));
4939 
4940  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
4941  }
4942  #endif // defined(PORTD/B/C)
4943  #endif // defined(PORTF)
4944  } else {
4945 
4946  volatile uint8_t next, bit;
4947 
4948  hi = *port | pinMask;
4949  lo = *port & ~pinMask;
4950  next = lo;
4951  bit = 8;
4952 
4953  asm volatile(
4954  "head20:" "\n\t" // Clk Pseudocode (T = 0)
4955  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
4956  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
4957  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
4958  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 6)
4959  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
4960  "dec %[bit]" "\n\t" // 1 bit-- (T = 8)
4961  "breq nextbyte20" "\n\t" // 1-2 if(bit == 0)
4962  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
4963  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
4964  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
4965  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
4966  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
4967  "rjmp head20" "\n\t" // 2 -> head20 (next bit out)
4968  "nextbyte20:" "\n\t" // (T = 10)
4969  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
4970  "nop" "\n\t" // 1 nop (T = 13)
4971  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 14)
4972  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 16)
4973  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
4974  "brne head20" "\n" // 2 if(i != 0) -> (next byte)
4975  : [port] "+e" (port),
4976  [byte] "+r" (b),
4977  [bit] "+r" (bit),
4978  [next] "+r" (next),
4979  [count] "+w" (i)
4980  : [hi] "r" (hi),
4981  [lo] "r" (lo),
4982  [ptr] "e" (ptr));
4983  }
4984  #elif (F_CPU >= 11100000UL) && (F_CPU <= 14300000UL)
4985  if(is800KHz) {
4986  volatile uint8_t next;
4987 
4988  // PORTD OUTPUT ----------------------------------------------------
4989 
4990  #if defined(PORTD)
4991  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
4992  if(port == &PORTD) {
4993  #endif
4994 
4995  hi = PORTD | pinMask;
4996  lo = PORTD & ~pinMask;
4997  next = lo;
4998  if(b & 0x80) next = hi;
4999  asm volatile(
5000  "headD:" "\n\t" // (T = 0)
5001  "out %[port], %[hi]" "\n\t" // (T = 1)
5002  "rcall bitTimeD" "\n\t" // Bit 7 (T = 15)
5003  "out %[port], %[hi]" "\n\t"
5004  "rcall bitTimeD" "\n\t" // Bit 6
5005  "out %[port], %[hi]" "\n\t"
5006  "rcall bitTimeD" "\n\t" // Bit 5
5007  "out %[port], %[hi]" "\n\t"
5008  "rcall bitTimeD" "\n\t" // Bit 4
5009  "out %[port], %[hi]" "\n\t"
5010  "rcall bitTimeD" "\n\t" // Bit 3
5011  "out %[port], %[hi]" "\n\t"
5012  "rcall bitTimeD" "\n\t" // Bit 2
5013  "out %[port], %[hi]" "\n\t"
5014  "rcall bitTimeD" "\n\t" // Bit 1
5015  // Bit 0:
5016  "out %[port] , %[hi]" "\n\t" // 1 PORT = hi (T = 1)
5017  "rjmp .+0" "\n\t" // 2 nop nop (T = 3)
5018  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 5)
5019  "out %[port] , %[next]" "\n\t" // 1 PORT = next (T = 6)
5020  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
5021  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 0x80) (T = 8)
5022  "mov %[next] , %[hi]" "\n\t" // 0-1 next = hi (T = 9)
5023  "nop" "\n\t" // 1 (T = 10)
5024  "out %[port] , %[lo]" "\n\t" // 1 PORT = lo (T = 11)
5025  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 13)
5026  "brne headD" "\n\t" // 2 if(i != 0) -> (next byte)
5027  "rjmp doneD" "\n\t"
5028  "bitTimeD:" "\n\t" // nop nop nop (T = 4)
5029  "out %[port], %[next]" "\n\t" // 1 PORT = next (T = 5)
5030  "mov %[next], %[lo]" "\n\t" // 1 next = lo (T = 6)
5031  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 7)
5032  "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 0x80) (T = 8)
5033  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 9)
5034  "nop" "\n\t" // 1 (T = 10)
5035  "out %[port], %[lo]" "\n\t" // 1 PORT = lo (T = 11)
5036  "ret" "\n\t" // 4 nop nop nop nop (T = 15)
5037  "doneD:" "\n"
5038  : [byte] "+r" (b),
5039  [next] "+r" (next),
5040  [count] "+w" (i)
5041  : [port] "I" (_SFR_IO_ADDR(PORTD)),
5042  [ptr] "e" (ptr),
5043  [hi] "r" (hi),
5044  [lo] "r" (lo));
5045 
5046  #if defined(PORTB) || defined(PORTC) || defined(PORTF)
5047  } else
5048  #endif
5049  #endif
5050 
5051  #if defined(PORTB)
5052  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
5053  if(port == &PORTB) {
5054  #endif
5055 
5056  hi = PORTB | pinMask;
5057  lo = PORTB & ~pinMask;
5058  next = lo;
5059  if(b & 0x80) next = hi;
5060 
5061  asm volatile(
5062  "headB:" "\n\t"
5063  "out %[port], %[hi]" "\n\t"
5064  "rcall bitTimeB" "\n\t"
5065  "out %[port], %[hi]" "\n\t"
5066  "rcall bitTimeB" "\n\t"
5067  "out %[port], %[hi]" "\n\t"
5068  "rcall bitTimeB" "\n\t"
5069  "out %[port], %[hi]" "\n\t"
5070  "rcall bitTimeB" "\n\t"
5071  "out %[port], %[hi]" "\n\t"
5072  "rcall bitTimeB" "\n\t"
5073  "out %[port], %[hi]" "\n\t"
5074  "rcall bitTimeB" "\n\t"
5075  "out %[port], %[hi]" "\n\t"
5076  "rcall bitTimeB" "\n\t"
5077  "out %[port] , %[hi]" "\n\t"
5078  "rjmp .+0" "\n\t"
5079  "ld %[byte] , %a[ptr]+" "\n\t"
5080  "out %[port] , %[next]" "\n\t"
5081  "mov %[next] , %[lo]" "\n\t"
5082  "sbrc %[byte] , 7" "\n\t"
5083  "mov %[next] , %[hi]" "\n\t"
5084  "nop" "\n\t"
5085  "out %[port] , %[lo]" "\n\t"
5086  "sbiw %[count], 1" "\n\t"
5087  "brne headB" "\n\t"
5088  "rjmp doneB" "\n\t"
5089  "bitTimeB:" "\n\t"
5090  "out %[port], %[next]" "\n\t"
5091  "mov %[next], %[lo]" "\n\t"
5092  "rol %[byte]" "\n\t"
5093  "sbrc %[byte], 7" "\n\t"
5094  "mov %[next], %[hi]" "\n\t"
5095  "nop" "\n\t"
5096  "out %[port], %[lo]" "\n\t"
5097  "ret" "\n\t"
5098  "doneB:" "\n"
5099  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
5100  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
5101  [lo] "r" (lo));
5102 
5103  #if defined(PORTD) || defined(PORTC) || defined(PORTF)
5104  }
5105  #endif
5106  #if defined(PORTC) || defined(PORTF)
5107  else
5108  #endif
5109  #endif
5110 
5111  #if defined(PORTC)
5112  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
5113  if(port == &PORTC) {
5114  #endif
5115 
5116  hi = PORTC | pinMask;
5117  lo = PORTC & ~pinMask;
5118  next = lo;
5119  if(b & 0x80) next = hi;
5120 
5121  asm volatile(
5122  "headC:" "\n\t"
5123  "out %[port], %[hi]" "\n\t"
5124  "rcall bitTimeC" "\n\t"
5125  "out %[port], %[hi]" "\n\t"
5126  "rcall bitTimeC" "\n\t"
5127  "out %[port], %[hi]" "\n\t"
5128  "rcall bitTimeC" "\n\t"
5129  "out %[port], %[hi]" "\n\t"
5130  "rcall bitTimeC" "\n\t"
5131  "out %[port], %[hi]" "\n\t"
5132  "rcall bitTimeC" "\n\t"
5133  "out %[port], %[hi]" "\n\t"
5134  "rcall bitTimeC" "\n\t"
5135  "out %[port], %[hi]" "\n\t"
5136  "rcall bitTimeC" "\n\t"
5137  "out %[port] , %[hi]" "\n\t"
5138  "rjmp .+0" "\n\t"
5139  "ld %[byte] , %a[ptr]+" "\n\t"
5140  "out %[port] , %[next]" "\n\t"
5141  "mov %[next] , %[lo]" "\n\t"
5142  "sbrc %[byte] , 7" "\n\t"
5143  "mov %[next] , %[hi]" "\n\t"
5144  "nop" "\n\t"
5145  "out %[port] , %[lo]" "\n\t"
5146  "sbiw %[count], 1" "\n\t"
5147  "brne headC" "\n\t"
5148  "rjmp doneC" "\n\t"
5149  "bitTimeC:" "\n\t"
5150  "out %[port], %[next]" "\n\t"
5151  "mov %[next], %[lo]" "\n\t"
5152  "rol %[byte]" "\n\t"
5153  "sbrc %[byte], 7" "\n\t"
5154  "mov %[next], %[hi]" "\n\t"
5155  "nop" "\n\t"
5156  "out %[port], %[lo]" "\n\t"
5157  "ret" "\n\t"
5158  "doneC:" "\n"
5159  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
5160  : [port] "I" (_SFR_IO_ADDR(PORTC)), [ptr] "e" (ptr), [hi] "r" (hi),
5161  [lo] "r" (lo));
5162 
5163  #if defined(PORTD) || defined(PORTB) || defined(PORTF)
5164  }
5165  #endif
5166  #if defined(PORTF)
5167  else
5168  #endif
5169  #endif
5170 
5171  #if defined(PORTF)
5172  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
5173  if(port == &PORTF) {
5174  #endif
5175 
5176  hi = PORTF | pinMask;
5177  lo = PORTF & ~pinMask;
5178  next = lo;
5179  if(b & 0x80) next = hi;
5180 
5181  asm volatile(
5182  "headF:" "\n\t"
5183  "out %[port], %[hi]" "\n\t"
5184  "rcall bitTimeC" "\n\t"
5185  "out %[port], %[hi]" "\n\t"
5186  "rcall bitTimeC" "\n\t"
5187  "out %[port], %[hi]" "\n\t"
5188  "rcall bitTimeC" "\n\t"
5189  "out %[port], %[hi]" "\n\t"
5190  "rcall bitTimeC" "\n\t"
5191  "out %[port], %[hi]" "\n\t"
5192  "rcall bitTimeC" "\n\t"
5193  "out %[port], %[hi]" "\n\t"
5194  "rcall bitTimeC" "\n\t"
5195  "out %[port], %[hi]" "\n\t"
5196  "rcall bitTimeC" "\n\t"
5197  "out %[port] , %[hi]" "\n\t"
5198  "rjmp .+0" "\n\t"
5199  "ld %[byte] , %a[ptr]+" "\n\t"
5200  "out %[port] , %[next]" "\n\t"
5201  "mov %[next] , %[lo]" "\n\t"
5202  "sbrc %[byte] , 7" "\n\t"
5203  "mov %[next] , %[hi]" "\n\t"
5204  "nop" "\n\t"
5205  "out %[port] , %[lo]" "\n\t"
5206  "sbiw %[count], 1" "\n\t"
5207  "brne headF" "\n\t"
5208  "rjmp doneC" "\n\t"
5209  "bitTimeC:" "\n\t"
5210  "out %[port], %[next]" "\n\t"
5211  "mov %[next], %[lo]" "\n\t"
5212  "rol %[byte]" "\n\t"
5213  "sbrc %[byte], 7" "\n\t"
5214  "mov %[next], %[hi]" "\n\t"
5215  "nop" "\n\t"
5216  "out %[port], %[lo]" "\n\t"
5217  "ret" "\n\t"
5218  "doneC:" "\n"
5219  : [byte] "+r" (b), [next] "+r" (next), [count] "+w" (i)
5220  : [port] "I" (_SFR_IO_ADDR(PORTF)), [ptr] "e" (ptr), [hi] "r" (hi),
5221  [lo] "r" (lo));
5222 
5223  #if defined(PORTD) || defined(PORTB) || defined(PORTC)
5224  }
5225  #endif
5226  #endif
5227  } else {
5228  volatile uint8_t next, bit;
5229 
5230  hi = *port | pinMask;
5231  lo = *port & ~pinMask;
5232  next = lo;
5233  bit = 8;
5234 
5235  asm volatile(
5236  "head30:" "\n\t" // Clk Pseudocode (T = 0)
5237  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
5238  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
5239  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
5240  "rjmp .+0" "\n\t" // 2 nop nop (T = 6)
5241  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 8)
5242  "rjmp .+0" "\n\t" // 2 nop nop (T = 10)
5243  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
5244  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
5245  "nop" "\n\t" // 1 nop (T = 15)
5246  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 17)
5247  "rjmp .+0" "\n\t" // 2 nop nop (T = 19)
5248  "dec %[bit]" "\n\t" // 1 bit-- (T = 20)
5249  "breq nextbyte30" "\n\t" // 1-2 if(bit == 0)
5250  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 22)
5251  "rjmp .+0" "\n\t" // 2 nop nop (T = 24)
5252  "rjmp .+0" "\n\t" // 2 nop nop (T = 26)
5253  "rjmp .+0" "\n\t" // 2 nop nop (T = 28)
5254  "rjmp head30" "\n\t" // 2 -> head30 (next bit out)
5255  "nextbyte30:" "\n\t" // (T = 22)
5256  "nop" "\n\t" // 1 nop (T = 23)
5257  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 24)
5258  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 26)
5259  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 28)
5260  "brne head30" "\n" // 1-2 if(i != 0) -> (next byte)
5261  : [port] "+e" (port),
5262  [byte] "+r" (b),
5263  [bit] "+r" (bit),
5264  [next] "+r" (next),
5265  [count] "+w" (i)
5266  : [hi] "r" (hi),
5267  [lo] "r" (lo),
5268  [ptr] "e" (ptr));
5269  }
5270  #elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L)
5271  if(is800KHz) {
5272  volatile uint8_t next, bit;
5273 
5274  hi = *port | pinMask;
5275  lo = *port & ~pinMask;
5276  next = lo;
5277  bit = 8;
5278 
5279  asm volatile(
5280  "head20:" "\n\t" // Clk Pseudocode (T = 0)
5281  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
5282  "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 128)
5283  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
5284  "dec %[bit]" "\n\t" // 1 bit-- (T = 5)
5285  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 7)
5286  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 8)
5287  "breq nextbyte20" "\n\t" // 1-2 if(bit == 0) (from dec above)
5288  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
5289  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
5290  "nop" "\n\t" // 1 nop (T = 13)
5291  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15)
5292  "nop" "\n\t" // 1 nop (T = 16)
5293  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
5294  "rjmp head20" "\n\t" // 2 -> head20 (next bit out)
5295  "nextbyte20:" "\n\t" // (T = 10)
5296  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 11)
5297  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 13)
5298  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15)
5299  "nop" "\n\t" // 1 nop (T = 16)
5300  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
5301  "brne head20" "\n" // 2 if(i != 0) -> (next byte)
5302  : [port] "+e" (port),
5303  [byte] "+r" (b),
5304  [bit] "+r" (bit),
5305  [next] "+r" (next),
5306  [count] "+w" (i)
5307  : [ptr] "e" (ptr),
5308  [hi] "r" (hi),
5309  [lo] "r" (lo));
5310  } else {
5311 
5312  volatile uint8_t next, bit;
5313 
5314  hi = *port | pinMask;
5315  lo = *port & ~pinMask;
5316  next = lo;
5317  bit = 8;
5318 
5319  asm volatile(
5320  "head40:" "\n\t" // Clk Pseudocode (T = 0)
5321  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
5322  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
5323  "mov %[next] , %[hi]" "\n\t" // 0-1 next = hi (T = 4)
5324  "rjmp .+0" "\n\t" // 2 nop nop (T = 6)
5325  "rjmp .+0" "\n\t" // 2 nop nop (T = 8)
5326  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 10)
5327  "rjmp .+0" "\n\t" // 2 nop nop (T = 12)
5328  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
5329  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
5330  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
5331  "rjmp .+0" "\n\t" // 2 nop nop (T = 20)
5332  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 22)
5333  "nop" "\n\t" // 1 nop (T = 23)
5334  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 24)
5335  "dec %[bit]" "\n\t" // 1 bit-- (T = 25)
5336  "breq nextbyte40" "\n\t" // 1-2 if(bit == 0)
5337  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 27)
5338  "nop" "\n\t" // 1 nop (T = 28)
5339  "rjmp .+0" "\n\t" // 2 nop nop (T = 30)
5340  "rjmp .+0" "\n\t" // 2 nop nop (T = 32)
5341  "rjmp .+0" "\n\t" // 2 nop nop (T = 34)
5342  "rjmp .+0" "\n\t" // 2 nop nop (T = 36)
5343  "rjmp .+0" "\n\t" // 2 nop nop (T = 38)
5344  "rjmp head40" "\n\t" // 2 -> head40 (next bit out)
5345  "nextbyte40:" "\n\t" // (T = 27)
5346  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 28)
5347  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 30)
5348  "rjmp .+0" "\n\t" // 2 nop nop (T = 32)
5349  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 34)
5350  "rjmp .+0" "\n\t" // 2 nop nop (T = 36)
5351  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 38)
5352  "brne head40" "\n" // 1-2 if(i != 0) -> (next byte)
5353  : [port] "+e" (port),
5354  [byte] "+r" (b),
5355  [bit] "+r" (bit),
5356  [next] "+r" (next),
5357  [count] "+w" (i)
5358  : [ptr] "e" (ptr),
5359  [hi] "r" (hi),
5360  [lo] "r" (lo));
5361  }
5362  #else
5363  #error "CPU SPEED NOT SUPPORTED"
5364  #endif
5365  #elif defined(__arm__)
5366 
5367 
5368  #if defined(TEENSYDUINO) && defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6
5369  #define CYCLES_800_T0H (F_CPU / 4000000)
5370  #define CYCLES_800_T1H (F_CPU / 1250000)
5371  #define CYCLES_800 (F_CPU / 800000)
5372  #define CYCLES_400_T0H (F_CPU / 2000000)
5373  #define CYCLES_400_T1H (F_CPU / 833333)
5374  #define CYCLES_400 (F_CPU / 400000)
5375 
5376  uint8_t *p = pixels,
5377  *end = p + numBytes, pix, mask;
5378  volatile uint8_t *set = portSetRegister(pin),
5379  *clr = portClearRegister(pin);
5380  uint32_t cyc;
5381 
5382  ARM_DEMCR |= ARM_DEMCR_TRCENA;
5383  ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
5384 
5385  if(is800KHz) {
5386  cyc = ARM_DWT_CYCCNT + CYCLES_800;
5387  while(p < end) {
5388  pix = *p++;
5389  for(mask = 0x80; mask; mask >>= 1) {
5390  while(ARM_DWT_CYCCNT - cyc < CYCLES_800);
5391  cyc = ARM_DWT_CYCCNT;
5392  *set = 1;
5393  if(pix & mask) {
5394  while(ARM_DWT_CYCCNT - cyc < CYCLES_800_T1H);
5395  } else {
5396  while(ARM_DWT_CYCCNT - cyc < CYCLES_800_T0H);
5397  }
5398  *clr = 1;
5399  }
5400  }
5401  while(ARM_DWT_CYCCNT - cyc < CYCLES_800);
5402  } else {
5403  cyc = ARM_DWT_CYCCNT + CYCLES_400;
5404  while(p < end) {
5405  pix = *p++;
5406  for(mask = 0x80; mask; mask >>= 1) {
5407  while(ARM_DWT_CYCCNT - cyc < CYCLES_400);
5408  cyc = ARM_DWT_CYCCNT;
5409  *set = 1;
5410  if(pix & mask) {
5411  while(ARM_DWT_CYCCNT - cyc < CYCLES_400_T1H);
5412  } else {
5413  while(ARM_DWT_CYCCNT - cyc < CYCLES_400_T0H);
5414  }
5415  *clr = 1;
5416  }
5417  }
5418  while(ARM_DWT_CYCCNT - cyc < CYCLES_400);
5419  }
5420  #else
5421  #error "Sorry, only 48 MHz is supported, please set Tools > CPU Speed to 48 MHz"
5422  #endif
5423  #elif defined(ESP8266) || defined(ESP32)
5424 
5425  espShow(pin, pixels, numBytes, is800KHz);
5426 
5427  #elif defined(__ARDUINO_ARC__)
5428 
5429  // Arduino 101 -----------------------------------------------------------
5430 
5431  #define NOPx7 { __builtin_arc_nop(); \
5432  __builtin_arc_nop(); __builtin_arc_nop(); \
5433  __builtin_arc_nop(); __builtin_arc_nop(); \
5434  __builtin_arc_nop(); __builtin_arc_nop(); }
5435 
5436  PinDescription *pindesc = &g_APinDescription[pin];
5437  register uint32_t loop = 8 * numBytes; // one loop to handle all bytes and all bits
5438  register uint8_t *p = pixels;
5439  register uint32_t currByte = (uint32_t) (*p);
5440  register uint32_t currBit = 0x80 & currByte;
5441  register uint32_t bitCounter = 0;
5442  register uint32_t first = 1;
5443 
5444  if (pindesc->ulGPIOType == SS_GPIO) {
5445  register uint32_t reg = pindesc->ulGPIOBase + SS_GPIO_SWPORTA_DR;
5446  uint32_t reg_val = __builtin_arc_lr((volatile uint32_t)reg);
5447  register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
5448  register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
5449 
5450  loop += 1;
5451  while(loop--) {
5452  if(!first) {
5453  currByte <<= 1;
5454  bitCounter++;
5455  }
5456 
5457  // 1 is >550ns high and >450ns low; 0 is 200..500ns high and >450ns low
5458  __builtin_arc_sr(first ? reg_bit_low : reg_bit_high, (volatile uint32_t)reg);
5459  if(currBit) { // ~400ns HIGH (740ns overall)
5460  NOPx7
5461  NOPx7
5462  }
5463  // ~340ns HIGH
5464  NOPx7
5465  __builtin_arc_nop();
5466 
5467  // 820ns LOW; per spec, max allowed low here is 5000ns */
5468  __builtin_arc_sr(reg_bit_low, (volatile uint32_t)reg);
5469  NOPx7
5470  NOPx7
5471 
5472  if(bitCounter >= 8) {
5473  bitCounter = 0;
5474  currByte = (uint32_t) (*++p);
5475  }
5476 
5477  currBit = 0x80 & currByte;
5478  first = 0;
5479  }
5480  } else if(pindesc->ulGPIOType == SOC_GPIO) {
5481  register uint32_t reg = pindesc->ulGPIOBase + SOC_GPIO_SWPORTA_DR;
5482  uint32_t reg_val = MMIO_REG_VAL(reg);
5483  register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
5484  register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
5485 
5486  loop += 1; // include first, special iteration
5487  while(loop--) {
5488  if(!first) {
5489  currByte <<= 1;
5490  bitCounter++;
5491  }
5492  MMIO_REG_VAL(reg) = first ? reg_bit_low : reg_bit_high;
5493  if(currBit) { // ~430ns HIGH (740ns overall)
5494  NOPx7
5495  NOPx7
5496  __builtin_arc_nop();
5497  }
5498  // ~310ns HIGH
5499  NOPx7
5500 
5501  // 850ns LOW; per spec, max allowed low here is 5000ns */
5502  MMIO_REG_VAL(reg) = reg_bit_low;
5503  NOPx7
5504  NOPx7
5505 
5506  if(bitCounter >= 8) {
5507  bitCounter = 0;
5508  currByte = (uint32_t) (*++p);
5509  }
5510 
5511  currBit = 0x80 & currByte;
5512  first = 0;
5513  }
5514  }
5515 
5516  #else
5517  #error Architecture not supported
5518  #endif
5519 
5520  #ifndef NRF52
5521  interrupts();
5522  #endif
5523 
5524  endTime = micros();
5525  }
5526 
5527  void NeoPixel::setPin(uint8_t p) {
5528  if(begun && (pin >= 0)) pinMode(pin, INPUT);
5529  pin = p;
5530  if(begun) {
5531  pinMode(p, OUTPUT);
5532  digitalWrite(p, LOW);
5533  }
5534  #ifdef __AVR__
5535  port = portOutputRegister(digitalPinToPort(p));
5536  pinMask = digitalPinToBitMask(p);
5537  #endif
5538  }
5539 
5541  uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
5542 
5543  if(n < numLEDs) {
5544  if(brightness) { // See notes in setBrightness()
5545  r = (r * brightness) >> 8;
5546  g = (g * brightness) >> 8;
5547  b = (b * brightness) >> 8;
5548  }
5549  uint8_t *p;
5550  if(wOffset == rOffset) {
5551  p = &pixels[n * 3];
5552  } else {
5553  p = &pixels[n * 4];
5554  p[wOffset] = 0;
5555  }
5556  p[rOffset] = r;
5557  p[gOffset] = g;
5558  p[bOffset] = b;
5559  }
5560  }
5561 
5563  uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
5564 
5565  if(n < numLEDs) {
5566  if(brightness) {
5567  r = (r * brightness) >> 8;
5568  g = (g * brightness) >> 8;
5569  b = (b * brightness) >> 8;
5570  w = (w * brightness) >> 8;
5571  }
5572  uint8_t *p;
5573  if(wOffset == rOffset) {
5574  p = &pixels[n * 3];
5575  } else {
5576  p = &pixels[n * 4];
5577  p[wOffset] = w;
5578  }
5579  p[rOffset] = r;
5580  p[gOffset] = g;
5581  p[bOffset] = b;
5582  }
5583  }
5584 
5585  void NeoPixel::setPixelColor(uint16_t n, uint32_t c) {
5586  if(n < numLEDs) {
5587  uint8_t *p,
5588  r = (uint8_t)(c >> 16),
5589  g = (uint8_t)(c >> 8),
5590  b = (uint8_t)c;
5591  if(brightness) {
5592  r = (r * brightness) >> 8;
5593  g = (g * brightness) >> 8;
5594  b = (b * brightness) >> 8;
5595  }
5596  if(wOffset == rOffset) {
5597  p = &pixels[n * 3];
5598  } else {
5599  p = &pixels[n * 4];
5600  uint8_t w = (uint8_t)(c >> 24);
5601  p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
5602  }
5603  p[rOffset] = r;
5604  p[gOffset] = g;
5605  p[bOffset] = b;
5606  }
5607  }
5608 
5609  uint32_t NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b) {
5610  return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
5611  }
5612 
5613  uint32_t NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
5614  return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
5615  }
5616 
5617  uint32_t NeoPixel::getPixelColor(uint16_t n) const {
5618  if(n >= numLEDs) return 0;
5619 
5620  uint8_t *p;
5621 
5622  if(wOffset == rOffset) {
5623  p = &pixels[n * 3];
5624  if(brightness) {
5625 
5626  return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
5627  (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
5628  ( (uint32_t)(p[bOffset] << 8) / brightness );
5629  } else {
5630  return ((uint32_t)p[rOffset] << 16) |
5631  ((uint32_t)p[gOffset] << 8) |
5632  (uint32_t)p[bOffset];
5633  }
5634  } else {
5635  p = &pixels[n * 4];
5636  if(brightness) {
5637  return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) |
5638  (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
5639  (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
5640  ( (uint32_t)(p[bOffset] << 8) / brightness );
5641  } else {
5642  return ((uint32_t)p[wOffset] << 24) |
5643  ((uint32_t)p[rOffset] << 16) |
5644  ((uint32_t)p[gOffset] << 8) |
5645  (uint32_t)p[bOffset];
5646  }
5647  }
5648  }
5649 
5650 
5651  uint8_t *NeoPixel::getPixels(void) const {
5652  return pixels;
5653  }
5654 
5655  uint16_t NeoPixel::numPixels(void) const {
5656  return numLEDs;
5657  }
5658 
5659  void NeoPixel::setBrightness(uint8_t b) {
5660 
5661  uint8_t newBrightness = b + 1;
5662  if(newBrightness != brightness) {
5663  uint8_t c,
5664  *ptr = pixels,
5665  oldBrightness = brightness - 1;
5666  uint16_t scale;
5667  if(oldBrightness == 0) scale = 0; // Avoid /0
5668  else if(b == 255) scale = 65535 / oldBrightness;
5669  else scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
5670  for(uint16_t i=0; i<numBytes; i++) {
5671  c = *ptr;
5672  *ptr++ = (c * scale) >> 8;
5673  }
5674  brightness = newBrightness;
5675  }
5676  }
5677 
5678  uint8_t NeoPixel::getBrightness(void) const {
5679  return brightness - 1;
5680  }
5681 
5682  void NeoPixel::clear() {
5683  memset(pixels, 0, numBytes);
5684  }
5685 
5686  static const uint8_t PROGMEM _sineTable[256] = {
5687  128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,
5688  176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,
5689  218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,
5690  245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,
5691  255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,
5692  245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,
5693  218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,
5694  176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,
5695  128,124,121,118,115,112,109,106,103,100, 97, 93, 90, 88, 85, 82,
5696  79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
5697  37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
5698  10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0,
5699  0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
5700  10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
5701  37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
5702  79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124};
5703 
5704  static const uint8_t PROGMEM _gammaTable[256] = {
5705  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5706  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
5707  1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
5708  3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
5709  7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12,
5710  13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
5711  20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
5712  30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
5713  42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
5714  58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
5715  76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
5716  97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
5717  122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
5718  150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
5719  182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
5720  218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255};
5721 
5722  uint8_t NeoPixel::sine8(uint8_t x) const {
5723  return pgm_read_byte(&_sineTable[x]); // 0-255 in, 0-255 out
5724  }
5725 
5726  uint8_t NeoPixel::gamma8(uint8_t x) const {
5727  return pgm_read_byte(&_gammaTable[x]); // 0-255 in, 0-255 out
5728  }
5729 
5731  #endif
5732  #endif
5733 
5950 #if EBOARD_COPY_AND_PASTE > 0x0
5951 
5953  extern int eVirtual_main();
5955 
5957  void setup(void);
5958 
5960  void setup(void) {
5961  //setup of RX and TX should be handled manually - in everyCase ^^
5964  #if EBOARD_DEBUG_MODE > 0x0
5965  Serial.begin(EBOARD_DEBUG_SPEED);
5966  #endif
5967  //this will initialize the interrupt handling!
5968  cli();
5969  TCCR1A = 0; TCCR1B = 0; //clear registers;
5970  OCR1A = EBOARD_PWM_SPE * 15624;
5971  TCCR1B |= (1 << WGM12); TCCR1B |= (1 << CS10); TCCR1B |= (1 << CS12);
5972  TIMSK1 |= (1 << OCIE1A);
5973  sei();
5974  #if EBOARD_BLUETOOTH > 0x0
5975  #if (EBOARD_BLUETOOTH > 0x0) && (((PIN_BLUETOOTH_RX==0x13) && (PIN_BLUETOOTH_TX==0x12)) && defined(__AVR_ATmega2560__))
5978  Serial1.begin(38400);
5979  #else
5980  _serial.begin(38400);
5981  #endif
5983  #endif
5984  #if EBOARD_I2C > 0x0
5985  Wire.begin();
5986  #endif
5987  #if EBOARD_SHIFT_REGISTER > 0x0
5988  pinMode(PIN_SHIFT_CLK,OUTPUT);
5989  pinMode(PIN_SHIFT_DAT,OUTPUT);
5990  pinMode(PIN_SHIFT_LAT,OUTPUT);
5991  shiftAll(); //set all to 0
5992  #endif
5993  #if EBOARD_USE_SPI > 0x0 && (EBOARD_NANO == 0)
5994  _servoHandler.begin(); //Setup SPI
5995  #endif
5996 
5997  #if EBOARD_DEBUG_MODE > 0x0
5998  Serial.print(eVirtual_main());
5999  Serial.println(" -- Exit Code. \n Program has finished. Reset to start again");
6000  #else
6001  eVirtual_main();
6002  #endif
6003  if (STOP) {} //prevent unused error
6004  delay(200);
6005  cli(); //disable timers after running the program :D
6006  writePWM(0);analogWrite(PIN_MOTOR_SPE,0);
6007  }
6010  void loop(void);
6012  void loop(void){
6013  //shall be empty
6014  }
6016 
6017 #endif
6018 
6019 #else
6020  #error This library is build for arduino-devices and should be used only in the Arduino IDE or with a similar linking process
6021 #endif
6022 #pragma GCC diagnostic pop
6023 #pragma pack(pop)
6024 
6025 #endif
uint16_t _rx_delay_intrabit
the rx startbit delay
Definition: eBoard.h:1608
uint8_t * pixels
stores the pixels
Definition: eBoard.h:4482
void onRequest(void(*function)(void))
this will set the user_onRequest method
optVAL_t _pwmValue
Definition: eBoard.h:2410
volatile uint8_t * port
the used port register
Definition: eBoard.h:4495
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:4478
uint8_t gOffset
stores the green color offset
Definition: eBoard.h:4486
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:3263
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:1601
[COPY&PASTE] This is the SoccerBoard ghost struct :D
Definition: eBoard.h:2742
static void(* user_onReceive)(int numBytes)
twi slave [Rx]receive-event user def handler
Definition: eBoard.h:885
void writeVal(const T &val)
[BLUETOOTH] writes Data to bluetooth
byte sendWait(const byte what)
sends data.
#define PIN_SHIFT_LAT
Definition: eBoard.h:1542
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:1623
[COPY&PASTE] This is the AX12Servo ghost struct :D
Definition: eBoard.h:3064
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:864
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:3175
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:479
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:1278
uint16_t numLEDs
stores the amount of LEDs
Definition: eBoard.h:4471
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:1414
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:4064
#define LCD_COMMAND_DISPLAY_OFF
Definition: eBoard.h:3816
TwoWire Wire
this is the well-known Arduino Wire Interface, just a little bit &#39;modified&#39; ;P
Definition: eBoard.h:1220
#define PIN_BLUETOOTH_RX
Definition: eBoard.h:1495
[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:2536
static uint8_t txBufferIndex
this defines the txBuffer Index - current position in txBuffer array
Definition: eBoard.h:873
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:4467
uint16_t _rx_delay_stopbit
the rx stopbit dely
Definition: eBoard.h:1610
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:4488
This is used to avoid path resolving issues and defines the common known Arduino Wire-Interface &#160;&#160;&#160;...
Definition: eBoard.h:859
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:2410
bool begun
true if NeoPixel::begin has been called
Definition: eBoard.h:4469
static uint8_t transmitting
&#39;boolean&#39; value. Set to 1 if transmitting => in master write mode
Definition: eBoard.h:878
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:1436
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:3812
long store_bits
[SHIFT] Manipulate me to set Pins via bitSet operations
Definition: eBoard.h:2378
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:4066
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:1536
void Reset(optVAL_t ID)
resets a servo
#define LCD_DATA_MODE
Definition: eBoard.h:3814
void sleep(uint16_t t)
Say goodnight!
#define _SS_MAX_RX_BUFF
Definition: eBoard.h:1566
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:1516
static uint8_t rxBufferLength
this defines the length of rxBuffer
Definition: eBoard.h:866
#define LCD_COMMAND_DISPLAY_ON
Definition: eBoard.h:3818
static uint8_t txAddress
this defines the txAddress the transmitting Dta
Definition: eBoard.h:869
int storedPos
stores the position the Servo should go to DynamixelBoard::action()
Definition: eBoard.h:3159
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:871
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:2629
#define LCD_PAGE_ADDRESSING
Definition: eBoard.h:3826
int optVAL_t
Definition: eBoard.h:1373
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:1259
static char _receive_buffer[64]
the buffer for rxBuffer
Definition: eBoard.h:1619
#define LCD_COMMAND_CHARGE_PUMP_SETTING
Definition: eBoard.h:3831
uint64_t pin_out
Definition: eBoard.h:2251
#define PIN_BLUETOOTH_TX
Definition: eBoard.h:1506
static void begin(void)
this will setup everything for SPI connection
optVAL_t id
stores the id of the AX12Servo obejct
Definition: eBoard.h:3170
void msleep(uint16_t t)
Say goodnight!
static bool STOP
Definition: eBoard.h:1365
void shiftAll(void)
[SHIFT] Changes bits according to store_bits
byte pX
the addressing mode (page/horizontal)
Definition: eBoard.h:4062
DynamixelBoard(SoccerBoard &)
The constructor.
ServoCds55 _servoHandler
this is the "to_use" instance of ServoCds55
Definition: eBoard.h:2713
void updateLength(uint16_t n)
this changes the length of the connected LED stripe
#define PIN_BLUETOOTH_STATE
Definition: eBoard.h:1484
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:1530
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:4473
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:1420
#define SPI_CLOCK_MASK
Definition: eBoard.h:1261
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:3822
void waitForButton(int)
šŸ”§ I prevent errors!
uint64_t pin_in
Definition: eBoard.h:2259
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:3841
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:3327
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:4054
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:3165
[COPY&PASTE] This is the DynamixelBoard ghost struct :D
Definition: eBoard.h:3236
char readVal(char oF='.')
[BLUETOOTH] reads a single value from bluetooth if available!
#define SPI_CLOCK_DIV8
Definition: eBoard.h:1245
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:1603
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:1523
uint32_t endTime
stores the last call time of show for NeoPixel::canShow()
Definition: eBoard.h:4492
void changeId(optVAL_t)
šŸ”§ I prevent errors!
uint8_t wOffset
stores the white color offset
Definition: eBoard.h:4490
uint16_t _tx_delay
the (generic) tx delay
Definition: eBoard.h:1612
DynamixelBoard * _conBoard
Definition: eBoard.h:3078
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:2993
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:2633
bool clear(void)
clears the LCD
#define BUFFER_LENGTH
Definition: eBoard.h:841
SPIClass SPI
Definition: eBoard.h:1353
void onReceive(void(*function)(int))
this will set the user_onReceive method
uint8_t brightness
stores the brightness
Definition: eBoard.h:4480
uint8_t pinMask
the used pinMask
Definition: eBoard.h:4497
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:1263
static uint8_t txBufferLength
this defines the length of txBuffer
Definition: eBoard.h:875
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:1625
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:1617
DynamixelBoard dBoard(board)
the dBoard object
uint16_t _rx_delay_centering
the rx center delay
Definition: eBoard.h:1606
static volatile uint8_t _receive_buffer_tail
size of rxBuffer
Definition: eBoard.h:1621
uint8_t rOffset
stores the red color offset
Definition: eBoard.h:4484
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:1595
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:3833
#define LCD_WIDTH
Definition: eBoard.h:3837
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:1615
static void(* user_onRequest)(void)
twi slave [Tx]transmitting-event user def handler
Definition: eBoard.h:880
uint8_t _receiveBitMask
the pin mask to directly read from register (Rx)
Definition: eBoard.h:1597
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:3451
optVAL_t cs
stores the ControlPin id
Definition: eBoard.h:2635
static uint8_t rxBuffer[]
this defines the rxBuffer used to enable delayed read
Definition: eBoard.h:862
volatile uint8_t * _receivePortRegister
the register the reveice pin is located on
Definition: eBoard.h:1599
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:4334
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:4302
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:3886
#define LCD_COMMAND_BLACK_BACKGROUND
Definition: eBoard.h:3820
void changeMotorID(optVAL_t newID)
change the AX-12 Servo this object should speak to
#define EBOARD_NEO_RGB
Definition: eBoard.h:4237
This is used to avoid path resolving issues and defines the common known Arduino SoftwareSerial inter...
Definition: eBoard.h:1592